xref: /wlan-dirver/qca-wifi-host-cmn/hif/src/usb/usbdrv.c (revision 8ddef7dd9a290d4a9b1efd5d3efacf51d78a1a0d)
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 != NULL) {
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 != NULL)
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 (NULL == 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 (NULL == 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 != NULL) {
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 (NULL == 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 != NULL) {
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 != NULL) {
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 != NULL) {
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 
550 	HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK",
551 		__func__,
552 		pipe->logical_pipe_num,
553 		urb->status, urb->actual_length,
554 		urb);
555 
556 	/* this urb is not pending anymore */
557 	usb_hif_remove_pending_transfer(urb_context);
558 	do {
559 		if (urb->status != 0) {
560 			status = A_ECOMM;
561 			switch (urb->status) {
562 			case -ECONNRESET:
563 			case -ENOENT:
564 			case -ESHUTDOWN:
565 				/* NOTE: no need to spew these errors when
566 				 * device is removed
567 				 * or urb is killed due to driver shutdown
568 				 */
569 				status = A_ECANCELED;
570 				break;
571 			default:
572 				HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
573 					__func__,
574 					pipe->logical_pipe_num,
575 					pipe->ep_address,
576 					urb->status);
577 				break;
578 			}
579 			break;
580 		}
581 		if (urb->actual_length == 0)
582 			break;
583 		buf = urb_context->buf;
584 		/* we are going to pass it up */
585 		urb_context->buf = NULL;
586 		qdf_nbuf_put_tail(buf, urb->actual_length);
587 
588 		if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
589 			uint8_t *data;
590 			uint32_t len;
591 
592 			qdf_nbuf_peek_header(buf, &data, &len);
593 			debug_dump_bytes(data, len, "hif recv data");
594 		}
595 		/* note: queue implements a lock */
596 		skb_queue_tail(&pipe->io_comp_queue, buf);
597 
598 		HIF_USB_SCHEDULE_WORK(pipe);
599 	} while (false);
600 
601 	usb_hif_cleanup_recv_urb(urb_context);
602 
603 	/* Prestart URBs runs out and now start working receive pipe. */
604 	if (--pipe->urb_prestart_cnt == 0)
605 		usb_hif_start_recv_pipes(pipe->device);
606 
607 	HIF_DBG("-%s", __func__);
608 }
609 
610 /**
611  * usb_hif_usb_recv_complete() - completion routine for rx urb
612  * @urb: urb for which the completion routine is being called
613  *
614  * Return: none
615  */
616 static void usb_hif_usb_recv_complete(struct urb *urb)
617 {
618 	struct HIF_URB_CONTEXT *urb_context =
619 					(struct HIF_URB_CONTEXT *) urb->context;
620 	QDF_STATUS status = QDF_STATUS_SUCCESS;
621 	qdf_nbuf_t buf = NULL;
622 	struct HIF_USB_PIPE *pipe = urb_context->pipe;
623 	struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device);
624 
625 	HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK",
626 		__func__,
627 		pipe->logical_pipe_num,
628 		urb->status, urb->actual_length,
629 		urb);
630 
631 	/* this urb is not pending anymore */
632 	usb_hif_remove_pending_transfer(urb_context);
633 
634 	do {
635 
636 		if (urb->status != 0) {
637 			status = A_ECOMM;
638 			switch (urb->status) {
639 #ifdef RX_SG_SUPPORT
640 			case -EOVERFLOW:
641 				urb->actual_length = HIF_USB_RX_BUFFER_SIZE;
642 				status = QDF_STATUS_SUCCESS;
643 				break;
644 #endif
645 			case -ECONNRESET:
646 			case -ENOENT:
647 			case -ESHUTDOWN:
648 				/* NOTE: no need to spew these errors when
649 				 * device is removed
650 				 * or urb is killed due to driver shutdown
651 				 */
652 				status = A_ECANCELED;
653 				break;
654 			default:
655 				HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
656 					__func__,
657 					pipe->logical_pipe_num,
658 					pipe->ep_address,
659 					urb->status);
660 				break;
661 			}
662 			break;
663 		}
664 		if (urb->actual_length == 0)
665 			break;
666 		buf = urb_context->buf;
667 		/* we are going to pass it up */
668 		urb_context->buf = NULL;
669 		qdf_nbuf_put_tail(buf, urb->actual_length);
670 		if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
671 			uint8_t *data;
672 			uint32_t len;
673 
674 			qdf_nbuf_peek_header(buf, &data, &len);
675 			debug_dump_bytes(data, len, "hif recv data");
676 		}
677 		/* note: queue implements a lock */
678 		skb_queue_tail(&pipe->io_comp_queue, buf);
679 		HIF_USB_SCHEDULE_WORK(pipe);
680 	} while (false);
681 
682 	usb_hif_cleanup_recv_urb(urb_context);
683 
684 	/* Only re-submit URB when STATUS is success and HIF is not at the
685 	 * suspend state.
686 	 */
687 	if (QDF_IS_STATUS_SUCCESS(status) && !sc->suspend_state) {
688 		if (pipe->urb_cnt >= pipe->urb_cnt_thresh) {
689 			/* our free urbs are piling up, post more transfers */
690 			usb_hif_post_recv_transfers(pipe,
691 						HIF_USB_RX_BUFFER_SIZE);
692 		}
693 	} else {
694 		HIF_ERROR("%s:  pipe: %d, fail to post URB: status(%d) suspend (%d)",
695 				__func__,
696 				pipe->logical_pipe_num,
697 				urb->status,
698 				sc->suspend_state);
699 	}
700 
701 	HIF_DBG("-%s", __func__);
702 }
703 
704 /**
705  * usb_hif_usb_recv_bundle_complete() - completion routine for rx bundling urb
706  * @urb: urb for which the completion routine is being called
707  *
708  * Return: none
709  */
710 static void usb_hif_usb_recv_bundle_complete(struct urb *urb)
711 {
712 	struct HIF_URB_CONTEXT *urb_context =
713 					(struct HIF_URB_CONTEXT *) urb->context;
714 	QDF_STATUS status = QDF_STATUS_SUCCESS;
715 	qdf_nbuf_t buf = NULL;
716 	struct HIF_USB_PIPE *pipe = urb_context->pipe;
717 	uint8_t *netdata, *netdata_new;
718 	uint32_t netlen, netlen_new;
719 	HTC_FRAME_HDR *HtcHdr;
720 	uint16_t payloadLen;
721 	qdf_nbuf_t new_skb = NULL;
722 
723 	HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK",
724 		__func__,
725 		pipe->logical_pipe_num,
726 		urb->status, urb->actual_length,
727 		urb);
728 
729 	/* this urb is not pending anymore */
730 	usb_hif_remove_pending_transfer(urb_context);
731 
732 	do {
733 
734 		if (urb->status != 0) {
735 			status = A_ECOMM;
736 			switch (urb->status) {
737 			case -ECONNRESET:
738 			case -ENOENT:
739 			case -ESHUTDOWN:
740 				/* NOTE: no need to spew these errors when
741 				 * device is removed
742 				 * or urb is killed due to driver shutdown
743 				 */
744 				status = A_ECANCELED;
745 				break;
746 			default:
747 				HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
748 					__func__,
749 					pipe->logical_pipe_num,
750 					pipe->ep_address,
751 					urb->status);
752 				break;
753 			}
754 			break;
755 		}
756 		if (urb->actual_length == 0)
757 			break;
758 		buf = urb_context->buf;
759 		if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
760 			uint8_t *data;
761 			uint32_t len;
762 
763 			qdf_nbuf_peek_header(buf, &data, &len);
764 			debug_dump_bytes(data, len, "hif recv data");
765 		}
766 
767 		qdf_nbuf_peek_header(buf, &netdata, &netlen);
768 		netlen = urb->actual_length;
769 
770 		do {
771 			uint16_t frame_len;
772 
773 			if (IS_FW_CRASH_DUMP(*(uint32_t *) netdata))
774 				frame_len = netlen;
775 			else {
776 				/* Hack into HTC header for bundle processing */
777 				HtcHdr = (HTC_FRAME_HDR *) netdata;
778 				if (HtcHdr->EndpointID >= ENDPOINT_MAX) {
779 					HIF_ERROR("athusb: Rx: invalid EndpointID=%d",
780 						HtcHdr->EndpointID);
781 					break;
782 				}
783 
784 				payloadLen = HtcHdr->PayloadLen;
785 				payloadLen = qdf_le16_to_cpu(payloadLen);
786 
787 				if (payloadLen > HIF_USB_RX_BUFFER_SIZE) {
788 					HIF_ERROR("athusb: payloadLen too long %u",
789 						payloadLen);
790 					break;
791 				}
792 				frame_len = (HTC_HDR_LENGTH + payloadLen);
793 			}
794 
795 			if (netlen < frame_len) {
796 				HIF_ERROR("athusb: subframe length %d not fitted into bundle packet length %d"
797 					, netlen, frame_len);
798 				break;
799 			}
800 
801 			/* allocate a new skb and copy */
802 			new_skb =
803 				qdf_nbuf_alloc(NULL, frame_len, 0, 4, false);
804 			if (new_skb == NULL) {
805 				HIF_ERROR("athusb: allocate skb (len=%u) failed"
806 						, frame_len);
807 				break;
808 			}
809 
810 			qdf_nbuf_peek_header(new_skb, &netdata_new,
811 						&netlen_new);
812 			qdf_mem_copy(netdata_new, netdata, frame_len);
813 			qdf_nbuf_put_tail(new_skb, frame_len);
814 			skb_queue_tail(&pipe->io_comp_queue, new_skb);
815 			new_skb = NULL;
816 			netdata += frame_len;
817 			netlen -= frame_len;
818 		} while (netlen);
819 		HIF_USB_SCHEDULE_WORK(pipe);
820 	} while (false);
821 
822 	if (urb_context->buf == NULL)
823 		HIF_ERROR("athusb: buffer in urb_context is NULL");
824 
825 	/* reset urb_context->buf ==> seems not necessary */
826 	usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context);
827 
828 	if (QDF_IS_STATUS_SUCCESS(status)) {
829 		if (pipe->urb_cnt >= pipe->urb_cnt_thresh) {
830 			/* our free urbs are piling up, post more transfers */
831 			usb_hif_post_recv_bundle_transfers(pipe,
832 					pipe->device->rx_bundle_buf_len);
833 		}
834 	}
835 
836 	HIF_DBG("-%s", __func__);
837 }
838 
839 /**
840  * usb_hif_post_recv_prestart_transfers() - post prestart recv urbs for a pipe
841  * @recv_pipe: rx data pipe
842  * @prestart_urb: number of prestart recv urbs to be posted
843  *
844  * Return: none
845  */
846 static void usb_hif_post_recv_prestart_transfers(struct HIF_USB_PIPE *recv_pipe,
847 						int prestart_urb)
848 {
849 	struct HIF_URB_CONTEXT *urb_context;
850 	uint8_t *data;
851 	uint32_t len;
852 	struct urb *urb;
853 	int i, usb_status, buffer_length = HIF_USB_RX_BUFFER_SIZE;
854 
855 	HIF_TRACE("+%s", __func__);
856 
857 	for (i = 0; i < prestart_urb; i++) {
858 		urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
859 		if (NULL == urb_context)
860 			break;
861 
862 		urb_context->buf =
863 			qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false);
864 		if (NULL == urb_context->buf) {
865 			usb_hif_cleanup_recv_urb(urb_context);
866 			break;
867 		}
868 
869 		qdf_nbuf_peek_header(urb_context->buf, &data, &len);
870 
871 		urb = urb_context->urb;
872 
873 		usb_fill_bulk_urb(urb,
874 				recv_pipe->device->udev,
875 				recv_pipe->usb_pipe_handle,
876 				data,
877 				buffer_length,
878 				usb_hif_usb_recv_prestart_complete,
879 				urb_context);
880 
881 		HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK",
882 			recv_pipe->logical_pipe_num,
883 			recv_pipe->usb_pipe_handle,
884 			recv_pipe->ep_address, buffer_length,
885 			urb_context->buf);
886 
887 		usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
888 
889 		usb_status = usb_submit_urb(urb, GFP_ATOMIC);
890 
891 		if (usb_status) {
892 			HIF_ERROR("athusb : usb bulk recv failed %d",
893 				usb_status);
894 			usb_hif_remove_pending_transfer(urb_context);
895 			usb_hif_cleanup_recv_urb(urb_context);
896 			break;
897 		}
898 		recv_pipe->urb_prestart_cnt++;
899 	}
900 
901 	HIF_TRACE("-%s", __func__);
902 }
903 
904 /**
905  * usb_hif_post_recv_transfers() - post recv urbs for a given pipe
906  * @recv_pipe: recv pipe for which urbs need to be posted
907  * @buffer_length: buffer length of the recv urbs
908  *
909  * Return: none
910  */
911 static void usb_hif_post_recv_transfers(struct HIF_USB_PIPE *recv_pipe,
912 							int buffer_length)
913 {
914 	struct HIF_URB_CONTEXT *urb_context;
915 	uint8_t *data;
916 	uint32_t len;
917 	struct urb *urb;
918 	int usb_status;
919 
920 	while (1) {
921 
922 		urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
923 		if (NULL == urb_context)
924 			break;
925 
926 		urb_context->buf = qdf_nbuf_alloc(NULL, buffer_length, 0,
927 						4, false);
928 		if (NULL == urb_context->buf) {
929 			usb_hif_cleanup_recv_urb(urb_context);
930 			break;
931 		}
932 
933 		qdf_nbuf_peek_header(urb_context->buf, &data, &len);
934 
935 		urb = urb_context->urb;
936 
937 		usb_fill_bulk_urb(urb,
938 				recv_pipe->device->udev,
939 				recv_pipe->usb_pipe_handle,
940 				data,
941 				buffer_length,
942 				usb_hif_usb_recv_complete, urb_context);
943 
944 		HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK",
945 			recv_pipe->logical_pipe_num,
946 			recv_pipe->usb_pipe_handle,
947 			recv_pipe->ep_address, buffer_length,
948 			urb_context->buf);
949 
950 		usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
951 
952 		usb_status = usb_submit_urb(urb, GFP_ATOMIC);
953 
954 		if (usb_status) {
955 			HIF_ERROR("athusb : usb bulk recv failed %d",
956 				usb_status);
957 			usb_hif_remove_pending_transfer(urb_context);
958 			usb_hif_cleanup_recv_urb(urb_context);
959 			break;
960 		}
961 	}
962 
963 }
964 
965 /**
966  * usb_hif_post_recv_bundle_transfers() - post recv urbs for a given pipe
967  * @recv_pipe: recv pipe for which urbs need to be posted
968  * @buffer_length: maximum length of rx bundle
969  *
970  * Return: none
971  */
972 static void usb_hif_post_recv_bundle_transfers(struct HIF_USB_PIPE *recv_pipe,
973 						int buffer_length)
974 {
975 	struct HIF_URB_CONTEXT *urb_context;
976 	uint8_t *data;
977 	uint32_t len;
978 	struct urb *urb;
979 	int usb_status;
980 
981 	while (1) {
982 
983 		urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
984 		if (NULL == urb_context)
985 			break;
986 
987 		if (NULL == urb_context->buf) {
988 			urb_context->buf =
989 			qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false);
990 			if (NULL == urb_context->buf) {
991 				usb_hif_cleanup_recv_urb(urb_context);
992 				break;
993 			}
994 		}
995 
996 		qdf_nbuf_peek_header(urb_context->buf, &data, &len);
997 
998 		urb = urb_context->urb;
999 		usb_fill_bulk_urb(urb,
1000 				recv_pipe->device->udev,
1001 				recv_pipe->usb_pipe_handle,
1002 				data,
1003 				buffer_length,
1004 				usb_hif_usb_recv_bundle_complete,
1005 				urb_context);
1006 
1007 		HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK",
1008 			recv_pipe->logical_pipe_num,
1009 			recv_pipe->usb_pipe_handle,
1010 			recv_pipe->ep_address, buffer_length,
1011 			urb_context->buf);
1012 
1013 		usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
1014 
1015 		usb_status = usb_submit_urb(urb, GFP_ATOMIC);
1016 
1017 		if (usb_status) {
1018 			HIF_ERROR("athusb : usb bulk recv failed %d",
1019 				usb_status);
1020 			usb_hif_remove_pending_transfer(urb_context);
1021 			usb_hif_free_urb_to_pipe(urb_context->pipe,
1022 						urb_context);
1023 			break;
1024 		}
1025 
1026 	}
1027 
1028 }
1029 
1030 /**
1031  * usb_hif_prestart_recv_pipes() - post prestart recv urbs
1032  * @device: HIF device for which prestart recv urbs need to be posted
1033  *
1034  * Return: none
1035  */
1036 void usb_hif_prestart_recv_pipes(struct HIF_DEVICE_USB *device)
1037 {
1038 	struct HIF_USB_PIPE *pipe;
1039 	int prestart_cnt = 8;
1040 
1041 	if (device->rx_ctrl_pipe_supported) {
1042 		pipe = &device->pipes[HIF_RX_CTRL_PIPE];
1043 		prestart_cnt = 4;
1044 		usb_hif_post_recv_prestart_transfers(pipe, prestart_cnt);
1045 	}
1046 	/*
1047 	 * USB driver learn to support bundle or not until the firmware
1048 	 * download and ready. Only allocate some URBs for control message
1049 	 * communication during the initial phase then start the final
1050 	 * working pipe after all information understood.
1051 	 */
1052 	pipe = &device->pipes[HIF_RX_DATA_PIPE];
1053 	usb_hif_post_recv_prestart_transfers(pipe, prestart_cnt);
1054 }
1055 
1056 /**
1057  * usb_hif_start_recv_pipes() - start recv urbs
1058  * @device: HIF device for which recv urbs need to be posted
1059  *
1060  * This function is called after all prestart recv urbs are exhausted
1061  *
1062  * Return: none
1063  */
1064 void usb_hif_start_recv_pipes(struct HIF_DEVICE_USB *device)
1065 {
1066 	struct HIF_USB_PIPE *pipe;
1067 	uint32_t buf_len;
1068 
1069 	HIF_ENTER();
1070 	pipe = &device->pipes[HIF_RX_DATA_PIPE];
1071 	pipe->urb_cnt_thresh = pipe->urb_alloc / 2;
1072 
1073 	HIF_TRACE("Post URBs to RX_DATA_PIPE: %d",
1074 		device->pipes[HIF_RX_DATA_PIPE].urb_cnt);
1075 	if (device->is_bundle_enabled) {
1076 		usb_hif_post_recv_bundle_transfers(pipe,
1077 					pipe->device->rx_bundle_buf_len);
1078 	} else {
1079 		buf_len = HIF_USB_RX_BUFFER_SIZE;
1080 		usb_hif_post_recv_transfers(pipe, buf_len);
1081 	}
1082 
1083 	HIF_DBG("athusb bulk recv len %d", buf_len);
1084 
1085 	if (!hif_usb_disable_rxdata2) {
1086 		HIF_TRACE("Post URBs to RX_DATA2_PIPE: %d",
1087 			device->pipes[HIF_RX_DATA2_PIPE].urb_cnt);
1088 
1089 		pipe = &device->pipes[HIF_RX_DATA2_PIPE];
1090 		pipe->urb_cnt_thresh = pipe->urb_alloc / 2;
1091 		usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE);
1092 	}
1093 
1094 	if (device->rx_ctrl_pipe_supported) {
1095 		HIF_TRACE("Post URBs to RX_CONTROL_PIPE: %d",
1096 			  device->pipes[HIF_RX_CTRL_PIPE].urb_cnt);
1097 
1098 		pipe = &device->pipes[HIF_RX_CTRL_PIPE];
1099 		pipe->urb_cnt_thresh = pipe->urb_alloc / 2;
1100 		usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE);
1101 	}
1102 	HIF_EXIT();
1103 }
1104 
1105 /**
1106  * usb_hif_submit_ctrl_out() - send out a ctrl urb
1107  * @device: HIF device for which urb needs to be posted
1108  * @req: request value for the ctrl message
1109  * @value: USB message value
1110  * @index: USB message index value
1111  * @data: pointer to data containing ctrl message to send
1112  * @size: size of the control message to send
1113  *
1114  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
1115  */
1116 QDF_STATUS usb_hif_submit_ctrl_out(struct HIF_DEVICE_USB *device,
1117 				   uint8_t req, uint16_t value, uint16_t index,
1118 				   void *data, uint32_t size)
1119 {
1120 	int32_t result = 0;
1121 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
1122 	uint8_t *buf = NULL;
1123 
1124 	do {
1125 
1126 		if (size > 0) {
1127 			buf = qdf_mem_malloc(size);
1128 			if (NULL == buf) {
1129 				ret = QDF_STATUS_E_NOMEM;
1130 				break;
1131 			}
1132 			qdf_mem_copy(buf, (uint8_t *) data, size);
1133 		}
1134 
1135 		HIF_DBG("ctrl-out req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d",
1136 				req, value, index, size);
1137 
1138 		result = usb_control_msg(device->udev,
1139 					usb_sndctrlpipe(device->udev, 0),
1140 					req,
1141 					USB_DIR_OUT | USB_TYPE_VENDOR |
1142 					USB_RECIP_DEVICE, value, index, buf,
1143 					size, 2 * HZ);
1144 
1145 		if (result < 0) {
1146 			HIF_ERROR("%s failed,result = %d", __func__, result);
1147 			ret = QDF_STATUS_E_FAILURE;
1148 		}
1149 
1150 	} while (false);
1151 
1152 	if (buf != NULL)
1153 		qdf_mem_free(buf);
1154 
1155 	return ret;
1156 }
1157 
1158 /**
1159  * usb_hif_submit_ctrl_in() - recv a resonse to the ctrl message sent out
1160  * @device: HIF device for which urb needs to be received
1161  * @req: request value for the ctrl message
1162  * @value: USB message value
1163  * @index: USB message index value
1164  * @data: pointer to data containing ctrl message to be received
1165  * @size: size of the control message to be received
1166  *
1167  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
1168  */
1169 QDF_STATUS usb_hif_submit_ctrl_in(struct HIF_DEVICE_USB *device,
1170 				  uint8_t req, uint16_t value, uint16_t index,
1171 				  void *data, uint32_t size)
1172 {
1173 	int32_t result = 0;
1174 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
1175 	uint8_t *buf = NULL;
1176 
1177 	do {
1178 
1179 		if (size > 0) {
1180 			buf = qdf_mem_malloc(size);
1181 			if (NULL == buf) {
1182 				ret = QDF_STATUS_E_NOMEM;
1183 				break;
1184 			}
1185 		}
1186 
1187 		HIF_DBG("ctrl-in req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d",
1188 				 req, value, index, size);
1189 
1190 		result = usb_control_msg(device->udev,
1191 					usb_rcvctrlpipe(device->udev, 0),
1192 					req,
1193 					USB_DIR_IN | USB_TYPE_VENDOR |
1194 					USB_RECIP_DEVICE, value, index, buf,
1195 					size, 2 * HZ);
1196 
1197 		if (result < 0) {
1198 			HIF_ERROR("%s failed, result = %d", __func__, result);
1199 			ret = QDF_STATUS_E_FAILURE;
1200 			break;
1201 		}
1202 
1203 		qdf_mem_copy((uint8_t *) data, buf, size);
1204 
1205 	} while (false);
1206 
1207 	if (buf != NULL)
1208 		qdf_mem_free(buf);
1209 
1210 	return ret;
1211 }
1212 
1213 /**
1214  * usb_hif_io_complete() - transmit call back for tx urb
1215  * @pipe: pointer to struct HIF_USB_PIPE
1216  *
1217  * Return: none
1218  */
1219 static void usb_hif_io_complete(struct HIF_USB_PIPE *pipe)
1220 {
1221 	qdf_nbuf_t buf;
1222 	struct HIF_DEVICE_USB *device;
1223 	HTC_FRAME_HDR *HtcHdr;
1224 	uint8_t *data;
1225 	uint32_t len;
1226 	struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device);
1227 
1228 	device = pipe->device;
1229 	HIF_ENTER();
1230 	while ((buf = skb_dequeue(&pipe->io_comp_queue))) {
1231 		if (pipe->flags & HIF_USB_PIPE_FLAG_TX) {
1232 			HIF_DBG("+athusb xmit callback buf:0x%pK", buf);
1233 			HtcHdr = (HTC_FRAME_HDR *)
1234 					qdf_nbuf_get_frag_vaddr(buf, 0);
1235 
1236 #ifdef ATH_11AC_TXCOMPACT
1237 /* ATH_11AC_TXCOMPACT does not support High Latency mode */
1238 #else
1239 			device->htc_callbacks.txCompletionHandler(device->
1240 								htc_callbacks.
1241 								Context, buf,
1242 								HtcHdr->
1243 								EndpointID, 0);
1244 #endif
1245 			HIF_DBG("-athusb xmit callback");
1246 		} else {
1247 			HIF_DBG("+athusb recv callback buf: 0x%pK", buf);
1248 			qdf_nbuf_peek_header(buf, &data, &len);
1249 
1250 			if (IS_FW_CRASH_DUMP(*((uint32_t *) data))) {
1251 				sc->fw_data = data;
1252 				sc->fw_data_len = len;
1253 				device->htc_callbacks.fwEventHandler(
1254 					device->htc_callbacks.Context,
1255 					QDF_STATUS_E_USB_ERROR);
1256 				qdf_nbuf_free(buf);
1257 			} else {
1258 				device->htc_callbacks.rxCompletionHandler(
1259 				device->htc_callbacks.Context, buf,
1260 				pipe->logical_pipe_num);
1261 			}
1262 			HIF_DBG("-athusb recv callback");
1263 		}
1264 	}
1265 
1266 	HIF_EXIT();
1267 }
1268 
1269 #ifdef HIF_USB_TASKLET
1270 /**
1271  * usb_hif_io_comp_tasklet() - per pipe tasklet routine
1272  * @context: pointer to HIF USB pipe
1273  *
1274  * Return: none
1275  */
1276 void usb_hif_io_comp_tasklet(unsigned long context)
1277 {
1278 	struct HIF_USB_PIPE *pipe = (struct HIF_USB_PIPE *) context;
1279 
1280 	usb_hif_io_complete(pipe);
1281 }
1282 
1283 #else
1284 /**
1285  * usb_hif_io_comp_work() - per pipe work queue
1286  * @work: pointer to struct work_struct
1287  *
1288  * Return: none
1289  */
1290 void usb_hif_io_comp_work(struct work_struct *work)
1291 {
1292 	struct HIF_USB_PIPE *pipe = container_of(work, struct HIF_USB_PIPE,
1293 						 io_complete_work);
1294 
1295 	usb_hif_io_complete(pipe);
1296 }
1297 #endif
1298