xref: /wlan-dirver/qca-wifi-host-cmn/hif/src/usb/hif_usb.c (revision 1b9674e21e24478fba4530f5ae7396b9555e9c6a)
1 /*
2  * Copyright (c) 2013-2018 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 #include <qdf_time.h>
20 #include <qdf_lock.h>
21 #include <qdf_mem.h>
22 #include <qdf_util.h>
23 #include <qdf_defer.h>
24 #include <qdf_atomic.h>
25 #include <qdf_nbuf.h>
26 #include "qdf_net_types.h"
27 #include <hif_usb_internal.h>
28 #include <htc_services.h>
29 #include <hif_debug.h>
30 #define ATH_MODULE_NAME hif
31 #include <a_debug.h>
32 #include "qdf_module.h"
33 #include "hif_usb_internal.h"
34 #include "if_usb.h"
35 #include "usb_api.h"
36 #include "target_type.h"
37 
38 #if defined(WLAN_DEBUG) || defined(DEBUG)
39 static ATH_DEBUG_MASK_DESCRIPTION g_hif_debug_description[] = {
40 	{USB_HIF_DEBUG_CTRL_TRANS, "Control Transfers"},
41 	{USB_HIF_DEBUG_BULK_IN, "BULK In Transfers"},
42 	{USB_HIF_DEBUG_BULK_OUT, "BULK Out Transfers"},
43 	{USB_HIF_DEBUG_DUMP_DATA, "Dump data"},
44 	{USB_HIF_DEBUG_ENUM, "Enumeration"},
45 };
46 
47 ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif,
48 				 "hif",
49 				 "USB Host Interface",
50 				 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_INFO |
51 				 USB_HIF_DEBUG_ENUM,
52 				 ATH_DEBUG_DESCRIPTION_COUNT
53 				 (g_hif_debug_description),
54 				 g_hif_debug_description);
55 
56 #endif
57 
58 #ifdef USB_ISOC_SUPPORT
59 unsigned int hif_usb_isoch_vo = 1;
60 #else
61 unsigned int hif_usb_isoch_vo;
62 #endif
63 unsigned int hif_usb_disable_rxdata2 = 1;
64 
65 /**
66  * usb_hif_usb_transmit_complete() - completion routing for tx urb's
67  * @urb: pointer to urb for which tx completion is called
68  *
69  * Return: none
70  */
71 static void usb_hif_usb_transmit_complete(struct urb *urb)
72 {
73 	struct HIF_URB_CONTEXT *urb_context =
74 		(struct HIF_URB_CONTEXT *)urb->context;
75 	qdf_nbuf_t buf;
76 	struct HIF_USB_PIPE *pipe = urb_context->pipe;
77 	struct hif_usb_send_context *send_context;
78 
79 	HIF_DBG("+%s: pipe: %d, stat:%d, len:%d", __func__,
80 		pipe->logical_pipe_num, urb->status, urb->actual_length);
81 
82 	/* this urb is not pending anymore */
83 	usb_hif_remove_pending_transfer(urb_context);
84 
85 	if (urb->status != 0) {
86 		HIF_ERROR("%s:  pipe: %d, failed:%d",
87 			  __func__, pipe->logical_pipe_num, urb->status);
88 	}
89 
90 	buf = urb_context->buf;
91 	send_context = urb_context->send_context;
92 
93 	if (send_context->new_alloc)
94 		qdf_mem_free(send_context);
95 	else
96 		qdf_nbuf_pull_head(buf, send_context->head_data_len);
97 
98 	urb_context->buf = NULL;
99 	usb_hif_cleanup_transmit_urb(urb_context);
100 
101 	/* note: queue implements a lock */
102 	skb_queue_tail(&pipe->io_comp_queue, buf);
103 	HIF_USB_SCHEDULE_WORK(pipe);
104 
105 	HIF_DBG("-%s", __func__);
106 }
107 
108 /**
109  * hif_send_internal() - HIF internal routine to prepare and submit tx urbs
110  * @hif_usb_device: pointer to HIF_DEVICE_USB structure
111  * @pipe_id: HIF pipe on which data is to be sent
112  * @hdr_buf: any header buf to be prepended, currently ignored
113  * @buf: qdf_nbuf_t containing data to be transmitted
114  * @nbytes: number of bytes to be transmitted
115  *
116  * Return: QDF_STATUS_SUCCESS on success and error QDF status on failure
117  */
118 static QDF_STATUS hif_send_internal(struct HIF_DEVICE_USB *hif_usb_device,
119 				    uint8_t pipe_id,
120 				    qdf_nbuf_t hdr_buf,
121 				    qdf_nbuf_t buf, unsigned int nbytes)
122 {
123 	QDF_STATUS status = QDF_STATUS_SUCCESS;
124 	struct HIF_DEVICE_USB *device = hif_usb_device;
125 	struct HIF_USB_PIPE *pipe = &device->pipes[pipe_id];
126 	struct HIF_URB_CONTEXT *urb_context;
127 	uint8_t *data;
128 	uint32_t len;
129 	struct urb *urb;
130 	int usb_status;
131 	int i;
132 	struct hif_usb_send_context *send_context;
133 	uint8_t frag_count;
134 	uint32_t head_data_len, tmp_frag_count = 0;
135 	unsigned char *data_ptr;
136 
137 	HIF_DBG("+%s pipe : %d, buf:0x%pK nbytes %u",
138 		__func__, pipe_id, buf, nbytes);
139 
140 	frag_count = qdf_nbuf_get_num_frags(buf);
141 	if (frag_count == 1) {
142 		/*
143 		 * | hif_usb_send_context | netbuf->data
144 		 */
145 		head_data_len = sizeof(struct hif_usb_send_context);
146 	} else if ((frag_count - 1) <= QDF_NBUF_CB_TX_MAX_EXTRA_FRAGS) {
147 		/*
148 		 * means have extra fragment buf in skb
149 		 * header data length should be total sending length subtract
150 		 * internal data length of netbuf
151 		 * | hif_usb_send_context | fragments except internal buffer |
152 		 * netbuf->data
153 		 */
154 		head_data_len = sizeof(struct hif_usb_send_context);
155 		while (tmp_frag_count < (frag_count - 1)) {
156 			head_data_len =
157 				head_data_len + qdf_nbuf_get_frag_len(buf,
158 						tmp_frag_count);
159 			tmp_frag_count = tmp_frag_count + 1;
160 		}
161 	} else {
162 		/* Extra fragments overflow */
163 		HIF_ERROR("%s Extra fragments count overflow : %d\n",
164 			  __func__, frag_count);
165 		status = QDF_STATUS_E_RESOURCES;
166 		goto err;
167 	}
168 
169 	/* Check whether head room is enough to save extra head data */
170 	if (head_data_len <= qdf_nbuf_headroom(buf)) {
171 		send_context = (struct hif_usb_send_context *)
172 		    qdf_nbuf_push_head(buf, head_data_len);
173 		send_context->new_alloc = false;
174 	} else {
175 		send_context =
176 		    qdf_mem_malloc(sizeof(struct hif_usb_send_context)
177 				   + head_data_len + nbytes);
178 		if (send_context == NULL) {
179 			HIF_ERROR("%s: qdf_mem_malloc failed", __func__);
180 			status = QDF_STATUS_E_NOMEM;
181 			goto err;
182 		}
183 		send_context->new_alloc = true;
184 	}
185 	send_context->netbuf = buf;
186 	send_context->hif_usb_device = hif_usb_device;
187 	send_context->transfer_id = pipe_id;
188 	send_context->head_data_len = head_data_len;
189 	/*
190 	 * Copy data to head part of netbuf or head of allocated buffer.
191 	 * if buffer is new allocated, the last buffer should be copied also.
192 	 * It assume last fragment is internal buffer of netbuf
193 	 * sometime total length of fragments larger than nbytes
194 	 */
195 	data_ptr = (unsigned char *)send_context +
196 				sizeof(struct hif_usb_send_context);
197 	for (i = 0;
198 	     i < (send_context->new_alloc ? frag_count : frag_count - 1); i++) {
199 		int frag_len = qdf_nbuf_get_frag_len(buf, i);
200 		unsigned char *frag_addr = qdf_nbuf_get_frag_vaddr(buf, i);
201 
202 		qdf_mem_copy(data_ptr, frag_addr, frag_len);
203 		data_ptr += frag_len;
204 	}
205 	/* Reset pData pointer and send out */
206 	data_ptr = (unsigned char *)send_context +
207 				sizeof(struct hif_usb_send_context);
208 
209 	urb_context = usb_hif_alloc_urb_from_pipe(pipe);
210 	if (NULL == urb_context) {
211 		/* TODO : note, it is possible to run out of urbs if 2
212 		 * endpoints map to the same pipe ID
213 		 */
214 		HIF_ERROR("%s pipe:%d no urbs left. URB Cnt : %d",
215 			__func__, pipe_id, pipe->urb_cnt);
216 		status = QDF_STATUS_E_RESOURCES;
217 		goto err;
218 	}
219 	urb_context->send_context = send_context;
220 	urb = urb_context->urb;
221 	urb_context->buf = buf;
222 	data = data_ptr;
223 	len = nbytes;
224 
225 	usb_fill_bulk_urb(urb,
226 			  device->udev,
227 			  pipe->usb_pipe_handle,
228 			  data,
229 			  (len % pipe->max_packet_size) ==
230 			  0 ? (len + 1) : len,
231 			  usb_hif_usb_transmit_complete, urb_context);
232 
233 	if ((len % pipe->max_packet_size) == 0)
234 		/* hit a max packet boundary on this pipe */
235 
236 	HIF_DBG
237 	    ("athusb bulk send submit:%d, 0x%X (ep:0x%2.2X), %d bytes",
238 	     pipe->logical_pipe_num, pipe->usb_pipe_handle,
239 	     pipe->ep_address, nbytes);
240 
241 	usb_hif_enqueue_pending_transfer(pipe, urb_context);
242 	usb_status = usb_submit_urb(urb, GFP_ATOMIC);
243 	if (usb_status) {
244 		if (send_context->new_alloc)
245 			qdf_mem_free(send_context);
246 		else
247 			qdf_nbuf_pull_head(buf, head_data_len);
248 		urb_context->buf = NULL;
249 		HIF_ERROR("athusb : usb bulk transmit failed %d",
250 				usb_status);
251 		usb_hif_remove_pending_transfer(urb_context);
252 		usb_hif_cleanup_transmit_urb(urb_context);
253 		status = QDF_STATUS_E_FAILURE;
254 		goto err;
255 	}
256 
257 err:
258 	if (!QDF_IS_STATUS_SUCCESS(status) &&
259 				(status != QDF_STATUS_E_RESOURCES)) {
260 		HIF_ERROR("athusb send failed %d", status);
261 	}
262 
263 	HIF_DBG("-%s pipe : %d", __func__, pipe_id);
264 
265 	return status;
266 }
267 
268 /**
269  * hif_send_head() - HIF routine exposed to upper layers to send data
270  * @scn: pointer to hif_opaque_softc structure
271  * @pipe_id: HIF pipe on which data is to be sent
272  * @transfer_id: endpoint ID on which data is to be sent
273  * @nbytes: number of bytes to be transmitted
274  * @wbuf: qdf_nbuf_t containing data to be transmitted
275  * @hdr_buf: any header buf to be prepended, currently ignored
276  * @data_attr: data_attr field from cvg_nbuf_cb of wbuf
277  *
278  * Return: QDF_STATUS_SUCCESS on success and error QDF status on failure
279  */
280 QDF_STATUS hif_send_head(struct hif_opaque_softc *scn, uint8_t pipe_id,
281 				uint32_t transfer_id, uint32_t nbytes,
282 				qdf_nbuf_t wbuf, uint32_t data_attr)
283 {
284 	QDF_STATUS status = QDF_STATUS_SUCCESS;
285 	struct HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
286 
287 	HIF_TRACE("+%s", __func__);
288 	status = hif_send_internal(device, pipe_id, NULL, wbuf, nbytes);
289 	HIF_TRACE("-%s", __func__);
290 	return status;
291 }
292 
293 /**
294  * hif_get_free_queue_number() - get # of free TX resources in a given HIF pipe
295  * @scn: pointer to hif_opaque_softc structure
296  * @pipe_id: HIF pipe which is being polled for free resources
297  *
298  * Return: # of free resources in pipe_id
299  */
300 uint16_t hif_get_free_queue_number(struct hif_opaque_softc *scn,
301 				   uint8_t pipe_id)
302 {
303 	struct HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
304 
305 	return device->pipes[pipe_id].urb_cnt;
306 }
307 
308 /**
309  * hif_post_init() - copy HTC callbacks to HIF
310  * @scn: pointer to hif_opaque_softc structure
311  * @target: pointer to HTC_TARGET structure
312  * @callbacks: htc callbacks
313  *
314  * Return: none
315  */
316 void hif_post_init(struct hif_opaque_softc *scn, void *target,
317 		struct hif_msg_callbacks *callbacks)
318 {
319 	struct HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
320 
321 	qdf_mem_copy(&device->htc_callbacks, callbacks,
322 			sizeof(device->htc_callbacks));
323 }
324 
325 /**
326  * hif_detach_htc() - remove HTC callbacks from HIF
327  * @scn: pointer to hif_opaque_softc structure
328  *
329  * Return: none
330  */
331 void hif_detach_htc(struct hif_opaque_softc *scn)
332 {
333 	struct HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
334 
335 	usb_hif_flush_all(device);
336 	qdf_mem_zero(&device->htc_callbacks, sizeof(device->htc_callbacks));
337 }
338 
339 /**
340  * hif_usb_device_deinit() - de- init  HIF_DEVICE_USB, cleanup pipe resources
341  * @sc: pointer to hif_usb_softc structure
342  *
343  * Return: None
344  */
345 void hif_usb_device_deinit(struct hif_usb_softc *sc)
346 {
347 	struct HIF_DEVICE_USB *device = &sc->hif_hdl;
348 
349 	HIF_TRACE("+%s", __func__);
350 
351 	usb_hif_cleanup_pipe_resources(device);
352 
353 	usb_set_intfdata(device->interface, NULL);
354 
355 	if (device->diag_cmd_buffer != NULL)
356 		qdf_mem_free(device->diag_cmd_buffer);
357 
358 	if (device->diag_resp_buffer != NULL)
359 		qdf_mem_free(device->diag_resp_buffer);
360 
361 	HIF_TRACE("-%s", __func__);
362 }
363 
364 /**
365  * hif_usb_device_init() - init  HIF_DEVICE_USB, setup pipe resources
366  * @sc: pointer to hif_usb_softc structure
367  *
368  * Return: QDF_STATUS_SUCCESS on success or a QDF error
369  */
370 QDF_STATUS hif_usb_device_init(struct hif_usb_softc *sc)
371 {
372 	int i;
373 	struct HIF_DEVICE_USB *device = &sc->hif_hdl;
374 	struct usb_interface *interface = sc->interface;
375 	struct usb_device *dev = interface_to_usbdev(interface);
376 	QDF_STATUS status = QDF_STATUS_SUCCESS;
377 	struct HIF_USB_PIPE *pipe;
378 
379 	HIF_TRACE("+%s", __func__);
380 
381 	do {
382 
383 		usb_set_intfdata(interface, device);
384 		qdf_spinlock_create(&(device->cs_lock));
385 		qdf_spinlock_create(&(device->rx_lock));
386 		qdf_spinlock_create(&(device->tx_lock));
387 		device->udev = dev;
388 		device->interface = interface;
389 
390 		HIF_ERROR("%s device %pK device->udev %pK device->interface %pK",
391 			__func__,
392 			device,
393 			device->udev,
394 			device->interface);
395 
396 		for (i = 0; i < HIF_USB_PIPE_MAX; i++) {
397 			pipe = &device->pipes[i];
398 
399 			HIF_USB_INIT_WORK(pipe);
400 			skb_queue_head_init(&pipe->io_comp_queue);
401 		}
402 
403 		device->diag_cmd_buffer =
404 			qdf_mem_malloc(USB_CTRL_MAX_DIAG_CMD_SIZE);
405 		if (NULL == device->diag_cmd_buffer) {
406 			status = QDF_STATUS_E_NOMEM;
407 			break;
408 		}
409 		device->diag_resp_buffer =
410 			qdf_mem_malloc(USB_CTRL_MAX_DIAG_RESP_SIZE);
411 		if (NULL == device->diag_resp_buffer) {
412 			status = QDF_STATUS_E_NOMEM;
413 			break;
414 		}
415 
416 		status = usb_hif_setup_pipe_resources(device);
417 
418 	} while (false);
419 
420 	if (hif_is_supported_rx_ctrl_pipe(HIF_GET_SOFTC(sc)))
421 		device->rx_ctrl_pipe_supported = 1;
422 
423 	if (status != QDF_STATUS_SUCCESS)
424 		HIF_ERROR("%s: abnormal condition", __func__);
425 
426 	HIF_TRACE("+%s", __func__);
427 	return status;
428 }
429 
430 /**
431  * hif_start() - Enable HIF TX and RX
432  * @scn: pointer to hif_opaque_softc structure
433  *
434  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
435  */
436 QDF_STATUS hif_start(struct hif_opaque_softc *scn)
437 {
438 	struct HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
439 	int i;
440 
441 	HIF_TRACE("+%s", __func__);
442 	usb_hif_prestart_recv_pipes(device);
443 
444 	/* set the TX resource avail threshold for each TX pipe */
445 	for (i = HIF_TX_CTRL_PIPE; i <= HIF_TX_DATA_HP_PIPE; i++) {
446 		device->pipes[i].urb_cnt_thresh =
447 		    device->pipes[i].urb_alloc / 2;
448 	}
449 
450 	HIF_TRACE("-%s", __func__);
451 	return QDF_STATUS_SUCCESS;
452 }
453 
454 /**
455  * hif_usb_stop_device() - Stop/flush all HIF communication
456  * @scn: pointer to hif_opaque_softc structure
457  *
458  * Return: none
459  */
460 void hif_usb_stop_device(struct hif_softc *hif_sc)
461 {
462 	struct HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(hif_sc);
463 
464 	HIF_TRACE("+%s", __func__);
465 
466 	usb_hif_flush_all(device);
467 
468 	HIF_TRACE("-%s", __func__);
469 }
470 
471 /**
472  * hif_get_default_pipe() - get default pipes for HIF TX/RX
473  * @scn: pointer to hif_opaque_softc structure
474  * @ul_pipe: pointer to TX pipe
475  * @ul_pipe: pointer to TX pipe
476  *
477  * Return: none
478  */
479 void hif_get_default_pipe(struct hif_opaque_softc *scn, uint8_t *ul_pipe,
480 			  uint8_t *dl_pipe)
481 {
482 	*ul_pipe = HIF_TX_CTRL_PIPE;
483 	*dl_pipe = HIF_RX_CTRL_PIPE;
484 }
485 
486 #if defined(USB_MULTI_IN_TEST) || defined(USB_ISOC_TEST)
487 /**
488  * hif_map_service_to_pipe() - maps ul/dl pipe to service id.
489  * @scn: HIF context
490  * @svc_id: sevice index
491  * @ul_pipe: pointer to uplink pipe id
492  * @dl_pipe: pointer to down-linklink pipe id
493  * @ul_is_polled: if ul is polling based
494  * @ul_is_polled: if dl is polling based
495  *
496  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
497  */
498 int hif_map_service_to_pipe(struct hif_opaque_softc *scn, uint16_t svc_id,
499 			    uint8_t *ul_pipe, uint8_t *dl_pipe,
500 			    int *ul_is_polled, int *dl_is_polled)
501 {
502 	QDF_STATUS status = QDF_STATUS_SUCCESS;
503 
504 	switch (svc_id) {
505 	case HTC_CTRL_RSVD_SVC:
506 	case WMI_CONTROL_SVC:
507 	case HTC_RAW_STREAMS_SVC:
508 		*ul_pipe = HIF_TX_CTRL_PIPE;
509 		*dl_pipe = HIF_RX_DATA_PIPE;
510 		break;
511 	case WMI_DATA_BE_SVC:
512 		*ul_pipe = HIF_TX_DATA_LP_PIPE;
513 		*dl_pipe = HIF_RX_DATA_PIPE;
514 		break;
515 	case WMI_DATA_BK_SVC:
516 		*ul_pipe = HIF_TX_DATA_MP_PIPE;
517 		*dl_pipe = HIF_RX_DATA2_PIPE;
518 		break;
519 	case WMI_DATA_VI_SVC:
520 		*ul_pipe = HIF_TX_DATA_HP_PIPE;
521 		*dl_pipe = HIF_RX_DATA_PIPE;
522 		break;
523 	case WMI_DATA_VO_SVC:
524 		*ul_pipe = HIF_TX_DATA_LP_PIPE;
525 		*dl_pipe = HIF_RX_DATA_PIPE;
526 		break;
527 	default:
528 		status = QDF_STATUS_E_FAILURE;
529 		break;
530 	}
531 
532 	return status;
533 }
534 #else
535 
536 #ifdef QCA_TX_HTT2_SUPPORT
537 #define USB_TX_CHECK_HTT2_SUPPORT 1
538 #else
539 #define USB_TX_CHECK_HTT2_SUPPORT 0
540 #endif
541 
542 /**
543  * hif_map_service_to_pipe() - maps ul/dl pipe to service id.
544  * @scn: HIF context
545  * @svc_id: sevice index
546  * @ul_pipe: pointer to uplink pipe id
547  * @dl_pipe: pointer to down-linklink pipe id
548  * @ul_is_polled: if ul is polling based
549  * @ul_is_polled: if dl is polling based
550  *
551  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
552  */
553 int hif_map_service_to_pipe(struct hif_opaque_softc *scn, uint16_t svc_id,
554 			    uint8_t *ul_pipe, uint8_t *dl_pipe,
555 			    int *ul_is_polled, int *dl_is_polled)
556 {
557 	QDF_STATUS status = QDF_STATUS_SUCCESS;
558 	struct HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
559 
560 	switch (svc_id) {
561 	case HTC_CTRL_RSVD_SVC:
562 	case WMI_CONTROL_SVC:
563 		*ul_pipe = HIF_TX_CTRL_PIPE;
564 		if (device->rx_ctrl_pipe_supported)
565 			*dl_pipe = HIF_RX_CTRL_PIPE;
566 		else
567 			*dl_pipe = HIF_RX_DATA_PIPE;
568 		break;
569 	case WMI_DATA_BE_SVC:
570 	case WMI_DATA_BK_SVC:
571 		*ul_pipe = HIF_TX_DATA_LP_PIPE;
572 		if (hif_usb_disable_rxdata2)
573 			*dl_pipe = HIF_RX_DATA_PIPE;
574 		else
575 			*dl_pipe = HIF_RX_DATA2_PIPE;
576 		break;
577 	case WMI_DATA_VI_SVC:
578 		*ul_pipe = HIF_TX_DATA_MP_PIPE;
579 		if (hif_usb_disable_rxdata2)
580 			*dl_pipe = HIF_RX_DATA_PIPE;
581 		else
582 			*dl_pipe = HIF_RX_DATA2_PIPE;
583 		break;
584 	case WMI_DATA_VO_SVC:
585 		*ul_pipe = HIF_TX_DATA_HP_PIPE;
586 		if (hif_usb_disable_rxdata2)
587 			*dl_pipe = HIF_RX_DATA_PIPE;
588 		else
589 			*dl_pipe = HIF_RX_DATA2_PIPE;
590 		break;
591 	case HTC_RAW_STREAMS_SVC:
592 		*ul_pipe = HIF_TX_CTRL_PIPE;
593 		*dl_pipe = HIF_RX_DATA_PIPE;
594 		break;
595 	case HTT_DATA_MSG_SVC:
596 		*ul_pipe = HIF_TX_DATA_LP_PIPE;
597 		if (hif_usb_disable_rxdata2)
598 			*dl_pipe = HIF_RX_DATA_PIPE;
599 		else
600 			*dl_pipe = HIF_RX_DATA2_PIPE;
601 		break;
602 	case HTT_DATA2_MSG_SVC:
603 		if (USB_TX_CHECK_HTT2_SUPPORT) {
604 			*ul_pipe = HIF_TX_DATA_HP_PIPE;
605 			if (hif_usb_disable_rxdata2)
606 				*dl_pipe = HIF_RX_DATA_PIPE;
607 			else
608 				*dl_pipe = HIF_RX_DATA2_PIPE;
609 			}
610 		break;
611 	default:
612 		status = QDF_STATUS_E_FAILURE;
613 		break;
614 	}
615 
616 	return status;
617 }
618 #endif
619 
620 /**
621  * hif_ctrl_msg_exchange() - send usb ctrl message and receive response
622  * @macp: pointer to HIF_DEVICE_USB
623  * @send_req_val: USB send message request value
624  * @send_msg: pointer to data to send
625  * @len: length in bytes of the data to send
626  * @response_req_val: USB response message request value
627  * @response_msg: pointer to response msg
628  * @response_len: length of the response message
629  *
630  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
631  */
632 static QDF_STATUS hif_ctrl_msg_exchange(struct HIF_DEVICE_USB *macp,
633 					uint8_t send_req_val,
634 					uint8_t *send_msg,
635 					uint32_t len,
636 					uint8_t response_req_val,
637 					uint8_t *response_msg,
638 					uint32_t *response_len)
639 {
640 	QDF_STATUS status;
641 
642 	do {
643 
644 		/* send command */
645 		status = usb_hif_submit_ctrl_out(macp, send_req_val, 0, 0,
646 						 send_msg, len);
647 
648 		if (!QDF_IS_STATUS_SUCCESS(status))
649 			break;
650 
651 		if (NULL == response_msg) {
652 			/* no expected response */
653 			break;
654 		}
655 
656 		/* get response */
657 		status = usb_hif_submit_ctrl_in(macp, response_req_val, 0, 0,
658 						response_msg, *response_len);
659 
660 		if (!QDF_IS_STATUS_SUCCESS(status))
661 			break;
662 
663 	} while (false);
664 
665 	return status;
666 }
667 
668 #ifdef WLAN_FEATURE_BMI
669 /**
670  * hif_exchange_bmi_msg() - send/recev ctrl message of type BMI_CMD/BMI_RESP
671  * @scn: pointer to hif_opaque_softc
672  * @bmi_request: pointer to data to send
673  * @request_length: length in bytes of the data to send
674  * @bmi_response: pointer to response msg
675  * @bmi_response_length: length of the response message
676  * @timeout_ms: timeout to wait for response (ignored in current implementation)
677  *
678  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
679  */
680 
681 QDF_STATUS hif_exchange_bmi_msg(struct hif_opaque_softc *scn,
682 				qdf_dma_addr_t cmd, qdf_dma_addr_t rsp,
683 				uint8_t *bmi_request,
684 				uint32_t request_length,
685 				uint8_t *bmi_response,
686 				uint32_t *bmi_response_lengthp,
687 				uint32_t timeout_ms)
688 {
689 	struct HIF_DEVICE_USB *macp = HIF_GET_USB_DEVICE(scn);
690 
691 	return hif_ctrl_msg_exchange(macp,
692 				USB_CONTROL_REQ_SEND_BMI_CMD,
693 				bmi_request,
694 				request_length,
695 				USB_CONTROL_REQ_RECV_BMI_RESP,
696 				bmi_response, bmi_response_lengthp);
697 }
698 #endif /* WLAN_FEATURE_BMI */
699 
700 /**
701  * hif_diag_read_access() - Read data from target memory or register
702  * @scn: pointer to hif_opaque_softc
703  * @address: register address to read from
704  * @data: pointer to buffer to store the value read from the register
705  *
706  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
707  */
708 QDF_STATUS hif_diag_read_access(struct hif_opaque_softc *scn, uint32_t address,
709 					uint32_t *data)
710 {
711 	struct HIF_DEVICE_USB *macp = HIF_GET_USB_DEVICE(scn);
712 	QDF_STATUS status;
713 	USB_CTRL_DIAG_CMD_READ *cmd;
714 	uint32_t respLength;
715 
716 	cmd = (USB_CTRL_DIAG_CMD_READ *) macp->diag_cmd_buffer;
717 
718 	qdf_mem_zero(cmd, sizeof(*cmd));
719 	cmd->Cmd = USB_CTRL_DIAG_CC_READ;
720 	cmd->Address = address;
721 	respLength = sizeof(USB_CTRL_DIAG_RESP_READ);
722 
723 	status = hif_ctrl_msg_exchange(macp,
724 				USB_CONTROL_REQ_DIAG_CMD,
725 				(uint8_t *) cmd,
726 				sizeof(*cmd),
727 				USB_CONTROL_REQ_DIAG_RESP,
728 				macp->diag_resp_buffer, &respLength);
729 
730 	if (QDF_IS_STATUS_SUCCESS(status)) {
731 		USB_CTRL_DIAG_RESP_READ *pResp =
732 			(USB_CTRL_DIAG_RESP_READ *) macp->diag_resp_buffer;
733 		*data = pResp->ReadValue;
734 		status = QDF_STATUS_SUCCESS;
735 	} else {
736 		status = QDF_STATUS_E_FAILURE;
737 	}
738 
739 	return status;
740 }
741 
742 /**
743  * hif_diag_write_access() - write data to target memory or register
744  * @scn: pointer to hif_opaque_softc
745  * @address: register address to write to
746  * @data: value to be written to the address
747  *
748  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
749  */
750 QDF_STATUS hif_diag_write_access(struct hif_opaque_softc *scn,
751 					uint32_t address,
752 					uint32_t data)
753 {
754 	struct HIF_DEVICE_USB *macp = HIF_GET_USB_DEVICE(scn);
755 	USB_CTRL_DIAG_CMD_WRITE *cmd;
756 
757 	cmd = (USB_CTRL_DIAG_CMD_WRITE *) macp->diag_cmd_buffer;
758 
759 	qdf_mem_zero(cmd, sizeof(*cmd));
760 	cmd->Cmd = USB_CTRL_DIAG_CC_WRITE;
761 	cmd->Address = address;
762 	cmd->Value = data;
763 
764 	return hif_ctrl_msg_exchange(macp,
765 				USB_CONTROL_REQ_DIAG_CMD,
766 				(uint8_t *) cmd,
767 				sizeof(*cmd), 0, NULL, 0);
768 }
769 
770 /**
771  * hif_dump_info() - dump info about all HIF pipes and endpoints
772  * @scn: pointer to hif_opaque_softc
773  *
774  * Return: none
775  */
776 void hif_dump_info(struct hif_opaque_softc *scn)
777 {
778 	struct HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
779 	struct HIF_USB_PIPE *pipe = NULL;
780 	struct usb_host_interface *iface_desc = NULL;
781 	struct usb_endpoint_descriptor *ep_desc;
782 	uint8_t i = 0;
783 
784 	for (i = 0; i < HIF_USB_PIPE_MAX; i++) {
785 		pipe = &device->pipes[i];
786 		HIF_ERROR("PipeIndex : %d URB Cnt : %d PipeHandle : %x",
787 			i, pipe->urb_cnt,
788 			pipe->usb_pipe_handle);
789 		if (usb_pipeisoc(pipe->usb_pipe_handle))
790 			HIF_INFO("Pipe Type ISOC");
791 		else if (usb_pipebulk(pipe->usb_pipe_handle))
792 			HIF_INFO("Pipe Type BULK");
793 		else if (usb_pipeint(pipe->usb_pipe_handle))
794 			HIF_INFO("Pipe Type INT");
795 		else if (usb_pipecontrol(pipe->usb_pipe_handle))
796 			HIF_INFO("Pipe Type control");
797 	}
798 
799 	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
800 		ep_desc = &iface_desc->endpoint[i].desc;
801 		if (ep_desc) {
802 			HIF_INFO(
803 				"ep_desc : %pK Index : %d: DescType : %d Addr : %d Maxp : %d Atrrib : %d",
804 				ep_desc, i, ep_desc->bDescriptorType,
805 				ep_desc->bEndpointAddress,
806 				ep_desc->wMaxPacketSize,
807 				ep_desc->bmAttributes);
808 			if ((ep_desc) && (usb_endpoint_type(ep_desc) ==
809 						USB_ENDPOINT_XFER_ISOC)) {
810 				HIF_INFO("ISOC EP Detected");
811 			}
812 		}
813 	}
814 
815 }
816 
817 /**
818  * hif_flush_surprise_remove() - Cleanup residual buffers for device shutdown
819  * @scn: HIF context
820  *
821  * Not applicable to USB bus
822  *
823  * Return: none
824  */
825 void hif_flush_surprise_remove(struct hif_opaque_softc *scn)
826 {
827 /* TO DO... */
828 }
829 
830 /**
831  * hif_diag_read_mem() -read nbytes of data from target memory or register
832  * @scn: pointer to hif_opaque_softc
833  * @address: register address to read from
834  * @data: buffer to store the value read
835  * @nbytes: number of bytes to be read from 'address'
836  *
837  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
838  */
839 QDF_STATUS hif_diag_read_mem(struct hif_opaque_softc *scn,
840 					 uint32_t address, uint8_t *data,
841 					 int nbytes)
842 {
843 	QDF_STATUS status = QDF_STATUS_SUCCESS;
844 
845 	HIF_TRACE("+%s", __func__);
846 
847 	if ((address & 0x3) || ((uintptr_t)data & 0x3))
848 		return QDF_STATUS_E_IO;
849 
850 	while ((nbytes >= 4) &&
851 		QDF_IS_STATUS_SUCCESS(status =
852 					hif_diag_read_access(scn,
853 							address,
854 							(uint32_t *)data))) {
855 
856 		nbytes -= sizeof(uint32_t);
857 		address += sizeof(uint32_t);
858 		data += sizeof(uint32_t);
859 
860 	}
861 	HIF_TRACE("-%s", __func__);
862 	return status;
863 }
864 qdf_export_symbol(hif_diag_read_mem);
865 
866 /**
867  * hif_diag_write_mem() -write  nbytes of data to target memory or register
868  * @scn: pointer to hif_opaque_softc
869  * @address: register address to write to
870  * @data: buffer containing data to be written
871  * @nbytes: number of bytes to be written
872  *
873  * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
874  */
875 QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *scn,
876 					   uint32_t address,
877 					   uint8_t *data, int nbytes)
878 {
879 	QDF_STATUS status = QDF_STATUS_SUCCESS;
880 
881 	HIF_TRACE("+%s", __func__);
882 	if ((address & 0x3) || ((uintptr_t)data & 0x3))
883 		return QDF_STATUS_E_IO;
884 
885 	while (nbytes >= 4 &&
886 		QDF_IS_STATUS_SUCCESS(status =
887 					hif_diag_write_access(scn,
888 						address,
889 						*((uint32_t *)data)))) {
890 
891 		nbytes -= sizeof(uint32_t);
892 		address += sizeof(uint32_t);
893 		data += sizeof(uint32_t);
894 
895 	}
896 	HIF_TRACE("-%s", __func__);
897 	return status;
898 }
899 
900 void hif_send_complete_check(struct hif_opaque_softc *scn,
901 						uint8_t PipeID, int force)
902 {
903 	/* NO-OP*/
904 }
905 
906 /* diagnostic command defnitions */
907 #define USB_CTRL_DIAG_CC_READ       0
908 #define USB_CTRL_DIAG_CC_WRITE      1
909 #define USB_CTRL_DIAG_CC_WARM_RESET 2
910 
911 void hif_suspend_wow(struct hif_opaque_softc *scn)
912 {
913 	HIF_INFO("HIFsuspendwow - TODO");
914 }
915 
916 /**
917  * hif_usb_set_bundle_mode() - enable bundling and set default rx bundle cnt
918  * @scn: pointer to hif_opaque_softc structure
919  * @enabled: flag to enable/disable bundling
920  * @rx_bundle_cnt: bundle count to be used for RX
921  *
922  * Return: none
923  */
924 void hif_usb_set_bundle_mode(struct hif_softc *scn,
925 					bool enabled, int rx_bundle_cnt)
926 {
927 	struct HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
928 
929 	device->is_bundle_enabled = enabled;
930 	device->rx_bundle_cnt = rx_bundle_cnt;
931 	if (device->is_bundle_enabled && (device->rx_bundle_cnt == 0))
932 		device->rx_bundle_cnt = 1;
933 
934 	device->rx_bundle_buf_len = device->rx_bundle_cnt *
935 					HIF_USB_RX_BUNDLE_ONE_PKT_SIZE;
936 
937 	HIF_DBG("athusb bundle %s cnt %d", enabled ? "enabled" : "disabled",
938 			rx_bundle_cnt);
939 }
940 
941 /**
942  * hif_is_supported_rx_ctrl_pipe() - return true if device supports exclusive
943  * control pipe in the RX direction.
944  * @scn: hif context
945  *
946  * Return: true if device supports RX control pipe.
947  */
948 bool hif_is_supported_rx_ctrl_pipe(struct hif_softc *scn)
949 {
950 	struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(scn);
951 	struct hif_target_info *tgt_info = hif_get_target_info_handle(hif_hdl);
952 
953 	switch (tgt_info->target_type) {
954 	case TARGET_TYPE_QCN7605:
955 		return true;
956 	default:
957 		return false;
958 	}
959 }
960