xref: /wlan-dirver/qca-wifi-host-cmn/hif/src/usb/usbdrv.c (revision 11f5a63a6cbdda84849a730de22f0a71e635d58c)
1 /*
2  * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #define ATH_MODULE_NAME hif
20 #include "a_debug.h"
21 #include "hif_usb_internal.h"
22 #include "if_usb.h"
23 #include "cds_api.h"
24 #include "hif_debug.h"
25 
26 #define IS_BULK_EP(attr) (((attr) & 3) == 0x02)
27 #define IS_INT_EP(attr) (((attr) & 3) == 0x03)
28 #define IS_ISOC_EP(attr) (((attr) & 3) == 0x01)
29 #define IS_DIR_IN(addr) ((addr) & 0x80)
30 
31 #define IS_FW_CRASH_DUMP(x)(((x == FW_ASSERT_PATTERN) || \
32 				(x == FW_REG_PATTERN) || \
33 				((x & FW_RAMDUMP_PATTERN_MASK) ==  \
34 						FW_RAMDUMP_PATTERN)) ? 1 : 0)
35 
36 static void usb_hif_post_recv_transfers(struct HIF_USB_PIPE *recv_pipe,
37 					int buffer_length);
38 static void usb_hif_post_recv_bundle_transfers
39 						(struct HIF_USB_PIPE *recv_pipe,
40 						int buffer_length);
41 static void usb_hif_cleanup_recv_urb(struct HIF_URB_CONTEXT *urb_context);
42 
43 
44 /**
45  * usb_hif_free_urb_to_pipe() - add urb back to urb list of a pipe
46  * @pipe: pointer to struct HIF_USB_PIPE
47  * @urb_context: pointer to struct HIF_URB_CONTEXT
48  *
49  * Return: none
50  */
51 static void usb_hif_free_urb_to_pipe(struct HIF_USB_PIPE *pipe,
52 					struct HIF_URB_CONTEXT *urb_context)
53 {
54 	qdf_spin_lock_irqsave(&pipe->device->cs_lock);
55 	pipe->urb_cnt++;
56 	DL_ListAdd(&pipe->urb_list_head, &urb_context->link);
57 	qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
58 }
59 
60 /**
61  * usb_hif_alloc_urb_from_pipe() - remove urb back from urb list of a pipe
62  * @pipe: pointer to struct HIF_USB_PIPE
63  *
64  * Return: struct HIF_URB_CONTEXT urb context removed from the urb list
65  */
66 struct HIF_URB_CONTEXT *usb_hif_alloc_urb_from_pipe(struct HIF_USB_PIPE *pipe)
67 {
68 	struct HIF_URB_CONTEXT *urb_context = NULL;
69 	DL_LIST *item;
70 
71 	qdf_spin_lock_irqsave(&pipe->device->cs_lock);
72 	item = dl_list_remove_item_from_head(&pipe->urb_list_head);
73 	if (item) {
74 		urb_context = A_CONTAINING_STRUCT(item, struct HIF_URB_CONTEXT,
75 						  link);
76 		pipe->urb_cnt--;
77 	}
78 	qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
79 
80 	return urb_context;
81 }
82 
83 /**
84  * usb_hif_dequeue_pending_transfer() - remove urb from pending xfer list
85  * @pipe: pointer to struct HIF_USB_PIPE
86  *
87  * Return: struct HIF_URB_CONTEXT urb context removed from the pending xfer list
88  */
89 static struct HIF_URB_CONTEXT *usb_hif_dequeue_pending_transfer
90 						(struct HIF_USB_PIPE *pipe)
91 {
92 	struct HIF_URB_CONTEXT *urb_context = NULL;
93 	DL_LIST *item;
94 
95 	qdf_spin_lock_irqsave(&pipe->device->cs_lock);
96 	item = dl_list_remove_item_from_head(&pipe->urb_pending_list);
97 	if (item)
98 		urb_context = A_CONTAINING_STRUCT(item, struct HIF_URB_CONTEXT,
99 						  link);
100 	qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
101 
102 	return urb_context;
103 }
104 
105 /**
106  * usb_hif_enqueue_pending_transfer() - add urb to pending xfer list
107  * @pipe: pointer to struct HIF_USB_PIPE
108  * @urb_context: pointer to struct HIF_URB_CONTEXT to be added to the xfer list
109  *
110  * Return: none
111  */
112 void usb_hif_enqueue_pending_transfer(struct HIF_USB_PIPE *pipe,
113 					struct HIF_URB_CONTEXT *urb_context)
114 {
115 	qdf_spin_lock_irqsave(&pipe->device->cs_lock);
116 	dl_list_insert_tail(&pipe->urb_pending_list, &urb_context->link);
117 	qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
118 }
119 
120 
121 /**
122  * usb_hif_remove_pending_transfer() - remove urb from its own list
123  * @urb_context: pointer to struct HIF_URB_CONTEXT to be removed
124  *
125  * Return: none
126  */
127 void
128 usb_hif_remove_pending_transfer(struct HIF_URB_CONTEXT *urb_context)
129 {
130 	qdf_spin_lock_irqsave(&urb_context->pipe->device->cs_lock);
131 	dl_list_remove(&urb_context->link);
132 	qdf_spin_unlock_irqrestore(&urb_context->pipe->device->cs_lock);
133 }
134 
135 /**
136  * usb_hif_alloc_pipe_resources() - allocate urb_cnt urbs to a HIF pipe
137  * @pipe: pointer to struct HIF_USB_PIPE to which resources will be allocated
138  * @urb_cnt: number of urbs to be added to the HIF pipe
139  *
140  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
141  */
142 static QDF_STATUS usb_hif_alloc_pipe_resources
143 					(struct HIF_USB_PIPE *pipe, int urb_cnt)
144 {
145 	QDF_STATUS status = QDF_STATUS_SUCCESS;
146 	int i;
147 	struct HIF_URB_CONTEXT *urb_context;
148 
149 	DL_LIST_INIT(&pipe->urb_list_head);
150 	DL_LIST_INIT(&pipe->urb_pending_list);
151 
152 	for (i = 0; i < urb_cnt; i++) {
153 		urb_context = qdf_mem_malloc(sizeof(*urb_context));
154 		if (!urb_context) {
155 			status = QDF_STATUS_E_NOMEM;
156 			break;
157 		}
158 		urb_context->pipe = pipe;
159 		urb_context->urb = usb_alloc_urb(0, GFP_KERNEL);
160 
161 		if (!urb_context->urb) {
162 			status = QDF_STATUS_E_NOMEM;
163 			qdf_mem_free(urb_context);
164 			HIF_ERROR("urb_context->urb is null");
165 			break;
166 		}
167 
168 		/* note we are only allocate the urb contexts here, the actual
169 		 * URB is
170 		 * allocated from the kernel as needed to do a transaction
171 		 */
172 		pipe->urb_alloc++;
173 
174 		usb_hif_free_urb_to_pipe(pipe, urb_context);
175 	}
176 
177 	HIF_DBG("athusb: alloc resources lpipe:%d hpipe:0x%X urbs:%d",
178 		pipe->logical_pipe_num,
179 		pipe->usb_pipe_handle,
180 		pipe->urb_alloc);
181 	return status;
182 }
183 
184 /**
185  * usb_hif_free_pipe_resources() - free urb resources allocated to a HIF pipe
186  * @pipe: pointer to struct HIF_USB_PIPE
187  *
188  * Return: none
189  */
190 static void usb_hif_free_pipe_resources(struct HIF_USB_PIPE *pipe)
191 {
192 	struct HIF_URB_CONTEXT *urb_context;
193 
194 	if (!pipe->device) {
195 		/* nothing allocated for this pipe */
196 		HIF_ERROR("pipe->device is null");
197 		return;
198 	}
199 
200 	HIF_TRACE("athusb: free resources lpipe:%d hpipe:0x%X urbs:%d avail:%d",
201 			 pipe->logical_pipe_num,
202 			 pipe->usb_pipe_handle, pipe->urb_alloc,
203 			 pipe->urb_cnt);
204 
205 	if (pipe->urb_alloc != pipe->urb_cnt) {
206 		HIF_ERROR("athusb: urb leak! lpipe:%d hpipe:0x%X urbs:%d avail:%d",
207 				 pipe->logical_pipe_num,
208 				 pipe->usb_pipe_handle, pipe->urb_alloc,
209 				 pipe->urb_cnt);
210 	}
211 
212 	while (true) {
213 		urb_context = usb_hif_alloc_urb_from_pipe(pipe);
214 		if (!urb_context)
215 			break;
216 
217 		if (urb_context->buf) {
218 			qdf_nbuf_free(urb_context->buf);
219 			urb_context->buf = NULL;
220 		}
221 
222 		usb_free_urb(urb_context->urb);
223 		urb_context->urb = NULL;
224 		qdf_mem_free(urb_context);
225 	}
226 
227 }
228 
229 #ifdef QCN7605_SUPPORT
230 /**
231  * usb_hif_get_logical_pipe_num() - get pipe number for a particular enpoint
232  * @device: pointer to HIF_DEVICE_USB structure
233  * @ep_address: endpoint address
234  * @urb_count: number of urb resources to be allocated to the pipe
235  *
236  * Return: uint8_t pipe number corresponding to ep_address
237  */
238 static uint8_t usb_hif_get_logical_pipe_num(struct HIF_DEVICE_USB *device,
239 					    uint8_t ep_address,
240 					    int *urb_count)
241 {
242 	uint8_t pipe_num = HIF_USB_PIPE_INVALID;
243 
244 	switch (ep_address) {
245 	case USB_EP_ADDR_APP_CTRL_IN:
246 		pipe_num = HIF_RX_CTRL_PIPE;
247 		*urb_count = RX_URB_COUNT;
248 		break;
249 	case USB_EP_ADDR_APP_DATA_IN:
250 		pipe_num = HIF_RX_DATA_PIPE;
251 		*urb_count = RX_URB_COUNT;
252 		break;
253 		break;
254 	case USB_EP_ADDR_APP_CTRL_OUT:
255 		pipe_num = HIF_TX_CTRL_PIPE;
256 		*urb_count = TX_URB_COUNT;
257 		break;
258 	case USB_EP_ADDR_APP_DATA_OUT:
259 		pipe_num = HIF_TX_DATA_LP_PIPE;
260 		*urb_count = TX_URB_COUNT;
261 		break;
262 	default:
263 		/* note: there may be endpoints not currently used */
264 		break;
265 	}
266 
267 	return pipe_num;
268 }
269 #else
270 /**
271  * usb_hif_get_logical_pipe_num() - get pipe number for a particular enpoint
272  * @device: pointer to HIF_DEVICE_USB structure
273  * @ep_address: endpoint address
274  * @urb_count: number of urb resources to be allocated to the pipe
275  *
276  * Return: uint8_t pipe number corresponding to ep_address
277  */
278 static uint8_t usb_hif_get_logical_pipe_num
279 					(struct HIF_DEVICE_USB *device,
280 					uint8_t ep_address,
281 					int *urb_count)
282 {
283 	uint8_t pipe_num = HIF_USB_PIPE_INVALID;
284 
285 	switch (ep_address) {
286 	case USB_EP_ADDR_APP_CTRL_IN:
287 		pipe_num = HIF_RX_CTRL_PIPE;
288 		*urb_count = RX_URB_COUNT;
289 		break;
290 	case USB_EP_ADDR_APP_DATA_IN:
291 		pipe_num = HIF_RX_DATA_PIPE;
292 		*urb_count = RX_URB_COUNT;
293 		break;
294 	case USB_EP_ADDR_APP_INT_IN:
295 		pipe_num = HIF_RX_INT_PIPE;
296 		*urb_count = RX_URB_COUNT;
297 		break;
298 	case USB_EP_ADDR_APP_DATA2_IN:
299 		pipe_num = HIF_RX_DATA2_PIPE;
300 		*urb_count = RX_URB_COUNT;
301 		break;
302 	case USB_EP_ADDR_APP_CTRL_OUT:
303 		pipe_num = HIF_TX_CTRL_PIPE;
304 		*urb_count = TX_URB_COUNT;
305 		break;
306 	case USB_EP_ADDR_APP_DATA_LP_OUT:
307 		pipe_num = HIF_TX_DATA_LP_PIPE;
308 		*urb_count = TX_URB_COUNT;
309 		break;
310 	case USB_EP_ADDR_APP_DATA_MP_OUT:
311 		pipe_num = HIF_TX_DATA_MP_PIPE;
312 		*urb_count = TX_URB_COUNT;
313 		break;
314 	case USB_EP_ADDR_APP_DATA_HP_OUT:
315 		pipe_num = HIF_TX_DATA_HP_PIPE;
316 		*urb_count = TX_URB_COUNT;
317 		break;
318 	default:
319 		/* note: there may be endpoints not currently used */
320 		break;
321 	}
322 
323 	return pipe_num;
324 }
325 #endif /* QCN7605_SUPPORT */
326 
327 /**
328  * usb_hif_get_logical_pipe_num() - setup urb resources for all pipes
329  * @device: pointer to HIF_DEVICE_USB structure
330  *
331  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
332  */
333 QDF_STATUS usb_hif_setup_pipe_resources(struct HIF_DEVICE_USB *device)
334 {
335 	struct usb_interface *interface = device->interface;
336 	struct usb_host_interface *iface_desc = interface->cur_altsetting;
337 	struct usb_endpoint_descriptor *endpoint;
338 	int i;
339 	int urbcount;
340 	QDF_STATUS status = QDF_STATUS_SUCCESS;
341 	struct HIF_USB_PIPE *pipe;
342 	uint8_t pipe_num;
343 
344 	/* walk decriptors and setup pipes */
345 	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
346 		endpoint = &iface_desc->endpoint[i].desc;
347 
348 		if (IS_BULK_EP(endpoint->bmAttributes)) {
349 			HIF_DBG("%s Bulk Ep:0x%2.2X maxpktsz:%d",
350 				IS_DIR_IN(endpoint->bEndpointAddress) ?
351 								"RX" : "TX",
352 				endpoint->bEndpointAddress,
353 				qdf_le16_to_cpu(endpoint->wMaxPacketSize));
354 		} else if (IS_INT_EP(endpoint->bmAttributes)) {
355 			HIF_DBG("%s Int Ep:0x%2.2X maxpktsz:%d interval:%d",
356 				IS_DIR_IN(endpoint->bEndpointAddress) ?
357 								"RX" : "TX",
358 				endpoint->bEndpointAddress,
359 				qdf_le16_to_cpu(endpoint->wMaxPacketSize),
360 				endpoint->bInterval);
361 		} else if (IS_ISOC_EP(endpoint->bmAttributes)) {
362 			/* TODO for ISO */
363 			HIF_DBG("%s ISOC Ep:0x%2.2X maxpktsz:%d interval:%d",
364 				IS_DIR_IN(endpoint->bEndpointAddress) ?
365 								"RX" : "TX",
366 				endpoint->bEndpointAddress,
367 				qdf_le16_to_cpu(endpoint->wMaxPacketSize),
368 				endpoint->bInterval);
369 		}
370 		urbcount = 0;
371 
372 		pipe_num = usb_hif_get_logical_pipe_num(device,
373 						endpoint->bEndpointAddress,
374 						&urbcount);
375 		if (HIF_USB_PIPE_INVALID == pipe_num)
376 			continue;
377 
378 		pipe = &device->pipes[pipe_num];
379 		if (pipe->device) {
380 			/*pipe was already setup */
381 			continue;
382 		}
383 
384 		pipe->device = device;
385 		pipe->logical_pipe_num = pipe_num;
386 		pipe->ep_address = endpoint->bEndpointAddress;
387 		pipe->max_packet_size =
388 			qdf_le16_to_cpu(endpoint->wMaxPacketSize);
389 
390 		if (IS_BULK_EP(endpoint->bmAttributes)) {
391 			if (IS_DIR_IN(pipe->ep_address)) {
392 				pipe->usb_pipe_handle =
393 					usb_rcvbulkpipe(device->udev,
394 							pipe->ep_address);
395 			} else {
396 				pipe->usb_pipe_handle =
397 					usb_sndbulkpipe(device->udev,
398 						pipe->ep_address);
399 			}
400 		} else if (IS_INT_EP(endpoint->bmAttributes)) {
401 			if (IS_DIR_IN(pipe->ep_address)) {
402 				pipe->usb_pipe_handle =
403 					usb_rcvintpipe(device->udev,
404 						pipe->ep_address);
405 			} else {
406 				pipe->usb_pipe_handle =
407 					usb_sndintpipe(device->udev,
408 						pipe->ep_address);
409 			}
410 		} else if (IS_ISOC_EP(endpoint->bmAttributes)) {
411 			/* TODO for ISO */
412 			if (IS_DIR_IN(pipe->ep_address)) {
413 				pipe->usb_pipe_handle =
414 					usb_rcvisocpipe(device->udev,
415 						pipe->ep_address);
416 			} else {
417 				pipe->usb_pipe_handle =
418 					usb_sndisocpipe(device->udev,
419 						pipe->ep_address);
420 			}
421 		}
422 		pipe->ep_desc = endpoint;
423 
424 		if (!IS_DIR_IN(pipe->ep_address))
425 			pipe->flags |= HIF_USB_PIPE_FLAG_TX;
426 
427 		status = usb_hif_alloc_pipe_resources(pipe, urbcount);
428 
429 		if (!QDF_IS_STATUS_SUCCESS(status))
430 			break;
431 
432 	}
433 
434 	return status;
435 }
436 
437 
438 /**
439  * usb_hif_cleanup_pipe_resources() - free urb resources for all pipes
440  * @device: pointer to HIF_DEVICE_USB structure
441  *
442  * Return: none
443  */
444 void usb_hif_cleanup_pipe_resources(struct HIF_DEVICE_USB *device)
445 {
446 	int i;
447 
448 	for (i = 0; i < HIF_USB_PIPE_MAX; i++)
449 		usb_hif_free_pipe_resources(&device->pipes[i]);
450 }
451 
452 /**
453  * usb_hif_flush_pending_transfers() - kill pending urbs for a pipe
454  * @pipe: pointer to struct HIF_USB_PIPE structure
455  *
456  * Return: none
457  */
458 static void usb_hif_flush_pending_transfers(struct HIF_USB_PIPE *pipe)
459 {
460 	struct HIF_URB_CONTEXT *urb_context;
461 
462 	HIF_TRACE("+%s pipe : %d", __func__, pipe->logical_pipe_num);
463 
464 	while (1) {
465 		urb_context = usb_hif_dequeue_pending_transfer(pipe);
466 		if (!urb_context) {
467 			HIF_WARN("urb_context is NULL");
468 			break;
469 		}
470 		HIF_TRACE("  pending urb ctxt: 0x%pK", urb_context);
471 		if (urb_context->urb) {
472 			HIF_TRACE("  killing urb: 0x%pK", urb_context->urb);
473 			/* killing the URB will cause the completion routines to
474 			 * run
475 			 */
476 			usb_kill_urb(urb_context->urb);
477 		}
478 	}
479 	HIF_TRACE("-%s", __func__);
480 }
481 
482 /**
483  * usb_hif_flush_all() - flush pending transfers for all pipes for a usb bus
484  * @device: pointer to HIF_DEVICE_USB structure
485  *
486  * Return: none
487  */
488 void usb_hif_flush_all(struct HIF_DEVICE_USB *device)
489 {
490 	int i;
491 	struct HIF_USB_PIPE *pipe;
492 
493 	HIF_TRACE("+%s", __func__);
494 
495 	for (i = 0; i < HIF_USB_PIPE_MAX; i++) {
496 		if (device->pipes[i].device) {
497 			usb_hif_flush_pending_transfers(&device->pipes[i]);
498 			pipe = &device->pipes[i];
499 
500 		HIF_USB_FLUSH_WORK(pipe);
501 		}
502 	}
503 
504 	HIF_TRACE("-%s", __func__);
505 }
506 
507 /**
508  * usb_hif_cleanup_recv_urb() - cleanup recv urb
509  * @urb_context: pointer to struct HIF_URB_CONTEXT structure
510  *
511  * Return: none
512  */
513 static void usb_hif_cleanup_recv_urb(struct HIF_URB_CONTEXT *urb_context)
514 {
515 
516 	if (urb_context->buf) {
517 		qdf_nbuf_free(urb_context->buf);
518 		urb_context->buf = NULL;
519 	}
520 
521 	usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context);
522 }
523 
524 /**
525  * usb_hif_cleanup_transmit_urb() - cleanup transmit urb
526  * @urb_context: pointer to struct HIF_URB_CONTEXT structure
527  *
528  * Return: none
529  */
530 void usb_hif_cleanup_transmit_urb(struct HIF_URB_CONTEXT *urb_context)
531 {
532 	usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context);
533 }
534 
535 /**
536  * usb_hif_usb_recv_prestart_complete() - completion routine for prestart rx urb
537  * @urb: urb for which the completion routine is being called
538  *
539  * Return: none
540  */
541 static void usb_hif_usb_recv_prestart_complete
542 							(struct urb *urb)
543 {
544 	struct HIF_URB_CONTEXT *urb_context =
545 					(struct HIF_URB_CONTEXT *) urb->context;
546 	QDF_STATUS status = QDF_STATUS_SUCCESS;
547 	qdf_nbuf_t buf = NULL;
548 	struct HIF_USB_PIPE *pipe = urb_context->pipe;
549 	struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device);
550 
551 	HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK",
552 		__func__,
553 		pipe->logical_pipe_num,
554 		urb->status, urb->actual_length,
555 		urb);
556 
557 	/* this urb is not pending anymore */
558 	usb_hif_remove_pending_transfer(urb_context);
559 	do {
560 		if (urb->status != 0) {
561 			status = A_ECOMM;
562 			switch (urb->status) {
563 			case -ECONNRESET:
564 			case -ENOENT:
565 			case -ESHUTDOWN:
566 				/* NOTE: no need to spew these errors when
567 				 * device is removed
568 				 * or urb is killed due to driver shutdown
569 				 */
570 				status = A_ECANCELED;
571 				break;
572 			default:
573 				HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
574 					__func__,
575 					pipe->logical_pipe_num,
576 					pipe->ep_address,
577 					urb->status);
578 				break;
579 			}
580 			break;
581 		}
582 		if (urb->actual_length == 0)
583 			break;
584 		buf = urb_context->buf;
585 		/* we are going to pass it up */
586 		urb_context->buf = NULL;
587 		qdf_nbuf_put_tail(buf, urb->actual_length);
588 
589 		if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
590 			uint8_t *data;
591 			uint32_t len;
592 
593 			qdf_nbuf_peek_header(buf, &data, &len);
594 			debug_dump_bytes(data, len, "hif recv data");
595 		}
596 		/* note: queue implements a lock */
597 		skb_queue_tail(&pipe->io_comp_queue, buf);
598 
599 		HIF_USB_SCHEDULE_WORK(pipe);
600 	} while (false);
601 
602 	usb_hif_cleanup_recv_urb(urb_context);
603 
604 	/* Prestart URBs runs out and now start working receive pipe. */
605 	qdf_spin_lock_irqsave(&pipe->device->rx_prestart_lock);
606 	if ((--pipe->urb_prestart_cnt == 0) && !sc->suspend_state)
607 		usb_hif_start_recv_pipes(pipe->device);
608 	qdf_spin_unlock_irqrestore(&pipe->device->rx_prestart_lock);
609 
610 	HIF_DBG("-%s", __func__);
611 }
612 
613 /**
614  * usb_hif_usb_recv_complete() - completion routine for rx urb
615  * @urb: urb for which the completion routine is being called
616  *
617  * Return: none
618  */
619 static void usb_hif_usb_recv_complete(struct urb *urb)
620 {
621 	struct HIF_URB_CONTEXT *urb_context =
622 					(struct HIF_URB_CONTEXT *) urb->context;
623 	QDF_STATUS status = QDF_STATUS_SUCCESS;
624 	qdf_nbuf_t buf = NULL;
625 	struct HIF_USB_PIPE *pipe = urb_context->pipe;
626 	struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device);
627 
628 	HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK",
629 		__func__,
630 		pipe->logical_pipe_num,
631 		urb->status, urb->actual_length,
632 		urb);
633 
634 	/* this urb is not pending anymore */
635 	usb_hif_remove_pending_transfer(urb_context);
636 
637 	do {
638 
639 		if (urb->status != 0) {
640 			status = A_ECOMM;
641 			switch (urb->status) {
642 #ifdef RX_SG_SUPPORT
643 			case -EOVERFLOW:
644 				urb->actual_length = HIF_USB_RX_BUFFER_SIZE;
645 				status = QDF_STATUS_SUCCESS;
646 				break;
647 #endif
648 			case -ECONNRESET:
649 			case -ENOENT:
650 			case -ESHUTDOWN:
651 				/* NOTE: no need to spew these errors when
652 				 * device is removed
653 				 * or urb is killed due to driver shutdown
654 				 */
655 				status = A_ECANCELED;
656 				break;
657 			default:
658 				HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
659 					__func__,
660 					pipe->logical_pipe_num,
661 					pipe->ep_address,
662 					urb->status);
663 				break;
664 			}
665 			break;
666 		}
667 		if (urb->actual_length == 0)
668 			break;
669 		buf = urb_context->buf;
670 		/* we are going to pass it up */
671 		urb_context->buf = NULL;
672 		qdf_nbuf_put_tail(buf, urb->actual_length);
673 		if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
674 			uint8_t *data;
675 			uint32_t len;
676 
677 			qdf_nbuf_peek_header(buf, &data, &len);
678 			debug_dump_bytes(data, len, "hif recv data");
679 		}
680 		/* note: queue implements a lock */
681 		skb_queue_tail(&pipe->io_comp_queue, buf);
682 		HIF_USB_SCHEDULE_WORK(pipe);
683 	} while (false);
684 
685 	usb_hif_cleanup_recv_urb(urb_context);
686 
687 	/* Only re-submit URB when STATUS is success and HIF is not at the
688 	 * suspend state.
689 	 */
690 	if (QDF_IS_STATUS_SUCCESS(status) && !sc->suspend_state) {
691 		if (pipe->urb_cnt >= pipe->urb_cnt_thresh) {
692 			/* our free urbs are piling up, post more transfers */
693 			usb_hif_post_recv_transfers(pipe,
694 						HIF_USB_RX_BUFFER_SIZE);
695 		}
696 	} else {
697 		HIF_ERROR("%s:  pipe: %d, fail to post URB: status(%d) suspend (%d)",
698 				__func__,
699 				pipe->logical_pipe_num,
700 				urb->status,
701 				sc->suspend_state);
702 	}
703 
704 	HIF_DBG("-%s", __func__);
705 }
706 
707 /**
708  * usb_hif_usb_recv_bundle_complete() - completion routine for rx bundling urb
709  * @urb: urb for which the completion routine is being called
710  *
711  * Return: none
712  */
713 static void usb_hif_usb_recv_bundle_complete(struct urb *urb)
714 {
715 	struct HIF_URB_CONTEXT *urb_context =
716 					(struct HIF_URB_CONTEXT *) urb->context;
717 	QDF_STATUS status = QDF_STATUS_SUCCESS;
718 	qdf_nbuf_t buf = NULL;
719 	struct HIF_USB_PIPE *pipe = urb_context->pipe;
720 	uint8_t *netdata, *netdata_new;
721 	uint32_t netlen, netlen_new;
722 	HTC_FRAME_HDR *HtcHdr;
723 	uint16_t payloadLen;
724 	qdf_nbuf_t new_skb = NULL;
725 
726 	HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK",
727 		__func__,
728 		pipe->logical_pipe_num,
729 		urb->status, urb->actual_length,
730 		urb);
731 
732 	/* this urb is not pending anymore */
733 	usb_hif_remove_pending_transfer(urb_context);
734 
735 	do {
736 
737 		if (urb->status != 0) {
738 			status = A_ECOMM;
739 			switch (urb->status) {
740 			case -ECONNRESET:
741 			case -ENOENT:
742 			case -ESHUTDOWN:
743 				/* NOTE: no need to spew these errors when
744 				 * device is removed
745 				 * or urb is killed due to driver shutdown
746 				 */
747 				status = A_ECANCELED;
748 				break;
749 			default:
750 				HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
751 					__func__,
752 					pipe->logical_pipe_num,
753 					pipe->ep_address,
754 					urb->status);
755 				break;
756 			}
757 			break;
758 		}
759 		if (urb->actual_length == 0)
760 			break;
761 		buf = urb_context->buf;
762 		if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
763 			uint8_t *data;
764 			uint32_t len;
765 
766 			qdf_nbuf_peek_header(buf, &data, &len);
767 			debug_dump_bytes(data, len, "hif recv data");
768 		}
769 
770 		qdf_nbuf_peek_header(buf, &netdata, &netlen);
771 		netlen = urb->actual_length;
772 
773 		do {
774 			uint16_t frame_len;
775 
776 			if (IS_FW_CRASH_DUMP(*(uint32_t *) netdata))
777 				frame_len = netlen;
778 			else {
779 				/* Hack into HTC header for bundle processing */
780 				HtcHdr = (HTC_FRAME_HDR *) netdata;
781 				if (HtcHdr->EndpointID >= ENDPOINT_MAX) {
782 					HIF_ERROR("athusb: Rx: invalid EndpointID=%d",
783 						HtcHdr->EndpointID);
784 					break;
785 				}
786 
787 				payloadLen = HtcHdr->PayloadLen;
788 				payloadLen = qdf_le16_to_cpu(payloadLen);
789 
790 				if (payloadLen > HIF_USB_RX_BUFFER_SIZE) {
791 					HIF_ERROR("athusb: payloadLen too long %u",
792 						payloadLen);
793 					break;
794 				}
795 				frame_len = (HTC_HDR_LENGTH + payloadLen);
796 			}
797 
798 			if (netlen < frame_len) {
799 				HIF_ERROR("athusb: subframe length %d not fitted into bundle packet length %d"
800 					, netlen, frame_len);
801 				break;
802 			}
803 
804 			/* allocate a new skb and copy */
805 			new_skb =
806 				qdf_nbuf_alloc(NULL, frame_len, 0, 4, false);
807 			if (!new_skb) {
808 				HIF_ERROR("athusb: allocate skb (len=%u) failed"
809 						, frame_len);
810 				break;
811 			}
812 
813 			qdf_nbuf_peek_header(new_skb, &netdata_new,
814 						&netlen_new);
815 			qdf_mem_copy(netdata_new, netdata, frame_len);
816 			qdf_nbuf_put_tail(new_skb, frame_len);
817 			skb_queue_tail(&pipe->io_comp_queue, new_skb);
818 			new_skb = NULL;
819 			netdata += frame_len;
820 			netlen -= frame_len;
821 		} while (netlen);
822 		HIF_USB_SCHEDULE_WORK(pipe);
823 	} while (false);
824 
825 	if (!urb_context->buf)
826 		HIF_ERROR("athusb: buffer in urb_context is NULL");
827 
828 	/* reset urb_context->buf ==> seems not necessary */
829 	usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context);
830 
831 	if (QDF_IS_STATUS_SUCCESS(status)) {
832 		if (pipe->urb_cnt >= pipe->urb_cnt_thresh) {
833 			/* our free urbs are piling up, post more transfers */
834 			usb_hif_post_recv_bundle_transfers(pipe,
835 					pipe->device->rx_bundle_buf_len);
836 		}
837 	}
838 
839 	HIF_DBG("-%s", __func__);
840 }
841 
842 /**
843  * usb_hif_post_recv_prestart_transfers() - post prestart recv urbs for a pipe
844  * @recv_pipe: rx data pipe
845  * @prestart_urb: number of prestart recv urbs to be posted
846  *
847  * Return: none
848  */
849 static void usb_hif_post_recv_prestart_transfers(struct HIF_USB_PIPE *recv_pipe,
850 						int prestart_urb)
851 {
852 	struct HIF_URB_CONTEXT *urb_context;
853 	uint8_t *data;
854 	uint32_t len;
855 	struct urb *urb;
856 	int i, usb_status, buffer_length = HIF_USB_RX_BUFFER_SIZE;
857 
858 	HIF_TRACE("+%s", __func__);
859 
860 	qdf_spin_lock_irqsave(&recv_pipe->device->rx_prestart_lock);
861 	for (i = 0; i < prestart_urb; i++) {
862 		urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
863 		if (!urb_context)
864 			break;
865 
866 		urb_context->buf =
867 			qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false);
868 		if (!urb_context->buf) {
869 			usb_hif_cleanup_recv_urb(urb_context);
870 			break;
871 		}
872 
873 		qdf_nbuf_peek_header(urb_context->buf, &data, &len);
874 
875 		urb = urb_context->urb;
876 
877 		usb_fill_bulk_urb(urb,
878 				recv_pipe->device->udev,
879 				recv_pipe->usb_pipe_handle,
880 				data,
881 				buffer_length,
882 				usb_hif_usb_recv_prestart_complete,
883 				urb_context);
884 
885 		HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK",
886 			recv_pipe->logical_pipe_num,
887 			recv_pipe->usb_pipe_handle,
888 			recv_pipe->ep_address, buffer_length,
889 			urb_context->buf);
890 
891 		usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
892 		usb_status = usb_submit_urb(urb, GFP_ATOMIC);
893 
894 		if (usb_status) {
895 			HIF_ERROR("athusb : usb bulk recv failed %d",
896 				usb_status);
897 			usb_hif_remove_pending_transfer(urb_context);
898 			usb_hif_cleanup_recv_urb(urb_context);
899 			break;
900 		}
901 		recv_pipe->urb_prestart_cnt++;
902 	}
903 	qdf_spin_unlock_irqrestore(&recv_pipe->device->rx_prestart_lock);
904 
905 	HIF_TRACE("-%s", __func__);
906 }
907 
908 /**
909  * usb_hif_post_recv_transfers() - post recv urbs for a given pipe
910  * @recv_pipe: recv pipe for which urbs need to be posted
911  * @buffer_length: buffer length of the recv urbs
912  *
913  * Return: none
914  */
915 static void usb_hif_post_recv_transfers(struct HIF_USB_PIPE *recv_pipe,
916 							int buffer_length)
917 {
918 	struct HIF_URB_CONTEXT *urb_context;
919 	uint8_t *data;
920 	uint32_t len;
921 	struct urb *urb;
922 	int usb_status;
923 
924 	while (1) {
925 
926 		urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
927 		if (!urb_context)
928 			break;
929 
930 		urb_context->buf = qdf_nbuf_alloc(NULL, buffer_length, 0,
931 						4, false);
932 		if (!urb_context->buf) {
933 			usb_hif_cleanup_recv_urb(urb_context);
934 			break;
935 		}
936 
937 		qdf_nbuf_peek_header(urb_context->buf, &data, &len);
938 
939 		urb = urb_context->urb;
940 
941 		usb_fill_bulk_urb(urb,
942 				recv_pipe->device->udev,
943 				recv_pipe->usb_pipe_handle,
944 				data,
945 				buffer_length,
946 				usb_hif_usb_recv_complete, urb_context);
947 
948 		HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK",
949 			recv_pipe->logical_pipe_num,
950 			recv_pipe->usb_pipe_handle,
951 			recv_pipe->ep_address, buffer_length,
952 			urb_context->buf);
953 
954 		usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
955 
956 		usb_status = usb_submit_urb(urb, GFP_ATOMIC);
957 
958 		if (usb_status) {
959 			HIF_ERROR("athusb : usb bulk recv failed %d",
960 				usb_status);
961 			usb_hif_remove_pending_transfer(urb_context);
962 			usb_hif_cleanup_recv_urb(urb_context);
963 			break;
964 		}
965 	}
966 
967 }
968 
969 /**
970  * usb_hif_post_recv_bundle_transfers() - post recv urbs for a given pipe
971  * @recv_pipe: recv pipe for which urbs need to be posted
972  * @buffer_length: maximum length of rx bundle
973  *
974  * Return: none
975  */
976 static void usb_hif_post_recv_bundle_transfers(struct HIF_USB_PIPE *recv_pipe,
977 						int buffer_length)
978 {
979 	struct HIF_URB_CONTEXT *urb_context;
980 	uint8_t *data;
981 	uint32_t len;
982 	struct urb *urb;
983 	int usb_status;
984 
985 	while (1) {
986 
987 		urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
988 		if (!urb_context)
989 			break;
990 
991 		if (!urb_context->buf) {
992 			urb_context->buf =
993 			qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false);
994 			if (!urb_context->buf) {
995 				usb_hif_cleanup_recv_urb(urb_context);
996 				break;
997 			}
998 		}
999 
1000 		qdf_nbuf_peek_header(urb_context->buf, &data, &len);
1001 
1002 		urb = urb_context->urb;
1003 		usb_fill_bulk_urb(urb,
1004 				recv_pipe->device->udev,
1005 				recv_pipe->usb_pipe_handle,
1006 				data,
1007 				buffer_length,
1008 				usb_hif_usb_recv_bundle_complete,
1009 				urb_context);
1010 
1011 		HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK",
1012 			recv_pipe->logical_pipe_num,
1013 			recv_pipe->usb_pipe_handle,
1014 			recv_pipe->ep_address, buffer_length,
1015 			urb_context->buf);
1016 
1017 		usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
1018 
1019 		usb_status = usb_submit_urb(urb, GFP_ATOMIC);
1020 
1021 		if (usb_status) {
1022 			HIF_ERROR("athusb : usb bulk recv failed %d",
1023 				usb_status);
1024 			usb_hif_remove_pending_transfer(urb_context);
1025 			usb_hif_free_urb_to_pipe(urb_context->pipe,
1026 						urb_context);
1027 			break;
1028 		}
1029 
1030 	}
1031 
1032 }
1033 
1034 /**
1035  * usb_hif_prestart_recv_pipes() - post prestart recv urbs
1036  * @device: HIF device for which prestart recv urbs need to be posted
1037  *
1038  * Return: none
1039  */
1040 void usb_hif_prestart_recv_pipes(struct HIF_DEVICE_USB *device)
1041 {
1042 	struct HIF_USB_PIPE *pipe;
1043 	int prestart_cnt = 8;
1044 
1045 	if (device->rx_ctrl_pipe_supported) {
1046 		pipe = &device->pipes[HIF_RX_CTRL_PIPE];
1047 		prestart_cnt = 4;
1048 		usb_hif_post_recv_prestart_transfers(pipe, prestart_cnt);
1049 	}
1050 	/*
1051 	 * USB driver learn to support bundle or not until the firmware
1052 	 * download and ready. Only allocate some URBs for control message
1053 	 * communication during the initial phase then start the final
1054 	 * working pipe after all information understood.
1055 	 */
1056 	pipe = &device->pipes[HIF_RX_DATA_PIPE];
1057 	usb_hif_post_recv_prestart_transfers(pipe, prestart_cnt);
1058 }
1059 
1060 /**
1061  * usb_hif_start_recv_pipes() - start recv urbs
1062  * @device: HIF device for which recv urbs need to be posted
1063  *
1064  * This function is called after all prestart recv urbs are exhausted
1065  *
1066  * Return: none
1067  */
1068 void usb_hif_start_recv_pipes(struct HIF_DEVICE_USB *device)
1069 {
1070 	struct HIF_USB_PIPE *pipe;
1071 	uint32_t buf_len;
1072 
1073 	HIF_ENTER();
1074 	pipe = &device->pipes[HIF_RX_DATA_PIPE];
1075 	pipe->urb_cnt_thresh = pipe->urb_alloc / 2;
1076 
1077 	HIF_TRACE("Post URBs to RX_DATA_PIPE: %d is_bundle %d",
1078 		  device->pipes[HIF_RX_DATA_PIPE].urb_cnt,
1079 		  device->is_bundle_enabled);
1080 	if (device->is_bundle_enabled) {
1081 		usb_hif_post_recv_bundle_transfers(pipe,
1082 					pipe->device->rx_bundle_buf_len);
1083 	} else {
1084 		buf_len = HIF_USB_RX_BUFFER_SIZE;
1085 		usb_hif_post_recv_transfers(pipe, buf_len);
1086 	}
1087 
1088 	HIF_DBG("athusb bulk recv len %d", buf_len);
1089 
1090 	if (!hif_usb_disable_rxdata2) {
1091 		HIF_TRACE("Post URBs to RX_DATA2_PIPE: %d",
1092 			device->pipes[HIF_RX_DATA2_PIPE].urb_cnt);
1093 
1094 		pipe = &device->pipes[HIF_RX_DATA2_PIPE];
1095 		pipe->urb_cnt_thresh = pipe->urb_alloc / 2;
1096 		usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE);
1097 	}
1098 
1099 	if (device->rx_ctrl_pipe_supported) {
1100 		HIF_TRACE("Post URBs to RX_CONTROL_PIPE: %d",
1101 			  device->pipes[HIF_RX_CTRL_PIPE].urb_cnt);
1102 
1103 		pipe = &device->pipes[HIF_RX_CTRL_PIPE];
1104 		pipe->urb_cnt_thresh = pipe->urb_alloc / 2;
1105 		usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE);
1106 	}
1107 	HIF_EXIT();
1108 }
1109 
1110 /**
1111  * usb_hif_submit_ctrl_out() - send out a ctrl urb
1112  * @device: HIF device for which urb needs to be posted
1113  * @req: request value for the ctrl message
1114  * @value: USB message value
1115  * @index: USB message index value
1116  * @data: pointer to data containing ctrl message to send
1117  * @size: size of the control message to send
1118  *
1119  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
1120  */
1121 QDF_STATUS usb_hif_submit_ctrl_out(struct HIF_DEVICE_USB *device,
1122 				   uint8_t req, uint16_t value, uint16_t index,
1123 				   void *data, uint32_t size)
1124 {
1125 	int32_t result = 0;
1126 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
1127 	uint8_t *buf = NULL;
1128 
1129 	do {
1130 
1131 		if (size > 0) {
1132 			buf = qdf_mem_malloc(size);
1133 			if (!buf) {
1134 				ret = QDF_STATUS_E_NOMEM;
1135 				break;
1136 			}
1137 			qdf_mem_copy(buf, (uint8_t *) data, size);
1138 		}
1139 
1140 		HIF_DBG("ctrl-out req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d",
1141 				req, value, index, size);
1142 
1143 		result = usb_control_msg(device->udev,
1144 					usb_sndctrlpipe(device->udev, 0),
1145 					req,
1146 					USB_DIR_OUT | USB_TYPE_VENDOR |
1147 					USB_RECIP_DEVICE, value, index, buf,
1148 					size, 2 * HZ);
1149 
1150 		if (result < 0) {
1151 			HIF_ERROR("%s failed,result = %d", __func__, result);
1152 			ret = QDF_STATUS_E_FAILURE;
1153 		}
1154 
1155 	} while (false);
1156 
1157 	if (buf)
1158 		qdf_mem_free(buf);
1159 
1160 	return ret;
1161 }
1162 
1163 /**
1164  * usb_hif_submit_ctrl_in() - recv a resonse to the ctrl message sent out
1165  * @device: HIF device for which urb needs to be received
1166  * @req: request value for the ctrl message
1167  * @value: USB message value
1168  * @index: USB message index value
1169  * @data: pointer to data containing ctrl message to be received
1170  * @size: size of the control message to be received
1171  *
1172  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
1173  */
1174 QDF_STATUS usb_hif_submit_ctrl_in(struct HIF_DEVICE_USB *device,
1175 				  uint8_t req, uint16_t value, uint16_t index,
1176 				  void *data, uint32_t size)
1177 {
1178 	int32_t result = 0;
1179 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
1180 	uint8_t *buf = NULL;
1181 
1182 	do {
1183 
1184 		if (size > 0) {
1185 			buf = qdf_mem_malloc(size);
1186 			if (!buf) {
1187 				ret = QDF_STATUS_E_NOMEM;
1188 				break;
1189 			}
1190 		}
1191 
1192 		HIF_DBG("ctrl-in req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d",
1193 				 req, value, index, size);
1194 
1195 		result = usb_control_msg(device->udev,
1196 					usb_rcvctrlpipe(device->udev, 0),
1197 					req,
1198 					USB_DIR_IN | USB_TYPE_VENDOR |
1199 					USB_RECIP_DEVICE, value, index, buf,
1200 					size, 2 * HZ);
1201 
1202 		if (result < 0) {
1203 			HIF_ERROR("%s failed, result = %d", __func__, result);
1204 			ret = QDF_STATUS_E_FAILURE;
1205 			break;
1206 		}
1207 
1208 		qdf_mem_copy((uint8_t *) data, buf, size);
1209 
1210 	} while (false);
1211 
1212 	if (buf)
1213 		qdf_mem_free(buf);
1214 
1215 	return ret;
1216 }
1217 
1218 /**
1219  * usb_hif_io_complete() - transmit call back for tx urb
1220  * @pipe: pointer to struct HIF_USB_PIPE
1221  *
1222  * Return: none
1223  */
1224 static void usb_hif_io_complete(struct HIF_USB_PIPE *pipe)
1225 {
1226 	qdf_nbuf_t buf;
1227 	struct HIF_DEVICE_USB *device;
1228 	HTC_FRAME_HDR *HtcHdr;
1229 	uint8_t *data;
1230 	uint32_t len;
1231 	struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device);
1232 
1233 	device = pipe->device;
1234 	HIF_ENTER();
1235 	while ((buf = skb_dequeue(&pipe->io_comp_queue))) {
1236 		if (pipe->flags & HIF_USB_PIPE_FLAG_TX) {
1237 			HIF_DBG("+athusb xmit callback buf:0x%pK", buf);
1238 			HtcHdr = (HTC_FRAME_HDR *)
1239 					qdf_nbuf_get_frag_vaddr(buf, 0);
1240 
1241 #ifdef ATH_11AC_TXCOMPACT
1242 /* ATH_11AC_TXCOMPACT does not support High Latency mode */
1243 #else
1244 			device->htc_callbacks.txCompletionHandler(device->
1245 								htc_callbacks.
1246 								Context, buf,
1247 								HtcHdr->
1248 								EndpointID, 0);
1249 #endif
1250 			HIF_DBG("-athusb xmit callback");
1251 		} else {
1252 			HIF_DBG("+athusb recv callback buf: 0x%pK", buf);
1253 			qdf_nbuf_peek_header(buf, &data, &len);
1254 
1255 			if (IS_FW_CRASH_DUMP(*((uint32_t *) data))) {
1256 				sc->fw_data = data;
1257 				sc->fw_data_len = len;
1258 				device->htc_callbacks.fwEventHandler(
1259 					device->htc_callbacks.Context,
1260 					QDF_STATUS_E_USB_ERROR);
1261 				qdf_nbuf_free(buf);
1262 			} else {
1263 				device->htc_callbacks.rxCompletionHandler(
1264 				device->htc_callbacks.Context, buf,
1265 				pipe->logical_pipe_num);
1266 			}
1267 			HIF_DBG("-athusb recv callback");
1268 		}
1269 	}
1270 
1271 	HIF_EXIT();
1272 }
1273 
1274 #ifdef HIF_USB_TASKLET
1275 /**
1276  * usb_hif_io_comp_tasklet() - per pipe tasklet routine
1277  * @context: pointer to HIF USB pipe
1278  *
1279  * Return: none
1280  */
1281 void usb_hif_io_comp_tasklet(unsigned long context)
1282 {
1283 	struct HIF_USB_PIPE *pipe = (struct HIF_USB_PIPE *) context;
1284 
1285 	usb_hif_io_complete(pipe);
1286 }
1287 
1288 #else
1289 /**
1290  * usb_hif_io_comp_work() - per pipe work queue
1291  * @work: pointer to struct work_struct
1292  *
1293  * Return: none
1294  */
1295 void usb_hif_io_comp_work(struct work_struct *work)
1296 {
1297 	struct HIF_USB_PIPE *pipe = container_of(work, struct HIF_USB_PIPE,
1298 						 io_complete_work);
1299 
1300 	usb_hif_io_complete(pipe);
1301 }
1302 #endif
1303