1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
3*5113495bSYour Name * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name *
5*5113495bSYour Name * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name * above copyright notice and this permission notice appear in all
8*5113495bSYour Name * copies.
9*5113495bSYour Name *
10*5113495bSYour Name * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name */
19*5113495bSYour Name
20*5113495bSYour Name /*========================================================================
21*5113495bSYour Name
22*5113495bSYour Name \file epping_tx.c
23*5113495bSYour Name
24*5113495bSYour Name \brief WLAN End Point Ping test tool implementation
25*5113495bSYour Name
26*5113495bSYour Name ========================================================================*/
27*5113495bSYour Name
28*5113495bSYour Name /*--------------------------------------------------------------------------
29*5113495bSYour Name Include Files
30*5113495bSYour Name ------------------------------------------------------------------------*/
31*5113495bSYour Name #include <cds_api.h>
32*5113495bSYour Name #include <cds_sched.h>
33*5113495bSYour Name #include <linux/etherdevice.h>
34*5113495bSYour Name #include <linux/firmware.h>
35*5113495bSYour Name #include <wni_api.h>
36*5113495bSYour Name #include <wlan_ptt_sock_svc.h>
37*5113495bSYour Name #include <linux/wireless.h>
38*5113495bSYour Name #include <net/cfg80211.h>
39*5113495bSYour Name #include <linux/rtnetlink.h>
40*5113495bSYour Name #include <linux/semaphore.h>
41*5113495bSYour Name #include <linux/ctype.h>
42*5113495bSYour Name #include "epping_main.h"
43*5113495bSYour Name #include "epping_internal.h"
44*5113495bSYour Name #include "epping_test.h"
45*5113495bSYour Name
46*5113495bSYour Name #define TX_RETRY_TIMEOUT_IN_MS 1
47*5113495bSYour Name
48*5113495bSYour Name static bool enb_tx_dump;
49*5113495bSYour Name
epping_tx_dup_pkt(epping_adapter_t * adapter,HTC_ENDPOINT_ID eid,qdf_nbuf_t skb)50*5113495bSYour Name void epping_tx_dup_pkt(epping_adapter_t *adapter,
51*5113495bSYour Name HTC_ENDPOINT_ID eid, qdf_nbuf_t skb)
52*5113495bSYour Name {
53*5113495bSYour Name struct epping_cookie *cookie = NULL;
54*5113495bSYour Name int skb_len, ret;
55*5113495bSYour Name qdf_nbuf_t new_skb;
56*5113495bSYour Name
57*5113495bSYour Name cookie = epping_alloc_cookie(adapter->pEpping_ctx);
58*5113495bSYour Name if (!cookie) {
59*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
60*5113495bSYour Name "%s: epping_alloc_cookie returns no resource\n",
61*5113495bSYour Name __func__);
62*5113495bSYour Name return;
63*5113495bSYour Name }
64*5113495bSYour Name new_skb = qdf_nbuf_copy(skb);
65*5113495bSYour Name if (!new_skb) {
66*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
67*5113495bSYour Name "%s: qdf_nbuf_copy returns no resource\n", __func__);
68*5113495bSYour Name epping_free_cookie(adapter->pEpping_ctx, cookie);
69*5113495bSYour Name return;
70*5113495bSYour Name }
71*5113495bSYour Name SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
72*5113495bSYour Name cookie, qdf_nbuf_data(skb),
73*5113495bSYour Name qdf_nbuf_len(new_skb), eid, 0);
74*5113495bSYour Name SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, new_skb);
75*5113495bSYour Name skb_len = (int)qdf_nbuf_len(new_skb);
76*5113495bSYour Name /* send the packet */
77*5113495bSYour Name ret = htc_send_pkt(adapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt);
78*5113495bSYour Name if (ret != QDF_STATUS_SUCCESS) {
79*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
80*5113495bSYour Name "%s: htc_send_pkt failed, ret = %d\n", __func__, ret);
81*5113495bSYour Name epping_free_cookie(adapter->pEpping_ctx, cookie);
82*5113495bSYour Name qdf_nbuf_free(new_skb);
83*5113495bSYour Name return;
84*5113495bSYour Name }
85*5113495bSYour Name adapter->stats.tx_bytes += skb_len;
86*5113495bSYour Name ++adapter->stats.tx_packets;
87*5113495bSYour Name if (((adapter->stats.tx_packets +
88*5113495bSYour Name adapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 &&
89*5113495bSYour Name (adapter->stats.tx_packets || adapter->stats.tx_dropped)) {
90*5113495bSYour Name epping_log_stats(adapter, __func__);
91*5113495bSYour Name }
92*5113495bSYour Name }
93*5113495bSYour Name
epping_tx_send_int(qdf_nbuf_t skb,epping_adapter_t * adapter)94*5113495bSYour Name static int epping_tx_send_int(qdf_nbuf_t skb, epping_adapter_t *adapter)
95*5113495bSYour Name {
96*5113495bSYour Name EPPING_HEADER *eppingHdr = (EPPING_HEADER *) qdf_nbuf_data(skb);
97*5113495bSYour Name HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
98*5113495bSYour Name struct epping_cookie *cookie = NULL;
99*5113495bSYour Name uint8_t ac = 0;
100*5113495bSYour Name QDF_STATUS ret = QDF_STATUS_SUCCESS;
101*5113495bSYour Name int skb_len;
102*5113495bSYour Name EPPING_HEADER tmpHdr = *eppingHdr;
103*5113495bSYour Name
104*5113495bSYour Name /* allocate resource for this packet */
105*5113495bSYour Name cookie = epping_alloc_cookie(adapter->pEpping_ctx);
106*5113495bSYour Name /* no resource */
107*5113495bSYour Name if (!cookie) {
108*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
109*5113495bSYour Name "%s: epping_alloc_cookie returns no resource\n",
110*5113495bSYour Name __func__);
111*5113495bSYour Name return A_ERROR;
112*5113495bSYour Name }
113*5113495bSYour Name
114*5113495bSYour Name if (enb_tx_dump)
115*5113495bSYour Name epping_hex_dump((void *)eppingHdr, skb->len, __func__);
116*5113495bSYour Name /*
117*5113495bSYour Name * a quirk of linux, the payload of the frame is 32-bit aligned and thus
118*5113495bSYour Name * the addition of the HTC header will mis-align the start of the HTC
119*5113495bSYour Name * frame, so we add some padding which will be stripped off in the target
120*5113495bSYour Name */
121*5113495bSYour Name if (EPPING_ALIGNMENT_PAD > 0) {
122*5113495bSYour Name A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD);
123*5113495bSYour Name }
124*5113495bSYour Name /* prepare ep/HTC information */
125*5113495bSYour Name ac = eppingHdr->StreamNo_h;
126*5113495bSYour Name eid = adapter->pEpping_ctx->EppingEndpoint[ac];
127*5113495bSYour Name if (eid < 0 || eid >= EPPING_MAX_NUM_EPIDS) {
128*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
129*5113495bSYour Name "%s: invalid eid = %d, ac = %d\n", __func__, eid,
130*5113495bSYour Name ac);
131*5113495bSYour Name return A_ERROR;
132*5113495bSYour Name }
133*5113495bSYour Name if (tmpHdr.Cmd_h == EPPING_CMD_RESET_RECV_CNT ||
134*5113495bSYour Name tmpHdr.Cmd_h == EPPING_CMD_CONT_RX_START) {
135*5113495bSYour Name epping_set_kperf_flag(adapter, eid, tmpHdr.CmdBuffer_t[0]);
136*5113495bSYour Name }
137*5113495bSYour Name SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
138*5113495bSYour Name cookie, qdf_nbuf_data(skb), qdf_nbuf_len(skb),
139*5113495bSYour Name eid, 0);
140*5113495bSYour Name SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, skb);
141*5113495bSYour Name skb_len = skb->len;
142*5113495bSYour Name /* send the packet */
143*5113495bSYour Name ret = htc_send_pkt(adapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt);
144*5113495bSYour Name epping_log_packet(adapter, &tmpHdr, ret, __func__);
145*5113495bSYour Name if (ret != QDF_STATUS_SUCCESS) {
146*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
147*5113495bSYour Name "%s: htc_send_pkt failed, status = %d\n", __func__,
148*5113495bSYour Name ret);
149*5113495bSYour Name epping_free_cookie(adapter->pEpping_ctx, cookie);
150*5113495bSYour Name return A_ERROR;
151*5113495bSYour Name }
152*5113495bSYour Name adapter->stats.tx_bytes += skb_len;
153*5113495bSYour Name ++adapter->stats.tx_packets;
154*5113495bSYour Name if (((adapter->stats.tx_packets +
155*5113495bSYour Name adapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 &&
156*5113495bSYour Name (adapter->stats.tx_packets || adapter->stats.tx_dropped)) {
157*5113495bSYour Name epping_log_stats(adapter, __func__);
158*5113495bSYour Name }
159*5113495bSYour Name
160*5113495bSYour Name return 0;
161*5113495bSYour Name }
162*5113495bSYour Name
epping_tx_timer_expire(epping_adapter_t * adapter)163*5113495bSYour Name void epping_tx_timer_expire(epping_adapter_t *adapter)
164*5113495bSYour Name {
165*5113495bSYour Name qdf_nbuf_t nodrop_skb;
166*5113495bSYour Name
167*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_INFO, "%s: queue len: %d\n", __func__,
168*5113495bSYour Name qdf_nbuf_queue_len(&adapter->nodrop_queue));
169*5113495bSYour Name
170*5113495bSYour Name if (!qdf_nbuf_queue_len(&adapter->nodrop_queue)) {
171*5113495bSYour Name /* nodrop queue is empty so no need to arm timer */
172*5113495bSYour Name adapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
173*5113495bSYour Name return;
174*5113495bSYour Name }
175*5113495bSYour Name
176*5113495bSYour Name /* try to flush nodrop queue */
177*5113495bSYour Name while ((nodrop_skb = qdf_nbuf_queue_remove(&adapter->nodrop_queue))) {
178*5113495bSYour Name htc_set_nodrop_pkt(adapter->pEpping_ctx->HTCHandle, true);
179*5113495bSYour Name if (epping_tx_send_int(nodrop_skb, adapter)) {
180*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
181*5113495bSYour Name "%s: nodrop: %pK xmit fail in timer\n",
182*5113495bSYour Name __func__, nodrop_skb);
183*5113495bSYour Name /* fail to xmit so put the nodrop packet to the nodrop queue */
184*5113495bSYour Name qdf_nbuf_queue_insert_head(&adapter->nodrop_queue,
185*5113495bSYour Name nodrop_skb);
186*5113495bSYour Name break;
187*5113495bSYour Name } else {
188*5113495bSYour Name htc_set_nodrop_pkt(adapter->pEpping_ctx->HTCHandle, false);
189*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_INFO,
190*5113495bSYour Name "%s: nodrop: %pK xmit ok in timer\n",
191*5113495bSYour Name __func__, nodrop_skb);
192*5113495bSYour Name }
193*5113495bSYour Name }
194*5113495bSYour Name
195*5113495bSYour Name /* if nodrop queue is not empty, continue to arm timer */
196*5113495bSYour Name if (nodrop_skb) {
197*5113495bSYour Name qdf_spin_lock_bh(&adapter->data_lock);
198*5113495bSYour Name /* if nodrop queue is not empty, continue to arm timer */
199*5113495bSYour Name if (adapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) {
200*5113495bSYour Name adapter->epping_timer_state = EPPING_TX_TIMER_RUNNING;
201*5113495bSYour Name qdf_timer_mod(&adapter->epping_timer,
202*5113495bSYour Name TX_RETRY_TIMEOUT_IN_MS);
203*5113495bSYour Name }
204*5113495bSYour Name qdf_spin_unlock_bh(&adapter->data_lock);
205*5113495bSYour Name } else {
206*5113495bSYour Name adapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
207*5113495bSYour Name }
208*5113495bSYour Name }
209*5113495bSYour Name
epping_tx_send(qdf_nbuf_t skb,epping_adapter_t * adapter)210*5113495bSYour Name int epping_tx_send(qdf_nbuf_t skb, epping_adapter_t *adapter)
211*5113495bSYour Name {
212*5113495bSYour Name qdf_nbuf_t nodrop_skb;
213*5113495bSYour Name EPPING_HEADER *eppingHdr;
214*5113495bSYour Name uint8_t ac = 0;
215*5113495bSYour Name
216*5113495bSYour Name eppingHdr = (EPPING_HEADER *) qdf_nbuf_data(skb);
217*5113495bSYour Name
218*5113495bSYour Name if (!IS_EPPING_PACKET(eppingHdr)) {
219*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
220*5113495bSYour Name "%s: Received non endpoint ping packets\n", __func__);
221*5113495bSYour Name /* no packet to send, cleanup */
222*5113495bSYour Name qdf_nbuf_free(skb);
223*5113495bSYour Name return -ENOMEM;
224*5113495bSYour Name }
225*5113495bSYour Name
226*5113495bSYour Name /* the stream ID is mapped to an access class */
227*5113495bSYour Name ac = eppingHdr->StreamNo_h;
228*5113495bSYour Name /* hard coded two ep ids */
229*5113495bSYour Name if (ac != 0 && ac != 1) {
230*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
231*5113495bSYour Name "%s: ac %d is not mapped to mboxping service\n",
232*5113495bSYour Name __func__, ac);
233*5113495bSYour Name qdf_nbuf_free(skb);
234*5113495bSYour Name return -ENOMEM;
235*5113495bSYour Name }
236*5113495bSYour Name
237*5113495bSYour Name /*
238*5113495bSYour Name * some EPPING packets cannot be dropped no matter what access class
239*5113495bSYour Name * it was sent on. A special care has been taken:
240*5113495bSYour Name * 1. when there is no TX resource, queue the control packets to
241*5113495bSYour Name * a special queue
242*5113495bSYour Name * 2. when there is TX resource, send the queued control packets first
243*5113495bSYour Name * and then other packets
244*5113495bSYour Name * 3. a timer launches to check if there is queued control packets and
245*5113495bSYour Name * flush them
246*5113495bSYour Name */
247*5113495bSYour Name
248*5113495bSYour Name /* check the nodrop queue first */
249*5113495bSYour Name while ((nodrop_skb = qdf_nbuf_queue_remove(&adapter->nodrop_queue))) {
250*5113495bSYour Name htc_set_nodrop_pkt(adapter->pEpping_ctx->HTCHandle, true);
251*5113495bSYour Name if (epping_tx_send_int(nodrop_skb, adapter)) {
252*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
253*5113495bSYour Name "%s: nodrop: %pK xmit fail\n", __func__,
254*5113495bSYour Name nodrop_skb);
255*5113495bSYour Name /* fail to xmit so put the nodrop packet to the nodrop queue */
256*5113495bSYour Name qdf_nbuf_queue_insert_head(&adapter->nodrop_queue,
257*5113495bSYour Name nodrop_skb);
258*5113495bSYour Name /* no cookie so free the current skb */
259*5113495bSYour Name goto tx_fail;
260*5113495bSYour Name } else {
261*5113495bSYour Name htc_set_nodrop_pkt(adapter->pEpping_ctx->HTCHandle, false);
262*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_INFO,
263*5113495bSYour Name "%s: nodrop: %pK xmit ok\n", __func__,
264*5113495bSYour Name nodrop_skb);
265*5113495bSYour Name }
266*5113495bSYour Name }
267*5113495bSYour Name
268*5113495bSYour Name /* send the original packet */
269*5113495bSYour Name if (epping_tx_send_int(skb, adapter))
270*5113495bSYour Name goto tx_fail;
271*5113495bSYour Name
272*5113495bSYour Name return 0;
273*5113495bSYour Name
274*5113495bSYour Name tx_fail:
275*5113495bSYour Name if (!IS_EPING_PACKET_NO_DROP(eppingHdr)) {
276*5113495bSYour Name /* allow to drop the skb so drop it */
277*5113495bSYour Name qdf_nbuf_free(skb);
278*5113495bSYour Name ++adapter->stats.tx_dropped;
279*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
280*5113495bSYour Name "%s: Tx skb %pK dropped, stats.tx_dropped = %ld\n",
281*5113495bSYour Name __func__, skb, adapter->stats.tx_dropped);
282*5113495bSYour Name return -ENOMEM;
283*5113495bSYour Name } else {
284*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
285*5113495bSYour Name "%s: nodrop: %pK queued\n", __func__, skb);
286*5113495bSYour Name qdf_nbuf_queue_add(&adapter->nodrop_queue, skb);
287*5113495bSYour Name qdf_spin_lock_bh(&adapter->data_lock);
288*5113495bSYour Name if (adapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) {
289*5113495bSYour Name adapter->epping_timer_state = EPPING_TX_TIMER_RUNNING;
290*5113495bSYour Name qdf_timer_mod(&adapter->epping_timer,
291*5113495bSYour Name TX_RETRY_TIMEOUT_IN_MS);
292*5113495bSYour Name }
293*5113495bSYour Name qdf_spin_unlock_bh(&adapter->data_lock);
294*5113495bSYour Name }
295*5113495bSYour Name
296*5113495bSYour Name return 0;
297*5113495bSYour Name }
298*5113495bSYour Name
299*5113495bSYour Name #ifdef HIF_SDIO
epping_tx_queue_full(void * Context,HTC_PACKET * pPacket)300*5113495bSYour Name enum htc_send_full_action epping_tx_queue_full(void *Context,
301*5113495bSYour Name HTC_PACKET *pPacket)
302*5113495bSYour Name {
303*5113495bSYour Name /*
304*5113495bSYour Name * Call netif_stop_queue frequently will impact the mboxping tx t-put.
305*5113495bSYour Name * Return HTC_SEND_FULL_KEEP directly in epping_tx_queue_full to avoid.
306*5113495bSYour Name */
307*5113495bSYour Name return HTC_SEND_FULL_KEEP;
308*5113495bSYour Name }
309*5113495bSYour Name #endif /* HIF_SDIO */
epping_tx_complete(void * ctx,HTC_PACKET * htc_pkt)310*5113495bSYour Name void epping_tx_complete(void *ctx, HTC_PACKET *htc_pkt)
311*5113495bSYour Name {
312*5113495bSYour Name epping_context_t *pEpping_ctx = (epping_context_t *) ctx;
313*5113495bSYour Name epping_adapter_t *adapter = pEpping_ctx->epping_adapter;
314*5113495bSYour Name struct net_device *dev = adapter->dev;
315*5113495bSYour Name QDF_STATUS status;
316*5113495bSYour Name HTC_ENDPOINT_ID eid;
317*5113495bSYour Name qdf_nbuf_t pktSkb;
318*5113495bSYour Name struct epping_cookie *cookie;
319*5113495bSYour Name A_BOOL flushing = false;
320*5113495bSYour Name qdf_nbuf_queue_t skb_queue;
321*5113495bSYour Name
322*5113495bSYour Name if (!htc_pkt)
323*5113495bSYour Name return;
324*5113495bSYour Name
325*5113495bSYour Name qdf_nbuf_queue_init(&skb_queue);
326*5113495bSYour Name
327*5113495bSYour Name qdf_spin_lock_bh(&adapter->data_lock);
328*5113495bSYour Name
329*5113495bSYour Name status = htc_pkt->Status;
330*5113495bSYour Name eid = htc_pkt->Endpoint;
331*5113495bSYour Name pktSkb = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt);
332*5113495bSYour Name cookie = htc_pkt->pPktContext;
333*5113495bSYour Name
334*5113495bSYour Name if (!pktSkb) {
335*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
336*5113495bSYour Name "%s: NULL skb from hc packet", __func__);
337*5113495bSYour Name QDF_BUG(0);
338*5113495bSYour Name } else {
339*5113495bSYour Name if (htc_pkt->pBuffer != qdf_nbuf_data(pktSkb)) {
340*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
341*5113495bSYour Name "%s: htc_pkt buffer not equal to skb->data",
342*5113495bSYour Name __func__);
343*5113495bSYour Name QDF_BUG(0);
344*5113495bSYour Name }
345*5113495bSYour Name /* add this to the list, use faster non-lock API */
346*5113495bSYour Name qdf_nbuf_queue_add(&skb_queue, pktSkb);
347*5113495bSYour Name
348*5113495bSYour Name if (QDF_IS_STATUS_SUCCESS(status)) {
349*5113495bSYour Name if (htc_pkt->ActualLength !=
350*5113495bSYour Name qdf_nbuf_len(pktSkb)) {
351*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
352*5113495bSYour Name "%s: htc_pkt length not equal to skb->len",
353*5113495bSYour Name __func__);
354*5113495bSYour Name QDF_BUG(0);
355*5113495bSYour Name }
356*5113495bSYour Name }
357*5113495bSYour Name }
358*5113495bSYour Name
359*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_INFO,
360*5113495bSYour Name "%s skb=%pK data=%pK len=0x%x eid=%d ",
361*5113495bSYour Name __func__, pktSkb, htc_pkt->pBuffer,
362*5113495bSYour Name htc_pkt->ActualLength, eid);
363*5113495bSYour Name
364*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
365*5113495bSYour Name if (status == QDF_STATUS_E_CANCELED) {
366*5113495bSYour Name /* a packet was flushed */
367*5113495bSYour Name flushing = true;
368*5113495bSYour Name }
369*5113495bSYour Name if (status != QDF_STATUS_E_RESOURCES) {
370*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
371*5113495bSYour Name "%s() -TX ERROR, status: 0x%x",
372*5113495bSYour Name __func__, status);
373*5113495bSYour Name }
374*5113495bSYour Name } else {
375*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_INFO, "%s: OK\n", __func__);
376*5113495bSYour Name flushing = false;
377*5113495bSYour Name }
378*5113495bSYour Name
379*5113495bSYour Name epping_free_cookie(adapter->pEpping_ctx, cookie);
380*5113495bSYour Name qdf_spin_unlock_bh(&adapter->data_lock);
381*5113495bSYour Name
382*5113495bSYour Name /* free all skbs in our local list */
383*5113495bSYour Name while (qdf_nbuf_queue_len(&skb_queue)) {
384*5113495bSYour Name /* use non-lock version */
385*5113495bSYour Name pktSkb = qdf_nbuf_queue_remove(&skb_queue);
386*5113495bSYour Name if (!pktSkb)
387*5113495bSYour Name break;
388*5113495bSYour Name qdf_nbuf_tx_free(pktSkb, QDF_NBUF_PKT_ERROR);
389*5113495bSYour Name pEpping_ctx->total_tx_acks++;
390*5113495bSYour Name }
391*5113495bSYour Name
392*5113495bSYour Name if (!flushing) {
393*5113495bSYour Name netif_wake_queue(dev);
394*5113495bSYour Name }
395*5113495bSYour Name }
396