Parcourir la source

qcacmn: Add USB bus support (HIF USB)

Add HIF changes for USB bus support.

Change-Id: I06609db68d537ba7c7716f2926589e0dbe738e58
CRs-Fixed: 1023663
Mohit Khanna il y a 9 ans
Parent
commit
bda5d43e70

+ 918 - 0
hif/src/usb/hif_usb.c

@@ -0,0 +1,918 @@
+/*
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+#include <qdf_time.h>
+#include <qdf_lock.h>
+#include <qdf_mem.h>
+#include <qdf_util.h>
+#include <qdf_defer.h>
+#include <qdf_atomic.h>
+#include <qdf_nbuf.h>
+#include "qdf_net_types.h"
+#include <hif_usb_internal.h>
+#include <htc_services.h>
+#include <hif_debug.h>
+#define ATH_MODULE_NAME hif
+#include <a_debug.h>
+
+#ifdef DEBUG
+static ATH_DEBUG_MASK_DESCRIPTION g_hif_debug_description[] = {
+	{USB_HIF_DEBUG_CTRL_TRANS, "Control Transfers"},
+	{USB_HIF_DEBUG_BULK_IN, "BULK In Transfers"},
+	{USB_HIF_DEBUG_BULK_OUT, "BULK Out Transfers"},
+	{USB_HIF_DEBUG_DUMP_DATA, "Dump data"},
+	{USB_HIF_DEBUG_ENUM, "Enumeration"},
+};
+
+ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif,
+				 "hif",
+				 "USB Host Interface",
+				 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_INFO |
+				 USB_HIF_DEBUG_ENUM,
+				 ATH_DEBUG_DESCRIPTION_COUNT
+				 (g_hif_debug_description),
+				 g_hif_debug_description);
+
+#endif
+
+#ifdef USB_ISOC_SUPPORT
+unsigned int hif_usb_isoch_vo = 1;
+#else
+unsigned int hif_usb_isoch_vo;
+#endif
+unsigned int hif_usb_disable_rxdata2 = 1;
+
+/**
+ * usb_hif_usb_transmit_complete() - completion routing for tx urb's
+ * @urb: pointer to urb for which tx completion is called
+ *
+ * Return: none
+ */
+static void usb_hif_usb_transmit_complete(struct urb *urb)
+{
+	HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context;
+	qdf_nbuf_t buf;
+	HIF_USB_PIPE *pipe = urb_context->pipe;
+	struct hif_usb_send_context *send_context;
+
+	HIF_DBG("+%s: pipe: %d, stat:%d, len:%d", __func__,
+		pipe->logical_pipe_num, urb->status, urb->actual_length);
+
+	/* this urb is not pending anymore */
+	usb_hif_remove_pending_transfer(urb_context);
+
+	if (urb->status != 0) {
+		HIF_ERROR("%s:  pipe: %d, failed:%d",
+			  __func__, pipe->logical_pipe_num, urb->status);
+	}
+
+	buf = urb_context->buf;
+	send_context = urb_context->send_context;
+
+	if (send_context->new_alloc)
+		qdf_mem_free(send_context);
+	else
+		qdf_nbuf_pull_head(buf, send_context->head_data_len);
+
+	urb_context->buf = NULL;
+	usb_hif_cleanup_transmit_urb(urb_context);
+
+	/* note: queue implements a lock */
+	skb_queue_tail(&pipe->io_comp_queue, buf);
+	HIF_USB_SCHEDULE_WORK(pipe)
+
+	HIF_DBG("-%s", __func__);
+}
+
+/**
+ * hif_send_internal() - HIF internal routine to prepare and submit tx urbs
+ * @hif_usb_device: pointer to HIF_DEVICE_USB structure
+ * @pipe_id: HIF pipe on which data is to be sent
+ * @hdr_buf: any header buf to be prepended, currently ignored
+ * @buf: qdf_nbuf_t containing data to be transmitted
+ * @nbytes: number of bytes to be transmitted
+ *
+ * Return: QDF_STATUS_SUCCESS on success and error QDF status on failure
+ */
+static QDF_STATUS hif_send_internal(HIF_DEVICE_USB *hif_usb_device,
+				    uint8_t pipe_id,
+				    qdf_nbuf_t hdr_buf,
+				    qdf_nbuf_t buf, unsigned int nbytes)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	HIF_DEVICE_USB *device = hif_usb_device;
+	HIF_USB_PIPE *pipe = &device->pipes[pipe_id];
+	HIF_URB_CONTEXT *urb_context;
+	uint8_t *data;
+	uint32_t len;
+	struct urb *urb;
+	int usb_status;
+	int i;
+	struct hif_usb_send_context *send_context;
+	int frag_count = 0, head_data_len, tmp_frag_count = 0;
+	unsigned char *data_ptr;
+
+	HIF_DBG("+%s pipe : %d, buf:0x%p nbytes %u",
+		__func__, pipe_id, buf, nbytes);
+
+	frag_count = qdf_nbuf_get_num_frags(buf);
+	if (frag_count > 1) {	/* means have extra fragment buf in skb */
+		/* header data length should be total sending length substract
+		 * internal data length of netbuf
+		 * | hif_usb_send_context | fragments except internal buffer |
+		 * netbuf->data
+		 */
+		head_data_len = sizeof(struct hif_usb_send_context);
+		while (tmp_frag_count < (frag_count - 1)) {
+			head_data_len =
+			    head_data_len +
+			    qdf_nbuf_get_frag_len(buf, tmp_frag_count);
+			tmp_frag_count = tmp_frag_count + 1;
+		}
+	} else {
+		/*
+		 * | hif_usb_send_context | netbuf->data
+		 */
+		head_data_len = sizeof(struct hif_usb_send_context);
+	}
+
+	/* Check whether head room is enough to save extra head data */
+	if (head_data_len <= qdf_nbuf_headroom(buf)) {
+		send_context = (struct hif_usb_send_context *)
+		    qdf_nbuf_push_head(buf, head_data_len);
+		send_context->new_alloc = false;
+	} else {
+		send_context =
+		    qdf_mem_malloc(sizeof(struct hif_usb_send_context)
+				   + head_data_len + nbytes);
+		if (send_context == NULL) {
+			HIF_ERROR("%s: qdf_mem_malloc failed", __func__);
+			status = QDF_STATUS_E_NOMEM;
+			goto err;
+		}
+		send_context->new_alloc = true;
+	}
+	send_context->netbuf = buf;
+	send_context->hif_usb_device = hif_usb_device;
+	send_context->transfer_id = pipe_id;
+	send_context->head_data_len = head_data_len;
+	/*
+	 * Copy data to head part of netbuf or head of allocated buffer.
+	 * if buffer is new allocated, the last buffer should be copied also.
+	 * It assume last fragment is internal buffer of netbuf
+	 * sometime total length of fragments larger than nbytes
+	 */
+	data_ptr = (unsigned char *)send_context +
+				sizeof(struct hif_usb_send_context);
+	for (i = 0;
+	     i < (send_context->new_alloc ? frag_count : frag_count - 1); i++) {
+		int frag_len = qdf_nbuf_get_frag_len(buf, i);
+		unsigned char *frag_addr = qdf_nbuf_get_frag_vaddr(buf, i);
+		qdf_mem_copy(data_ptr, frag_addr, frag_len);
+		data_ptr += frag_len;
+	}
+	/* Reset pData pointer and send out */
+	data_ptr = (unsigned char *)send_context +
+				sizeof(struct hif_usb_send_context);
+
+	urb_context = usb_hif_alloc_urb_from_pipe(pipe);
+	if (NULL == urb_context) {
+		/* TODO : note, it is possible to run out of urbs if 2
+		 * endpoints map to the same pipe ID
+		 */
+		HIF_ERROR("%s pipe:%d no urbs left. URB Cnt : %d",
+			__func__, pipe_id, pipe->urb_cnt);
+		status = QDF_STATUS_E_RESOURCES;
+		goto err;
+	}
+	urb_context->send_context = send_context;
+	urb = urb_context->urb;
+	urb_context->buf = buf;
+	data = data_ptr;
+	len = nbytes;
+
+	usb_fill_bulk_urb(urb,
+			  device->udev,
+			  pipe->usb_pipe_handle,
+			  data,
+			  (len % pipe->max_packet_size) ==
+			  0 ? (len + 1) : len,
+			  usb_hif_usb_transmit_complete, urb_context);
+
+	if ((len % pipe->max_packet_size) == 0)
+		/* hit a max packet boundary on this pipe */
+
+	HIF_DBG
+	    ("athusb bulk send submit:%d, 0x%X (ep:0x%2.2X), %d bytes",
+	     pipe->logical_pipe_num, pipe->usb_pipe_handle,
+	     pipe->ep_address, nbytes);
+
+	usb_hif_enqueue_pending_transfer(pipe, urb_context);
+	usb_status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (usb_status) {
+		if (send_context->new_alloc)
+			qdf_mem_free(send_context);
+		else
+			qdf_nbuf_pull_head(buf, head_data_len);
+		urb_context->buf = NULL;
+		HIF_ERROR("athusb : usb bulk transmit failed %d",
+				usb_status);
+		usb_hif_remove_pending_transfer(urb_context);
+		usb_hif_cleanup_transmit_urb(urb_context);
+		status = QDF_STATUS_E_FAILURE;
+		goto err;
+	}
+
+err:
+	if (!QDF_IS_STATUS_SUCCESS(status) &&
+				(status != QDF_STATUS_E_RESOURCES)) {
+		HIF_ERROR("athusb send failed %d", status);
+	}
+
+	HIF_DBG("-%s pipe : %d", __func__, pipe_id);
+
+	return status;
+}
+
+/**
+ * hif_send_head() - HIF routine exposed to upper layers to send data
+ * @scn: pointer to hif_opaque_softc structure
+ * @pipe_id: HIF pipe on which data is to be sent
+ * @transfer_id: endpoint ID on which data is to be sent
+ * @nbytes: number of bytes to be transmitted
+ * @wbuf: qdf_nbuf_t containing data to be transmitted
+ * @hdr_buf: any header buf to be prepended, currently ignored
+ * @data_attr: data_attr field from cvg_nbuf_cb of wbuf
+ *
+ * Return: QDF_STATUS_SUCCESS on success and error QDF status on failure
+ */
+QDF_STATUS hif_send_head(struct hif_opaque_softc *scn, uint8_t pipe_id,
+				uint32_t transfer_id, uint32_t nbytes,
+				qdf_nbuf_t wbuf, uint32_t data_attr)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
+	HIF_TRACE("+%s", __func__);
+	status = hif_send_internal(device, pipe_id, NULL, wbuf, nbytes);
+	HIF_TRACE("-%s", __func__);
+	return status;
+}
+
+/**
+ * hif_get_free_queue_number() - get # of free TX resources in a given HIF pipe
+ * @scn: pointer to hif_opaque_softc structure
+ * @pipe_id: HIF pipe which is being polled for free resources
+ *
+ * Return: # of free resources in pipe_id
+ */
+uint16_t hif_get_free_queue_number(struct hif_opaque_softc *scn, uint8_t pipe_id)
+{
+	HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
+
+	return device->pipes[pipe_id].urb_cnt;
+}
+
+/**
+ * hif_post_init() - copy HTC callbacks to HIF
+ * @scn: pointer to hif_opaque_softc structure
+ * @target: pointer to HTC_TARGET structure
+ * @callbacks: htc callbacks
+ *
+ * Return: none
+ */
+void hif_post_init(struct hif_opaque_softc *scn, void *target,
+		struct hif_msg_callbacks *callbacks)
+{
+	HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
+
+	qdf_mem_copy(&device->htc_callbacks, callbacks,
+			sizeof(device->htc_callbacks));
+}
+
+/**
+ * hif_detach_htc() - remove HTC callbacks from HIF
+ * @scn: pointer to hif_opaque_softc structure
+ *
+ * Return: none
+ */
+void hif_detach_htc(struct hif_opaque_softc *scn)
+{
+	HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
+	usb_hif_flush_all(device);
+	qdf_mem_zero(&device->htc_callbacks, sizeof(device->htc_callbacks));
+}
+
+/**
+ * hif_usb_device_deinit() - de- init  HIF_DEVICE_USB, cleanup pipe resources
+ * @sc: pointer to hif_usb_softc structure
+ *
+ * Return: None
+ */
+void hif_usb_device_deinit(struct hif_usb_softc *sc)
+{
+	HIF_DEVICE_USB *device = &sc->hif_hdl;
+
+	HIF_TRACE("+%s", __func__);
+
+	usb_hif_cleanup_pipe_resources(device);
+
+	usb_set_intfdata(device->interface, NULL);
+
+	if (device->diag_cmd_buffer != NULL)
+		qdf_mem_free(device->diag_cmd_buffer);
+
+	if (device->diag_resp_buffer != NULL)
+		qdf_mem_free(device->diag_resp_buffer);
+
+	HIF_TRACE("-%s", __func__);
+}
+
+/**
+ * hif_usb_device_init() - init  HIF_DEVICE_USB, setup pipe resources
+ * @sc: pointer to hif_usb_softc structure
+ *
+ * Return: QDF_STATUS_SUCCESS on success or a QDF error
+ */
+QDF_STATUS hif_usb_device_init(struct hif_usb_softc *sc)
+{
+	int i;
+	HIF_DEVICE_USB *device = &sc->hif_hdl;
+	struct usb_interface *interface = sc->interface;
+	struct usb_device *dev = interface_to_usbdev(interface);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	HIF_USB_PIPE *pipe;
+
+	HIF_TRACE("+%s", __func__);
+
+	do {
+
+		usb_set_intfdata(interface, device);
+		qdf_spinlock_create(&(device->cs_lock));
+		qdf_spinlock_create(&(device->rx_lock));
+		qdf_spinlock_create(&(device->tx_lock));
+		device->udev = dev;
+		device->interface = interface;
+
+		HIF_ERROR("%s device %p device->udev %p device->interface %p",
+			__func__,
+			device,
+			device->udev,
+			device->interface);
+
+		for (i = 0; i < HIF_USB_PIPE_MAX; i++) {
+			pipe = &device->pipes[i];
+
+			HIF_USB_INIT_WORK(pipe);
+			skb_queue_head_init(&pipe->io_comp_queue);
+		}
+
+		device->diag_cmd_buffer =
+			qdf_mem_malloc(USB_CTRL_MAX_DIAG_CMD_SIZE);
+		if (NULL == device->diag_cmd_buffer) {
+			status = QDF_STATUS_E_NOMEM;
+			break;
+		}
+		device->diag_resp_buffer =
+			qdf_mem_malloc(USB_CTRL_MAX_DIAG_RESP_SIZE);
+		if (NULL == device->diag_resp_buffer) {
+			status = QDF_STATUS_E_NOMEM;
+			break;
+		}
+
+		status = usb_hif_setup_pipe_resources(device);
+
+	} while (false);
+
+	if (status != QDF_STATUS_SUCCESS)
+		HIF_ERROR("%s: abnormal condition", __func__);
+
+	HIF_TRACE("+%s", __func__);
+	return status;
+}
+
+/**
+ * hif_start() - Enable HIF TX and RX
+ * @scn: pointer to hif_opaque_softc structure
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+QDF_STATUS hif_start(struct hif_opaque_softc *scn)
+{
+	HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
+	int i;
+
+	HIF_TRACE("+%s", __func__);
+	usb_hif_prestart_recv_pipes(device);
+
+	/* set the TX resource avail threshold for each TX pipe */
+	for (i = HIF_TX_CTRL_PIPE; i <= HIF_TX_DATA_HP_PIPE; i++) {
+		device->pipes[i].urb_cnt_thresh =
+		    device->pipes[i].urb_alloc / 2;
+	}
+
+	HIF_TRACE("-%s", __func__);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hif_usb_stop_device() - Stop/flush all HIF communication
+ * @scn: pointer to hif_opaque_softc structure
+ *
+ * Return: none
+ */
+void hif_usb_stop_device(struct hif_softc *hif_sc)
+{
+	HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(hif_sc);
+
+	HIF_TRACE("+%s", __func__);
+
+	usb_hif_flush_all(device);
+
+	HIF_TRACE("-%s", __func__);
+}
+
+/**
+ * hif_get_default_pipe() - get default pipes for HIF TX/RX
+ * @scn: pointer to hif_opaque_softc structure
+ * @ul_pipe: pointer to TX pipe
+ * @ul_pipe: pointer to TX pipe
+ *
+ * Return: none
+ */
+void hif_get_default_pipe(struct hif_opaque_softc *scn, uint8_t *ul_pipe,
+			  uint8_t *dl_pipe)
+{
+	*ul_pipe = HIF_TX_CTRL_PIPE;
+	*dl_pipe = HIF_RX_CTRL_PIPE;
+}
+
+#if defined(USB_MULTI_IN_TEST) || defined(USB_ISOC_TEST)
+/**
+ * hif_map_service_to_pipe() - maps ul/dl pipe to service id.
+ * @scn: HIF context
+ * @svc_id: sevice index
+ * @ul_pipe: pointer to uplink pipe id
+ * @dl_pipe: pointer to down-linklink pipe id
+ * @ul_is_polled: if ul is polling based
+ * @ul_is_polled: if dl is polling based
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+int hif_map_service_to_pipe(struct hif_opaque_softc *scn, uint16_t svc_id,
+			    uint8_t *ul_pipe, uint8_t *dl_pipe,
+			    int *ul_is_polled, int *dl_is_polled)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	switch (svc_id) {
+	case HTC_CTRL_RSVD_SVC:
+	case WMI_CONTROL_SVC:
+	case HTC_RAW_STREAMS_SVC:
+		*ul_pipe = HIF_TX_CTRL_PIPE;
+		*dl_pipe = HIF_RX_DATA_PIPE;
+		break;
+	case WMI_DATA_BE_SVC:
+		*ul_pipe = HIF_TX_DATA_LP_PIPE;
+		*dl_pipe = HIF_RX_DATA_PIPE;
+		break;
+	case WMI_DATA_BK_SVC:
+		*ul_pipe = HIF_TX_DATA_MP_PIPE;
+		*dl_pipe = HIF_RX_DATA2_PIPE;
+		break;
+	case WMI_DATA_VI_SVC:
+		*ul_pipe = HIF_TX_DATA_HP_PIPE;
+		*dl_pipe = HIF_RX_DATA_PIPE;
+		break;
+	case WMI_DATA_VO_SVC:
+		*ul_pipe = HIF_TX_DATA_LP_PIPE;
+		*dl_pipe = HIF_RX_DATA_PIPE;
+		break;
+	default:
+		status = QDF_STATUS_E_FAILURE;
+		break;
+	}
+
+	return status;
+}
+#else
+
+#ifdef QCA_TX_HTT2_SUPPORT
+#define USB_TX_CHECK_HTT2_SUPPORT 1
+#else
+#define USB_TX_CHECK_HTT2_SUPPORT 0
+#endif
+
+/**
+ * hif_map_service_to_pipe() - maps ul/dl pipe to service id.
+ * @scn: HIF context
+ * @svc_id: sevice index
+ * @ul_pipe: pointer to uplink pipe id
+ * @dl_pipe: pointer to down-linklink pipe id
+ * @ul_is_polled: if ul is polling based
+ * @ul_is_polled: if dl is polling based
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+int hif_map_service_to_pipe(struct hif_opaque_softc *scn, uint16_t svc_id,
+			    uint8_t *ul_pipe, uint8_t *dl_pipe,
+			    int *ul_is_polled, int *dl_is_polled)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	switch (svc_id) {
+	case HTC_CTRL_RSVD_SVC:
+	case WMI_CONTROL_SVC:
+		*ul_pipe = HIF_TX_CTRL_PIPE;
+		*dl_pipe = HIF_RX_DATA_PIPE;
+		break;
+	case WMI_DATA_BE_SVC:
+	case WMI_DATA_BK_SVC:
+		*ul_pipe = HIF_TX_DATA_LP_PIPE;
+		if (hif_usb_disable_rxdata2)
+			*dl_pipe = HIF_RX_DATA_PIPE;
+		else
+			*dl_pipe = HIF_RX_DATA2_PIPE;
+		break;
+	case WMI_DATA_VI_SVC:
+		*ul_pipe = HIF_TX_DATA_MP_PIPE;
+		if (hif_usb_disable_rxdata2)
+			*dl_pipe = HIF_RX_DATA_PIPE;
+		else
+			*dl_pipe = HIF_RX_DATA2_PIPE;
+		break;
+	case WMI_DATA_VO_SVC:
+		*ul_pipe = HIF_TX_DATA_HP_PIPE;
+		if (hif_usb_disable_rxdata2)
+			*dl_pipe = HIF_RX_DATA_PIPE;
+		else
+			*dl_pipe = HIF_RX_DATA2_PIPE;
+		break;
+	case HTC_RAW_STREAMS_SVC:
+		*ul_pipe = HIF_TX_CTRL_PIPE;
+		*dl_pipe = HIF_RX_DATA_PIPE;
+		break;
+	case HTT_DATA_MSG_SVC:
+		*ul_pipe = HIF_TX_DATA_LP_PIPE;
+		if (hif_usb_disable_rxdata2)
+			*dl_pipe = HIF_RX_DATA_PIPE;
+		else
+			*dl_pipe = HIF_RX_DATA2_PIPE;
+		break;
+	case HTT_DATA2_MSG_SVC:
+		if (USB_TX_CHECK_HTT2_SUPPORT) {
+			*ul_pipe = HIF_TX_DATA_HP_PIPE;
+			if (hif_usb_disable_rxdata2)
+				*dl_pipe = HIF_RX_DATA_PIPE;
+			else
+				*dl_pipe = HIF_RX_DATA2_PIPE;
+			}
+		break;
+	default:
+		status = QDF_STATUS_E_FAILURE;
+		break;
+	}
+
+	return status;
+}
+#endif
+
+/**
+ * hif_ctrl_msg_exchange() - send usb ctrl message and receive response
+ * @macp: pointer to HIF_DEVICE_USB
+ * @send_req_val: USB send message request value
+ * @send_msg: pointer to data to send
+ * @len: length in bytes of the data to send
+ * @response_req_val: USB response message request value
+ * @response_msg: pointer to response msg
+ * @response_len: length of the response message
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+static QDF_STATUS hif_ctrl_msg_exchange(HIF_DEVICE_USB *macp,
+				uint8_t send_req_val,
+				uint8_t *send_msg,
+				uint32_t len,
+				uint8_t response_req_val,
+				uint8_t *response_msg,
+				uint32_t *response_len)
+{
+	QDF_STATUS status;
+
+	do {
+
+		/* send command */
+		status = usb_hif_submit_ctrl_out(macp, send_req_val, 0, 0,
+						 send_msg, len);
+
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+
+		if (NULL == response_msg) {
+			/* no expected response */
+			break;
+		}
+
+		/* get response */
+		status = usb_hif_submit_ctrl_in(macp, response_req_val, 0, 0,
+						response_msg, *response_len);
+
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+
+	} while (false);
+
+	return status;
+}
+
+/**
+ * hif_exchange_bmi_msg() - send/recev ctrl message of type BMI_CMD/BMI_RESP
+ * @scn: pointer to hif_opaque_softc
+ * @bmi_request: pointer to data to send
+ * @request_length: length in bytes of the data to send
+ * @bmi_response: pointer to response msg
+ * @bmi_response_length: length of the response message
+ * @timeout_ms: timeout to wait for response (ignored in current implementation)
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+
+QDF_STATUS hif_exchange_bmi_msg(struct hif_opaque_softc *scn,
+				qdf_dma_addr_t cmd, qdf_dma_addr_t rsp,
+				uint8_t *bmi_request,
+				uint32_t request_length,
+				uint8_t *bmi_response,
+				uint32_t *bmi_response_lengthp,
+				uint32_t timeout_ms)
+{
+	HIF_DEVICE_USB *macp = HIF_GET_USB_DEVICE(scn);
+
+	return hif_ctrl_msg_exchange(macp,
+				USB_CONTROL_REQ_SEND_BMI_CMD,
+				bmi_request,
+				request_length,
+				USB_CONTROL_REQ_RECV_BMI_RESP,
+				bmi_response, bmi_response_lengthp);
+}
+
+/**
+ * hif_diag_read_access() - Read data from target memory or register
+ * @scn: pointer to hif_opaque_softc
+ * @address: register address to read from
+ * @data: pointer to buffer to store the value read from the register
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+QDF_STATUS hif_diag_read_access(struct hif_opaque_softc *scn, uint32_t address,
+					uint32_t *data)
+{
+	HIF_DEVICE_USB *macp = HIF_GET_USB_DEVICE(scn);
+	QDF_STATUS status;
+	USB_CTRL_DIAG_CMD_READ *cmd;
+	uint32_t respLength;
+
+	cmd = (USB_CTRL_DIAG_CMD_READ *) macp->diag_cmd_buffer;
+
+	qdf_mem_zero(cmd, sizeof(*cmd));
+	cmd->Cmd = USB_CTRL_DIAG_CC_READ;
+	cmd->Address = address;
+	respLength = sizeof(USB_CTRL_DIAG_RESP_READ);
+
+	status = hif_ctrl_msg_exchange(macp,
+				USB_CONTROL_REQ_DIAG_CMD,
+				(uint8_t *) cmd,
+				sizeof(*cmd),
+				USB_CONTROL_REQ_DIAG_RESP,
+				macp->diag_resp_buffer, &respLength);
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		USB_CTRL_DIAG_RESP_READ *pResp =
+			(USB_CTRL_DIAG_RESP_READ *) macp->diag_resp_buffer;
+		*data = pResp->ReadValue;
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+/**
+ * hif_diag_write_access() - write data to target memory or register
+ * @scn: pointer to hif_opaque_softc
+ * @address: register address to write to
+ * @data: value to be written to the address
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+QDF_STATUS hif_diag_write_access(struct hif_opaque_softc *scn,
+					uint32_t address,
+					uint32_t data)
+{
+	HIF_DEVICE_USB *macp = HIF_GET_USB_DEVICE(scn);
+	USB_CTRL_DIAG_CMD_WRITE *cmd;
+
+	cmd = (USB_CTRL_DIAG_CMD_WRITE *) macp->diag_cmd_buffer;
+
+	qdf_mem_zero(cmd, sizeof(*cmd));
+	cmd->Cmd = USB_CTRL_DIAG_CC_WRITE;
+	cmd->Address = address;
+	cmd->Value = data;
+
+	return hif_ctrl_msg_exchange(macp,
+				USB_CONTROL_REQ_DIAG_CMD,
+				(uint8_t *) cmd,
+				sizeof(*cmd), 0, NULL, 0);
+}
+
+/**
+ * hif_dump_info() - dump info about all HIF pipes and endpoints
+ * @scn: pointer to hif_opaque_softc
+ *
+ * Return: none
+ */
+void hif_dump_info(struct hif_opaque_softc *scn)
+{
+	HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
+	HIF_USB_PIPE *pipe = NULL;
+	struct usb_host_interface *iface_desc = NULL;
+	struct usb_endpoint_descriptor *ep_desc;
+	uint8_t i = 0;
+
+	for (i = 0; i < HIF_USB_PIPE_MAX; i++) {
+		pipe = &device->pipes[i];
+		HIF_ERROR("PipeIndex : %d URB Cnt : %d PipeHandle : %x",
+			i, pipe->urb_cnt,
+			pipe->usb_pipe_handle);
+		if (usb_pipeisoc(pipe->usb_pipe_handle))
+			HIF_INFO("Pipe Type ISOC");
+		else if (usb_pipebulk(pipe->usb_pipe_handle))
+			HIF_INFO("Pipe Type BULK");
+		else if (usb_pipeint(pipe->usb_pipe_handle))
+			HIF_INFO("Pipe Type INT");
+		else if (usb_pipecontrol(pipe->usb_pipe_handle))
+			HIF_INFO("Pipe Type control");
+	}
+
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
+		ep_desc = &iface_desc->endpoint[i].desc;
+		if (ep_desc) {
+			HIF_INFO(
+				"ep_desc : %p Index : %d: DescType : %d Addr : %d Maxp : %d Atrrib : %d",
+				ep_desc, i, ep_desc->bDescriptorType,
+				ep_desc->bEndpointAddress,
+				ep_desc->wMaxPacketSize,
+				ep_desc->bmAttributes);
+			if ((ep_desc) && (usb_endpoint_type(ep_desc) ==
+						USB_ENDPOINT_XFER_ISOC)) {
+				HIF_INFO("ISOC EP Detected");
+			}
+		}
+	}
+
+}
+
+/**
+ * hif_flush_surprise_remove() - Cleanup residual buffers for device shutdown
+ * @scn: HIF context
+ *
+ * Not applicable to USB bus
+ *
+ * Return: none
+ */
+void hif_flush_surprise_remove(struct hif_opaque_softc *scn)
+{
+/* TO DO... */
+}
+
+/**
+ * hif_diag_read_mem() -read nbytes of data from target memory or register
+ * @scn: pointer to hif_opaque_softc
+ * @address: register address to read from
+ * @data: buffer to store the value read
+ * @nbytes: number of bytes to be read from 'address'
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+QDF_STATUS hif_diag_read_mem(struct hif_opaque_softc *scn,
+					 uint32_t address, uint8_t *data,
+					 int nbytes)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	HIF_TRACE("+%s", __func__);
+
+	if ((address & 0x3) || ((uintptr_t)data & 0x3))
+		return QDF_STATUS_E_IO;
+
+	while ((nbytes >= 4) &&
+		QDF_IS_STATUS_SUCCESS(status =
+					hif_diag_read_access(scn,
+							address,
+							(uint32_t *)data))) {
+
+		nbytes -= sizeof(uint32_t);
+		address += sizeof(uint32_t);
+		data += sizeof(uint32_t);
+
+	}
+	HIF_TRACE("-%s", __func__);
+	return status;
+}
+
+/**
+ * hif_diag_write_mem() -write  nbytes of data to target memory or register
+ * @scn: pointer to hif_opaque_softc
+ * @address: register address to write to
+ * @data: buffer containing data to be written
+ * @nbytes: number of bytes to be written
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *scn,
+					   uint32_t address,
+					   uint8_t *data, int nbytes)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	HIF_TRACE("+%s", __func__);
+
+	if ((address & 0x3) || ((uintptr_t)data & 0x3))
+		return QDF_STATUS_E_IO;
+
+	while (nbytes >= 4 &&
+		QDF_IS_STATUS_SUCCESS(status =
+					hif_diag_write_access(scn,
+						address,
+						*((uint32_t *)data)))) {
+
+		nbytes -= sizeof(uint32_t);
+		address += sizeof(uint32_t);
+		data += sizeof(uint32_t);
+
+	}
+	HIF_TRACE("-%s", __func__);
+	return status;
+}
+
+void hif_send_complete_check(struct hif_opaque_softc *scn,
+						uint8_t PipeID, int force)
+{
+	/* NO-OP*/
+}
+
+/* diagnostic command defnitions */
+#define USB_CTRL_DIAG_CC_READ       0
+#define USB_CTRL_DIAG_CC_WRITE      1
+#define USB_CTRL_DIAG_CC_WARM_RESET 2
+
+void hif_suspend_wow(struct hif_opaque_softc *scn)
+{
+	HIF_INFO("HIFsuspendwow - TODO");
+}
+
+/**
+ * hif_set_bundle_mode() - enable bundling and set default rx bundle cnt
+ * @scn: pointer to hif_opaque_softc structure
+ * @enabled: flag to enable/disable bundling
+ * @rx_bundle_cnt: bundle count to be used for RX
+ *
+ * Return: none
+ */
+void hif_set_bundle_mode(struct hif_opaque_softc *scn,
+					bool enabled, int rx_bundle_cnt)
+{
+	HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn);
+
+	device->is_bundle_enabled = enabled;
+	device->rx_bundle_cnt = rx_bundle_cnt;
+	if (device->is_bundle_enabled && (device->rx_bundle_cnt == 0))
+		device->rx_bundle_cnt = 1;
+
+	device->rx_bundle_buf_len = device->rx_bundle_cnt *
+					HIF_USB_RX_BUNDLE_ONE_PKT_SIZE;
+
+	HIF_DBG("athusb bundle %s cnt %d", enabled ? "enabled" : "disabled",
+			rx_bundle_cnt);
+}

+ 127 - 0
hif/src/usb/hif_usb_internal.h

@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+#ifndef _HIF_USB_INTERNAL_H
+#define _HIF_USB_INTERNAL_H
+
+#include <qdf_nbuf.h>
+#include "a_types.h"
+#include "athdefs.h"
+#include "a_osapi.h"
+#include "a_usb_defs.h"
+#include <ol_if_athvar.h>
+#include <linux/usb.h>
+#include "hif.h"
+#include "if_usb.h"
+
+#define TX_URB_COUNT    32
+#define RX_URB_COUNT    32
+
+#define HIF_USB_RX_BUFFER_SIZE  (1792 + 8)
+#define HIF_USB_RX_BUNDLE_ONE_PKT_SIZE  (1792 + 8)
+
+#ifdef HIF_USB_TASKLET
+#define HIF_USB_SCHEDULE_WORK(pipe)\
+	tasklet_schedule(&pipe->io_complete_tasklet);
+
+#define HIF_USB_INIT_WORK(pipe)\
+		tasklet_init(&pipe->io_complete_tasklet,\
+				usb_hif_io_comp_tasklet,\
+				(long unsigned int)pipe);
+
+#define HIF_USB_FLUSH_WORK(pipe) flush_work(&pipe->io_complete_work);
+#else
+#define HIF_USB_SCHEDULE_WORK(pipe) schedule_work(&pipe->io_complete_work);
+#define HIF_USB_INIT_WORK(pipe)\
+		INIT_WORK(&pipe->io_complete_work,\
+				usb_hif_io_comp_work);
+#define HIF_USB_FLUSH_WORK(pipe)
+#endif
+
+/* debug masks */
+#define USB_HIF_DEBUG_CTRL_TRANS            ATH_DEBUG_MAKE_MODULE_MASK(0)
+#define USB_HIF_DEBUG_BULK_IN               ATH_DEBUG_MAKE_MODULE_MASK(1)
+#define USB_HIF_DEBUG_BULK_OUT              ATH_DEBUG_MAKE_MODULE_MASK(2)
+#define USB_HIF_DEBUG_ENUM                  ATH_DEBUG_MAKE_MODULE_MASK(3)
+#define USB_HIF_DEBUG_DUMP_DATA             ATH_DEBUG_MAKE_MODULE_MASK(4)
+#define USB_HIF_SUSPEND                     ATH_DEBUG_MAKE_MODULE_MASK(5)
+#define USB_HIF_ISOC_SUPPORT                ATH_DEBUG_MAKE_MODULE_MASK(6)
+
+struct _HIF_USB_PIPE;
+
+typedef struct _HIF_URB_CONTEXT {
+	DL_LIST link;
+	struct _HIF_USB_PIPE *pipe;
+	qdf_nbuf_t buf;
+	struct urb *urb;
+	struct hif_usb_send_context *send_context;
+} HIF_URB_CONTEXT;
+
+#define HIF_USB_PIPE_FLAG_TX    (1 << 0)
+
+/*
+ * Data structure to record required sending context data
+ */
+struct hif_usb_send_context {
+	A_BOOL new_alloc;
+	HIF_DEVICE_USB *hif_usb_device;
+	qdf_nbuf_t netbuf;
+	unsigned int transfer_id;
+	unsigned int head_data_len;
+};
+
+extern unsigned int hif_usb_disable_rxdata2;
+
+extern QDF_STATUS usb_hif_submit_ctrl_in(HIF_DEVICE_USB *macp,
+				uint8_t req,
+				uint16_t value,
+				uint16_t index,
+				void *data, uint32_t size);
+
+extern QDF_STATUS usb_hif_submit_ctrl_out(HIF_DEVICE_USB *macp,
+					uint8_t req,
+					uint16_t value,
+					uint16_t index,
+					void *data, uint32_t size);
+
+QDF_STATUS usb_hif_setup_pipe_resources(HIF_DEVICE_USB *device);
+void usb_hif_cleanup_pipe_resources(HIF_DEVICE_USB *device);
+void usb_hif_prestart_recv_pipes(HIF_DEVICE_USB *device);
+void usb_hif_start_recv_pipes(HIF_DEVICE_USB *device);
+void usb_hif_flush_all(HIF_DEVICE_USB *device);
+void usb_hif_cleanup_transmit_urb(HIF_URB_CONTEXT *urb_context);
+void usb_hif_enqueue_pending_transfer(HIF_USB_PIPE *pipe,
+						HIF_URB_CONTEXT *urb_context);
+void usb_hif_remove_pending_transfer(HIF_URB_CONTEXT *urb_context);
+HIF_URB_CONTEXT *usb_hif_alloc_urb_from_pipe(HIF_USB_PIPE *pipe);
+#ifdef HIF_USB_TASKLET
+void usb_hif_io_comp_tasklet(long unsigned int context);
+#else
+void usb_hif_io_comp_work(struct work_struct *work);
+#endif
+QDF_STATUS hif_diag_write_warm_reset(struct usb_interface *interface,
+			uint32_t address, uint32_t data);
+#endif

+ 716 - 0
hif/src/usb/if_usb.c

@@ -0,0 +1,716 @@
+/*
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include "if_usb.h"
+#include "hif_usb_internal.h"
+#include "bmi_msg.h"		/* TARGET_TYPE_ */
+#include "regtable_usb.h"
+#include "ol_fw.h"
+#include "hif_debug.h"
+#include "epping_main.h"
+#include "hif_main.h"
+#include "qwlan_version.h"
+
+#define DELAY_FOR_TARGET_READY 200	/* 200ms */
+
+/* Save memory addresses where we save FW ram dump, and then we could obtain
+ * them by symbol table.
+ */
+uint32_t fw_stack_addr;
+void *fw_ram_seg_addr[FW_RAM_SEG_CNT];
+
+
+
+static int hif_usb_unload_dev_num = -1;
+struct hif_usb_softc *g_usb_sc = NULL;
+
+void hif_usb_device_deinit(struct hif_usb_softc *sc);
+QDF_STATUS hif_usb_device_init(struct hif_usb_softc *sc);
+
+/**
+ * hif_usb_diag_write_cold_reset() - reset SOC by sending a diag command
+ * @scn: pointer to ol_softc structure
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+static inline QDF_STATUS
+hif_usb_diag_write_cold_reset(struct hif_softc *scn)
+{
+	struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(scn);
+
+
+	HIF_DBG("%s: resetting SOC", __func__);
+
+	return hif_diag_write_access(hif_hdl,
+				(ROME_USB_SOC_RESET_CONTROL_COLD_RST_LSB |
+				ROME_USB_RTC_SOC_BASE_ADDRESS),
+				SOC_RESET_CONTROL_COLD_RST_SET(1));
+}
+
+/**
+ * hif_usb_procfs_init() - create init procfs
+ * @scn: pointer to hif_usb_softc structure
+ *
+ * Return: int 0 if success else an appropriate error number
+ */
+static int
+hif_usb_procfs_init(struct hif_softc *scn)
+{
+	int ret = 0;
+
+	HIF_ENTER();
+
+	if (athdiag_procfs_init(scn) != 0) {
+		HIF_ERROR("athdiag_procfs_init failed");
+		ret = A_ERROR;
+	}
+
+	scn->athdiag_procfs_inited = true;
+
+	HIF_EXIT();
+	return ret;
+}
+
+/**
+ * hif_nointrs(): disable IRQ
+ * @scn: pointer to struct hif_softc
+ *
+ * This function stops interrupt(s)
+ *
+ * Return: none
+ */
+void hif_usb_nointrs(struct hif_softc *scn)
+{
+
+}
+
+/**
+ * hif_usb_reboot() - called at reboot time to reset WLAN SOC
+ * @nb: pointer to notifier_block registered during register_reboot_notifier
+ * @val: code indicating reboot reason
+ * @v: unused pointer
+ *
+ * Return: int 0 if success else an appropriate error number
+ */
+static int hif_usb_reboot(struct notifier_block *nb, unsigned long val,
+				void *v)
+{
+	struct hif_usb_softc *sc;
+
+	HIF_ENTER();
+	sc = container_of(nb, struct hif_usb_softc, reboot_notifier);
+	/* do cold reset */
+	hif_usb_diag_write_cold_reset(HIF_GET_SOFTC(sc));
+	HIF_EXIT();
+	return NOTIFY_DONE;
+}
+
+/**
+ * hif_usb_disable_lpm() - Disable lpm feature of usb2.0
+ * @udev: pointer to usb_device for which LPM is to be disabled
+ *
+ * LPM needs to be disabled to avoid usb2.0 probe timeout
+ *
+ * Return: int 0 if success else an appropriate error number
+ */
+static int hif_usb_disable_lpm(struct usb_device *udev)
+{
+	struct usb_hcd *hcd;
+	int ret = -EPERM;
+
+	HIF_ENTER();
+
+	if (!udev || !udev->bus) {
+		HIF_ERROR("Invalid input parameters");
+		goto exit;
+	}
+
+	hcd = bus_to_hcd(udev->bus);
+	if (udev->usb2_hw_lpm_enabled) {
+		if (hcd->driver->set_usb2_hw_lpm) {
+			ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, false);
+			if (!ret) {
+				udev->usb2_hw_lpm_enabled = false;
+				udev->usb2_hw_lpm_capable = false;
+				HIF_TRACE("%s: LPM is disabled", __func__);
+			} else {
+				HIF_TRACE("%s: Fail to disable LPM",
+						__func__);
+			}
+		} else {
+			HIF_TRACE("%s: hcd doesn't support LPM",
+						__func__);
+		}
+	} else {
+		HIF_TRACE("%s: LPM isn't enabled", __func__);
+	}
+exit:
+	HIF_EXIT();
+	return ret;
+}
+
+/**
+ * hif_usb_enable_bus() - enable usb bus
+ * @ol_sc: hif_softc struct
+ * @dev: device pointer
+ * @bdev: bus dev pointer
+ * @bid: bus id pointer
+ * @type: enum hif_enable_type such as HIF_ENABLE_TYPE_PROBE
+ *
+ * Return: QDF_STATUS_SUCCESS on success and error QDF status on failure
+ */
+QDF_STATUS hif_usb_enable_bus(struct hif_softc *scn,
+			struct device *dev, void *bdev,
+			const hif_bus_id *bid,
+			enum hif_enable_type type)
+
+{
+	struct usb_interface *interface = (struct usb_interface *)bdev;
+	struct usb_device_id *id = (struct usb_device_id *)bid;
+	int ret = 0;
+	struct hif_usb_softc *sc;
+	struct usb_device *usbdev = interface_to_usbdev(interface);
+	int vendor_id, product_id;
+
+	usb_get_dev(usbdev);
+
+	if (!scn) {
+		HIF_ERROR("%s: hif_ctx is NULL", __func__);
+		goto err_usb;
+	}
+
+	sc = HIF_GET_USB_SOFTC(scn);
+
+	HIF_INFO("%s hif_softc %p usbdev %p interface %p\n",
+		__func__,
+		scn,
+		usbdev,
+		interface);
+
+	vendor_id = qdf_le16_to_cpu(usbdev->descriptor.idVendor);
+	product_id = qdf_le16_to_cpu(usbdev->descriptor.idProduct);
+
+	HIF_ERROR("%s: con_mode = 0x%x, vendor_id = 0x%x product_id = 0x%x",
+		__func__, hif_get_conparam(scn), vendor_id, product_id);
+
+	sc->pdev = (void *)usbdev;
+	sc->dev = &usbdev->dev;
+	sc->devid = id->idProduct;
+
+	if ((usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
+			USB_REQ_SET_CONFIGURATION, 0, 1, 0, NULL, 0,
+			HZ)) < 0) {
+		HIF_ERROR("%s[%d]", __func__, __LINE__);
+		goto err_usb;
+	}
+
+	usb_set_interface(usbdev, 0, 0);
+	/* disable lpm to avoid usb2.0 probe timeout */
+	hif_usb_disable_lpm(usbdev);
+
+	/* params need to be added - TO DO
+	scn->enableuartprint = 1;
+	scn->enablefwlog = 0;
+	scn->max_no_of_peers = 1; */
+
+	sc->interface = interface;
+	sc->reboot_notifier.notifier_call = hif_usb_reboot;
+	register_reboot_notifier(&sc->reboot_notifier);
+
+	if (hif_usb_device_init(sc) != QDF_STATUS_SUCCESS) {
+		HIF_ERROR("ath: %s: hif_usb_device_init failed", __func__);
+		goto err_reset;
+	}
+
+	if (hif_usb_procfs_init(scn))
+		goto err_reset;
+
+	hif_usb_unload_dev_num = usbdev->devnum;
+	g_usb_sc = sc;
+	HIF_EXIT();
+	return 0;
+
+err_reset:
+	hif_usb_diag_write_cold_reset(scn);
+	g_usb_sc = NULL;
+	hif_usb_unload_dev_num = -1;
+	unregister_reboot_notifier(&sc->reboot_notifier);
+err_usb:
+	ret = QDF_STATUS_E_FAILURE;
+	usb_put_dev(usbdev);
+	return ret;
+}
+
+
+/**
+ * hif_usb_close(): close bus, delete hif_sc
+ * @ol_sc: soft_sc struct
+ *
+ * Return: none
+ */
+void hif_usb_close(struct hif_softc *scn)
+{
+	g_usb_sc = NULL;
+}
+
+/**
+ * hif_usb_disable_bus(): This function disables usb bus
+ * @hif_ctx: pointer to struct hif_softc
+ *
+ * Return: none
+ */
+void hif_usb_disable_bus(struct hif_softc *hif_ctx)
+{
+	struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(hif_ctx);
+	struct usb_interface *interface = sc->interface;
+	struct usb_device *udev = interface_to_usbdev(interface);
+
+	HIF_TRACE("%s: trying to remove hif_usb!", __func__);
+
+	/* disable lpm to avoid following cold reset will
+	 * cause xHCI U1/U2 timeout
+	 */
+	usb_disable_lpm(udev);
+
+	/* wait for disable lpm */
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(msecs_to_jiffies(DELAY_FOR_TARGET_READY));
+	set_current_state(TASK_RUNNING);
+
+	/* do cold reset */
+	hif_usb_diag_write_cold_reset(hif_ctx);
+
+	if (g_usb_sc->suspend_state)
+		hif_bus_resume(GET_HIF_OPAQUE_HDL(hif_ctx));
+
+	unregister_reboot_notifier(&sc->reboot_notifier);
+	usb_put_dev(interface_to_usbdev(interface));
+
+	hif_usb_device_deinit(sc);
+
+	HIF_TRACE("%s hif_usb removed !!!!!!", __func__);
+}
+
+/**
+ * hif_usb_bus_suspend() - suspend the bus
+ * @hif_ctx: hif_ctx
+ *
+ * This function suspends the bus, but usb doesn't need to suspend.
+ * Therefore just remove all the pending urb transactions
+ *
+ * Return: 0 for success and non-zero for failure
+ */
+int hif_usb_bus_suspend(struct hif_softc *hif_ctx)
+{
+	struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(hif_ctx);
+	HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(hif_ctx);
+
+	HIF_ENTER();
+	sc->suspend_state = 1;
+	usb_hif_flush_all(device);
+	HIF_EXIT();
+	return 0;
+}
+
+/**
+ * hif_usb_bus_resume() - hif resume API
+ * @hif_ctx: struct hif_opaque_softc
+ *
+ * This function resumes the bus. but usb doesn't need to resume.
+ * Post recv urbs for RX data pipe
+ *
+ * Return: 0 for success and non-zero for failure
+ */
+int hif_usb_bus_resume(struct hif_softc *hif_ctx)
+{
+	struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(hif_ctx);
+	HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(hif_ctx);
+
+	HIF_ENTER();
+	sc->suspend_state = 0;
+	usb_hif_start_recv_pipes(device);
+
+	HIF_EXIT();
+	return 0;
+}
+
+/**
+ * hif_bus_reset_resume() - resume the bus after reset
+ * @scn: struct hif_opaque_softc
+ *
+ * This function is called to tell the driver that USB device has been resumed
+ * and it has also been reset. The driver should redo any necessary
+ * initialization. This function resets WLAN SOC.
+ *
+ * Return: int 0 for success, non zero for failure
+ */
+int hif_bus_reset_resume(struct hif_opaque_softc *scn)
+{
+	int ret = 0;
+	struct hif_softc *hif_ctx = HIF_GET_SOFTC(scn);
+	HIF_ENTER();
+	if (hif_usb_diag_write_cold_reset(hif_ctx) != QDF_STATUS_SUCCESS)
+		ret = 1;
+
+	HIF_EXIT();
+	return ret;
+}
+
+/**
+ * hif_usb_open()- initialization routine for usb bus
+ * @ol_sc: ol_sc
+ * @bus_type: bus type
+ *
+ * Return: QDF_STATUS_SUCCESS on success and error QDF status on failure
+ */
+QDF_STATUS hif_usb_open(struct hif_softc *hif_ctx,
+		enum qdf_bus_type bus_type)
+{
+	hif_ctx->bus_type = bus_type;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hif_usb_disable_isr(): disable isr
+ * @hif_ctx: struct hif_softc
+ *
+ * Return: void
+ */
+void hif_usb_disable_isr(struct hif_softc *hif_ctx)
+{
+	/* TODO */
+}
+
+/**
+ * hif_usb_reg_tbl_attach()- attach hif, target register tables
+ * @scn: pointer to ol_softc structure
+ *
+ * Attach host and target register tables based on target_type, target_version
+ *
+ * Return: none
+ */
+void hif_usb_reg_tbl_attach(struct hif_softc *scn)
+{
+	u_int32_t hif_type, target_type;
+	int32_t ret = 0;
+	uint32_t chip_id;
+	QDF_STATUS rv;
+	struct hif_target_info *tgt_info = &scn->target_info;
+	struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(scn);
+
+	if (scn->hostdef == NULL && scn->targetdef == NULL) {
+		switch (tgt_info->target_type) {
+		case TARGET_TYPE_AR6320:
+			switch (tgt_info->target_version) {
+			case AR6320_REV1_VERSION:
+			case AR6320_REV1_1_VERSION:
+			case AR6320_REV1_3_VERSION:
+				hif_type = HIF_TYPE_AR6320;
+				target_type = TARGET_TYPE_AR6320;
+				break;
+			case AR6320_REV2_1_VERSION:
+			case AR6320_REV3_VERSION:
+			case QCA9377_REV1_1_VERSION:
+				hif_type = HIF_TYPE_AR6320V2;
+				target_type = TARGET_TYPE_AR6320V2;
+				break;
+			default:
+				ret = -1;
+				break;
+			}
+			break;
+		default:
+			ret = -1;
+			break;
+		}
+
+		if (ret)
+			return;
+
+		/* assign target register table if we find
+		corresponding type */
+		hif_register_tbl_attach(scn, hif_type);
+		target_register_tbl_attach(scn, target_type);
+		/* read the chip revision*/
+		rv = hif_diag_read_access(hif_hdl,
+					(CHIP_ID_ADDRESS |
+					RTC_SOC_BASE_ADDRESS),
+					&chip_id);
+		if (rv != QDF_STATUS_SUCCESS) {
+			HIF_ERROR("%s: get chip id val (%d)", __func__,
+				rv);
+		}
+		tgt_info->target_revision =
+				CHIP_ID_REVISION_GET(chip_id);
+	}
+}
+
+/**
+ * hif_usb_get_hw_info()- attach register table for USB
+ * @hif_ctx: pointer to hif_softc structure
+
+ * This function is used to attach the host and target register tables.
+ * Ideally, we should not attach register tables as a part of this function.
+ * There is scope of cleanup to move register table attach during
+ * initialization for USB bus.
+ *
+ * The reason we are doing register table attach for USB here is that, it relies
+ * on target_info->target_type and target_info->target_version,
+ * which get populated during bmi_firmware_download. "hif_get_fw_info" is the
+ * only initialization related call into HIF there after.
+ *
+ * To fix this, we can move the "get target info, functionality currently in
+ * bmi_firmware_download into hif initialization functions. This change will
+ * affect all buses. Can be taken up as a part of convergence.
+ *
+ * Return: none
+ */
+void hif_usb_get_hw_info(struct hif_softc *hif_ctx)
+{
+	hif_usb_reg_tbl_attach(hif_ctx);
+}
+
+
+/**
+ * hif_bus_configure() - configure the bus
+ * @scn: pointer to the hif context.
+ *
+ * return: 0 for success. nonzero for failure.
+ */
+int hif_usb_bus_configure(struct hif_softc *scn)
+{
+	return 0;
+}
+
+/**
+ * hif_usb_irq_enable() - hif_usb_irq_enable
+ * @scn: hif_softc
+ * @ce_id: ce_id
+ *
+ * Return: void
+ */
+void hif_usb_irq_enable(struct hif_softc *scn, int ce_id)
+{
+}
+
+/**
+ * hif_usb_irq_disable() - hif_usb_irq_disable
+ * @scn: hif_softc
+ * @ce_id: ce_id
+ *
+ * Return: void
+ */
+void hif_usb_irq_disable(struct hif_softc *scn, int ce_id)
+{
+}
+
+/**
+ * hif_usb_shutdown_bus_device() - This function shuts down the device
+ * @scn: hif opaque pointer
+ *
+ * Return: void
+ */
+void hif_usb_shutdown_bus_device(struct hif_softc *scn)
+{
+}
+
+/**
+ * hif_trigger_dump() - trigger various dump cmd
+ * @scn: struct hif_opaque_softc
+ * @cmd_id: dump command id
+ * @start: start/stop dump
+ *
+ * Return: None
+ */
+void hif_trigger_dump(struct hif_opaque_softc *scn, uint8_t cmd_id, bool start)
+{
+}
+
+/**
+ * hif_wlan_disable() - call the platform driver to disable wlan
+ * @scn: scn
+ *
+ * Return: void
+ */
+void hif_wlan_disable(struct hif_softc *scn)
+{
+}
+
+/**
+ * hif_fw_assert_ramdump_pattern() - handle firmware assert with ramdump pattern
+ * @sc: pointer to hif_usb_softc structure
+ *
+ * Return: void
+ */
+
+void hif_fw_assert_ramdump_pattern(struct hif_usb_softc *sc)
+{
+	uint32_t *reg, pattern, i = 0;
+	uint32_t len;
+	uint8_t *data;
+	uint8_t *ram_ptr = NULL;
+	char *fw_ram_seg_name[FW_RAM_SEG_CNT] = {"DRAM", "IRAM", "AXI"};
+
+	data = sc->fw_data;
+	len = sc->fw_data_len;
+	pattern = *((A_UINT32 *) data);
+
+	qdf_assert(sc->ramdump_index < FW_RAM_SEG_CNT);
+	i = sc->ramdump_index;
+	reg = (uint32_t *) (data + 4);
+	if (sc->fw_ram_dumping == 0) {
+		sc->fw_ram_dumping = 1;
+		HIF_ERROR("Firmware %s dump:\n", fw_ram_seg_name[i]);
+		sc->ramdump[i] =
+			qdf_mem_malloc(sizeof(struct fw_ramdump) +
+					FW_RAMDUMP_SEG_SIZE);
+		if (!sc->ramdump[i]) {
+			pr_err("Fail to allocate memory for ram dump");
+			QDF_BUG(0);
+		}
+		(sc->ramdump[i])->mem = (uint8_t *) (sc->ramdump[i] + 1);
+		fw_ram_seg_addr[i] = (sc->ramdump[i])->mem;
+		HIF_ERROR("FW %s start addr = %#08x\n",
+			fw_ram_seg_name[i], *reg);
+		HIF_ERROR("Memory addr for %s = %p\n",
+			fw_ram_seg_name[i],
+			(sc->ramdump[i])->mem);
+		(sc->ramdump[i])->start_addr = *reg;
+		(sc->ramdump[i])->length = 0;
+	}
+	reg++;
+	ram_ptr = (sc->ramdump[i])->mem + (sc->ramdump[i])->length;
+	(sc->ramdump[i])->length += (len - 8);
+	qdf_mem_copy(ram_ptr, (A_UINT8 *) reg, len - 8);
+
+	if (pattern == FW_RAMDUMP_END_PATTERN) {
+		HIF_ERROR("%s memory size = %d\n", fw_ram_seg_name[i],
+				(sc->ramdump[i])->length);
+		if (i == (FW_RAM_SEG_CNT - 1))
+			QDF_BUG(0);
+
+		sc->ramdump_index++;
+		sc->fw_ram_dumping = 0;
+	}
+}
+
+/**
+ * hif_ramdump_handler(): dump bus debug registers
+ * @scn: struct hif_opaque_softc
+ *
+ * This function is to receive information of firmware crash dump, and
+ * save it in host memory. It consists of 5 parts: registers, call stack,
+ * DRAM dump, IRAM dump, and AXI dump, and they are reported to host in order.
+ *
+ * registers: wrapped in a USB packet by starting as FW_ASSERT_PATTERN and
+ *            60 registers.
+ * call stack: wrapped in multiple USB packets, and each of them starts as
+ *             FW_REG_PATTERN and contains multiple double-words. The tail
+ *             of the last packet is FW_REG_END_PATTERN.
+ * DRAM dump: wrapped in multiple USB pakcets, and each of them start as
+ *            FW_RAMDUMP_PATTERN and contains multiple double-wors. The tail
+ *            of the last packet is FW_RAMDUMP_END_PATTERN;
+ * IRAM dump and AXI dump are with the same format as DRAM dump.
+ *
+ * Return: 0 for success or error code
+ */
+
+void hif_ramdump_handler(struct hif_opaque_softc *scn)
+{
+	uint32_t *reg, pattern, i, start_addr = 0;
+	uint32_t len;
+	uint8_t *data;
+	uint8_t str_buf[128];
+	uint32_t remaining;
+	struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(scn);
+	struct hif_softc *hif_ctx = HIF_GET_SOFTC(scn);
+	struct hif_target_info *tgt_info = &hif_ctx->target_info;
+
+	data = sc->fw_data;
+	len = sc->fw_data_len;
+	pattern = *((A_UINT32 *) data);
+
+	if (pattern == FW_ASSERT_PATTERN) {
+		HIF_ERROR("Firmware crash detected...\n");
+		HIF_ERROR("Host SW version: %s\n", QWLAN_VERSIONSTR);
+		HIF_ERROR("target_type: %d.target_version %d. target_revision%d.",
+			tgt_info->target_type,
+			tgt_info->target_version,
+			tgt_info->target_revision);
+
+		reg = (uint32_t *) (data + 4);
+		print_hex_dump(KERN_DEBUG, " ", DUMP_PREFIX_OFFSET, 16, 4, reg,
+				min_t(A_UINT32, len - 4, FW_REG_DUMP_CNT * 4),
+				false);
+		sc->fw_ram_dumping = 0;
+
+	} else if (pattern == FW_REG_PATTERN) {
+		reg = (uint32_t *) (data + 4);
+		start_addr = *reg++;
+		if (sc->fw_ram_dumping == 0) {
+			pr_err("Firmware stack dump:");
+			sc->fw_ram_dumping = 1;
+			fw_stack_addr = start_addr;
+		}
+		remaining = len - 8;
+		/* len is in byte, but it's printed in double-word. */
+		for (i = 0; i < (len - 8); i += 16) {
+			if ((*reg == FW_REG_END_PATTERN) && (i == len - 12)) {
+				sc->fw_ram_dumping = 0;
+				pr_err("Stack start address = %#08x\n",
+					fw_stack_addr);
+				break;
+			}
+			hex_dump_to_buffer(reg, remaining, 16, 4, str_buf,
+						sizeof(str_buf), false);
+			pr_err("%#08x: %s\n", start_addr + i, str_buf);
+			remaining -= 16;
+			reg += 4;
+		}
+	} else if ((!sc->enable_self_recovery) &&
+			((pattern & FW_RAMDUMP_PATTERN_MASK) ==
+						FW_RAMDUMP_PATTERN)) {
+		hif_fw_assert_ramdump_pattern(sc);
+	}
+}
+
+#ifndef QCA_WIFI_3_0
+/**
+ * hif_check_fw_reg(): hif_check_fw_reg
+ * @scn: scn
+ * @state:
+ *
+ * Return: int
+ */
+int hif_check_fw_reg(struct hif_opaque_softc *scn)
+{
+	return 0;
+}
+#endif
+

+ 160 - 0
hif/src/usb/if_usb.h

@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+#ifndef __ATH_USB_H__
+#define __ATH_USB_H__
+
+#include <linux/reboot.h>
+
+/*
+ * There may be some pending tx frames during platform suspend.
+ * Suspend operation should be delayed until those tx frames are
+ * transfered from the host to target. This macro specifies how
+ * long suspend thread has to sleep before checking pending tx
+ * frame count.
+ */
+#define OL_ATH_TX_DRAIN_WAIT_DELAY     50	/* ms */
+/*
+ * Wait time (in unit of OL_ATH_TX_DRAIN_WAIT_DELAY) for pending
+ * tx frame completion before suspend. Refer: hif_pci_suspend()
+ */
+#define OL_ATH_TX_DRAIN_WAIT_CNT       10
+
+#define CONFIG_COPY_ENGINE_SUPPORT	/* TBDXXX: here for now */
+#define ATH_DBG_DEFAULT   0
+#include <osdep.h>
+#include <ol_if_athvar.h>
+#include <athdefs.h>
+#include "osapi_linux.h"
+#include "hif_main.h"
+#include "hif.h"
+
+#define FW_REG_DUMP_CNT       60
+
+/* Magic patterns for FW to report crash information (Rome USB) */
+#define FW_ASSERT_PATTERN       0x0000c600
+#define FW_REG_PATTERN          0x0000d600
+#define FW_REG_END_PATTERN      0x0000e600
+#define FW_RAMDUMP_PATTERN      0x0000f600
+#define FW_RAMDUMP_END_PATTERN  0x0000f601
+#define FW_RAMDUMP_PATTERN_MASK 0xfffffff0
+
+/* FW RAM segments (Rome USB) */
+enum {
+	FW_RAM_SEG_DRAM,
+	FW_RAM_SEG_IRAM,
+	FW_RAM_SEG_AXI,
+	FW_RAM_SEG_CNT
+};
+
+/* Allocate 384K memory to save each segment of ram dump */
+#define FW_RAMDUMP_SEG_SIZE     393216
+
+/* structure to save RAM dump information */
+struct fw_ramdump {
+	uint32_t start_addr;
+	uint32_t length;
+	uint8_t *mem;
+};
+
+/* USB Endpoint definition */
+typedef enum {
+	HIF_TX_CTRL_PIPE = 0,
+	HIF_TX_DATA_LP_PIPE,
+	HIF_TX_DATA_MP_PIPE,
+	HIF_TX_DATA_HP_PIPE,
+	HIF_RX_CTRL_PIPE,
+	HIF_RX_DATA_PIPE,
+	HIF_RX_DATA2_PIPE,
+	HIF_RX_INT_PIPE,
+	HIF_USB_PIPE_MAX
+} HIF_USB_PIPE_ID;
+
+#define HIF_USB_PIPE_INVALID HIF_USB_PIPE_MAX
+
+typedef struct _HIF_USB_PIPE {
+	DL_LIST urb_list_head;
+	DL_LIST urb_pending_list;
+	int32_t urb_alloc;
+	int32_t urb_cnt;
+	int32_t urb_cnt_thresh;
+	unsigned int usb_pipe_handle;
+	uint32_t flags;
+	uint8_t ep_address;
+	uint8_t logical_pipe_num;
+	struct _HIF_DEVICE_USB *device;
+	uint16_t max_packet_size;
+#ifdef HIF_USB_TASKLET
+	struct tasklet_struct io_complete_tasklet;
+#else
+	struct work_struct io_complete_work;
+#endif
+	struct sk_buff_head io_comp_queue;
+	struct usb_endpoint_descriptor *ep_desc;
+	int32_t urb_prestart_cnt;
+} HIF_USB_PIPE;
+
+typedef struct _HIF_DEVICE_USB {
+	struct hif_softc ol_sc;
+	qdf_spinlock_t cs_lock;
+	qdf_spinlock_t tx_lock;
+	qdf_spinlock_t rx_lock;
+	struct hif_msg_callbacks htc_callbacks;
+	struct usb_device *udev;
+	struct usb_interface *interface;
+	HIF_USB_PIPE pipes[HIF_USB_PIPE_MAX];
+	uint8_t *diag_cmd_buffer;
+	uint8_t *diag_resp_buffer;
+	void *claimed_context;
+	A_BOOL is_bundle_enabled;
+	uint16_t rx_bundle_cnt;
+	uint32_t rx_bundle_buf_len;
+} HIF_DEVICE_USB;
+
+
+struct hif_usb_softc {
+	struct _HIF_DEVICE_USB hif_hdl;
+	/* For efficiency, should be first in struct */
+	struct device *dev;
+	struct usb_dev *pdev;
+	/*
+	 * Guard changes to Target HW state and to software
+	 * structures that track hardware state.
+	 */
+	u16 devid;
+	struct usb_interface *interface;
+	struct notifier_block reboot_notifier;  /* default mode before reboot */
+	u8 suspend_state;
+	u8 *fw_data;
+	u32 fw_data_len;
+	/* structure to save FW RAM dump (Rome USB) */
+	struct fw_ramdump *ramdump[FW_RAM_SEG_CNT];
+	uint8_t ramdump_index;
+	bool fw_ram_dumping;
+	/* enable FW self-recovery for Rome USB */
+	bool enable_self_recovery;
+};
+#endif /* __ATH_USB_H__ */

+ 70 - 0
hif/src/usb/regtable_usb.c

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include "bmi_msg.h"
+#include "targaddrs.h"
+#include "regtable_usb.h"
+#include "ar9888def.h"
+#include "ar6320def.h"
+#include "ar6320v2def.h"
+#include "hif_debug.h"
+
+void target_register_tbl_attach(struct hif_softc *scn,
+					uint32_t target_type)
+{
+	switch (target_type) {
+	case TARGET_TYPE_AR9888:
+		scn->targetdef = &ar9888_targetdef;
+		break;
+	case TARGET_TYPE_AR6320:
+		scn->targetdef = &ar6320_targetdef;
+		break;
+	case TARGET_TYPE_AR6320V2:
+		scn->targetdef = &ar6320v2_targetdef;
+		break;
+	default:
+		HIF_ERROR("%s: unknown target_type %u", __func__, target_type);
+		break;
+	}
+}
+void hif_register_tbl_attach(struct hif_softc *scn, uint32_t hif_type)
+{
+	switch (hif_type) {
+	case HIF_TYPE_AR9888:
+		scn->hostdef = &ar9888_hostdef;
+		break;
+	case HIF_TYPE_AR6320:
+		scn->hostdef = &ar6320_hostdef;
+		break;
+	case HIF_TYPE_AR6320V2:
+		scn->hostdef = &ar6320v2_hostdef;
+		break;
+	default:
+		HIF_ERROR("%s: unknown hif_type %u", __func__, hif_type);
+		break;
+	}
+}

+ 1295 - 0
hif/src/usb/regtable_usb.h

@@ -0,0 +1,1295 @@
+/*
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+#ifndef _REGTABLE_USB_H_
+#define _REGTABLE_USB_H_
+#include "if_usb.h"
+
+#define MISSING  0
+
+typedef struct targetdef_s {
+	u_int32_t d_RTC_SOC_BASE_ADDRESS;
+	u_int32_t d_RTC_WMAC_BASE_ADDRESS;
+	u_int32_t d_SYSTEM_SLEEP_OFFSET;
+	u_int32_t d_WLAN_SYSTEM_SLEEP_OFFSET;
+	u_int32_t d_WLAN_SYSTEM_SLEEP_DISABLE_LSB;
+	u_int32_t d_WLAN_SYSTEM_SLEEP_DISABLE_MASK;
+	u_int32_t d_CLOCK_CONTROL_OFFSET;
+	u_int32_t d_CLOCK_CONTROL_SI0_CLK_MASK;
+	u_int32_t d_RESET_CONTROL_OFFSET;
+	u_int32_t d_RESET_CONTROL_MBOX_RST_MASK;
+	u_int32_t d_RESET_CONTROL_SI0_RST_MASK;
+	u_int32_t d_WLAN_RESET_CONTROL_OFFSET;
+	u_int32_t d_WLAN_RESET_CONTROL_COLD_RST_MASK;
+	u_int32_t d_WLAN_RESET_CONTROL_WARM_RST_MASK;
+	u_int32_t d_GPIO_BASE_ADDRESS;
+	u_int32_t d_GPIO_PIN0_OFFSET;
+	u_int32_t d_GPIO_PIN1_OFFSET;
+	u_int32_t d_GPIO_PIN0_CONFIG_MASK;
+	u_int32_t d_GPIO_PIN1_CONFIG_MASK;
+	u_int32_t d_SI_CONFIG_BIDIR_OD_DATA_LSB;
+	u_int32_t d_SI_CONFIG_BIDIR_OD_DATA_MASK;
+	u_int32_t d_SI_CONFIG_I2C_LSB;
+	u_int32_t d_SI_CONFIG_I2C_MASK;
+	u_int32_t d_SI_CONFIG_POS_SAMPLE_LSB;
+	u_int32_t d_SI_CONFIG_POS_SAMPLE_MASK;
+	u_int32_t d_SI_CONFIG_INACTIVE_CLK_LSB;
+	u_int32_t d_SI_CONFIG_INACTIVE_CLK_MASK;
+	u_int32_t d_SI_CONFIG_INACTIVE_DATA_LSB;
+	u_int32_t d_SI_CONFIG_INACTIVE_DATA_MASK;
+	u_int32_t d_SI_CONFIG_DIVIDER_LSB;
+	u_int32_t d_SI_CONFIG_DIVIDER_MASK;
+	u_int32_t d_SI_BASE_ADDRESS;
+	u_int32_t d_SI_CONFIG_OFFSET;
+	u_int32_t d_SI_TX_DATA0_OFFSET;
+	u_int32_t d_SI_TX_DATA1_OFFSET;
+	u_int32_t d_SI_RX_DATA0_OFFSET;
+	u_int32_t d_SI_RX_DATA1_OFFSET;
+	u_int32_t d_SI_CS_OFFSET;
+	u_int32_t d_SI_CS_DONE_ERR_MASK;
+	u_int32_t d_SI_CS_DONE_INT_MASK;
+	u_int32_t d_SI_CS_START_LSB;
+	u_int32_t d_SI_CS_START_MASK;
+	u_int32_t d_SI_CS_RX_CNT_LSB;
+	u_int32_t d_SI_CS_RX_CNT_MASK;
+	u_int32_t d_SI_CS_TX_CNT_LSB;
+	u_int32_t d_SI_CS_TX_CNT_MASK;
+	u_int32_t d_BOARD_DATA_SZ;
+	u_int32_t d_BOARD_EXT_DATA_SZ;
+	u_int32_t d_MBOX_BASE_ADDRESS;
+	u_int32_t d_LOCAL_SCRATCH_OFFSET;
+	u_int32_t d_CPU_CLOCK_OFFSET;
+	u_int32_t d_LPO_CAL_OFFSET;
+	u_int32_t d_GPIO_PIN10_OFFSET;
+	u_int32_t d_GPIO_PIN11_OFFSET;
+	u_int32_t d_GPIO_PIN12_OFFSET;
+	u_int32_t d_GPIO_PIN13_OFFSET;
+	u_int32_t d_CLOCK_GPIO_OFFSET;
+	u_int32_t d_CPU_CLOCK_STANDARD_LSB;
+	u_int32_t d_CPU_CLOCK_STANDARD_MASK;
+	u_int32_t d_LPO_CAL_ENABLE_LSB;
+	u_int32_t d_LPO_CAL_ENABLE_MASK;
+	u_int32_t d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB;
+	u_int32_t d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK;
+	u_int32_t d_ANALOG_INTF_BASE_ADDRESS;
+	u_int32_t d_WLAN_MAC_BASE_ADDRESS;
+	u_int32_t d_CE0_BASE_ADDRESS;
+	u_int32_t d_CE1_BASE_ADDRESS;
+	u_int32_t d_FW_INDICATOR_ADDRESS;
+	u_int32_t d_DRAM_BASE_ADDRESS;
+	u_int32_t d_SOC_CORE_BASE_ADDRESS;
+	u_int32_t d_CORE_CTRL_ADDRESS;
+	u_int32_t d_CE_COUNT;
+	u_int32_t d_MSI_NUM_REQUEST;
+	u_int32_t d_MSI_ASSIGN_FW;
+	u_int32_t d_MSI_ASSIGN_CE_INITIAL;
+	u_int32_t d_PCIE_INTR_ENABLE_ADDRESS;
+	u_int32_t d_PCIE_INTR_CLR_ADDRESS;
+	u_int32_t d_PCIE_INTR_FIRMWARE_MASK;
+	u_int32_t d_PCIE_INTR_CE_MASK_ALL;
+	u_int32_t d_CORE_CTRL_CPU_INTR_MASK;
+	u_int32_t d_SR_WR_INDEX_ADDRESS;
+	u_int32_t d_DST_WATERMARK_ADDRESS;
+
+	/* htt_rx.c */
+	u_int32_t d_RX_MSDU_END_4_FIRST_MSDU_MASK;
+	u_int32_t d_RX_MSDU_END_4_FIRST_MSDU_LSB;
+	uint32_t d_RX_MPDU_START_0_RETRY_LSB;
+	uint32_t d_RX_MPDU_START_0_RETRY_MASK;
+	u_int32_t d_RX_MPDU_START_0_SEQ_NUM_MASK;
+	u_int32_t d_RX_MPDU_START_0_SEQ_NUM_LSB;
+	u_int32_t d_RX_MPDU_START_2_PN_47_32_LSB;
+	u_int32_t d_RX_MPDU_START_2_PN_47_32_MASK;
+	uint32_t d_RX_MPDU_START_2_TID_LSB;
+	uint32_t d_RX_MPDU_START_2_TID_MASK;
+	u_int32_t d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK;
+	u_int32_t d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB;
+	u_int32_t d_RX_MSDU_END_1_KEY_ID_OCT_MASK;
+	u_int32_t d_RX_MSDU_END_1_KEY_ID_OCT_LSB;
+	u_int32_t d_RX_MSDU_END_4_LAST_MSDU_MASK;
+	u_int32_t d_RX_MSDU_END_4_LAST_MSDU_LSB;
+	u_int32_t d_RX_ATTENTION_0_MCAST_BCAST_MASK;
+	u_int32_t d_RX_ATTENTION_0_MCAST_BCAST_LSB;
+	u_int32_t d_RX_ATTENTION_0_FRAGMENT_MASK;
+	u_int32_t d_RX_ATTENTION_0_FRAGMENT_LSB;
+	u_int32_t d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK;
+	u_int32_t d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK;
+	u_int32_t d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB;
+	u_int32_t d_RX_MSDU_START_0_MSDU_LENGTH_MASK;
+	u_int32_t d_RX_MSDU_START_0_MSDU_LENGTH_LSB;
+	u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET;
+	u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_MASK;
+	u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_LSB;
+	u_int32_t d_RX_MPDU_START_0_ENCRYPTED_MASK;
+	u_int32_t d_RX_MPDU_START_0_ENCRYPTED_LSB;
+	u_int32_t d_RX_ATTENTION_0_MORE_DATA_MASK;
+	u_int32_t d_RX_ATTENTION_0_MSDU_DONE_MASK;
+	u_int32_t d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK;
+	/* end */
+	/* copy_engine.c */
+	u_int32_t d_DST_WR_INDEX_ADDRESS;
+	u_int32_t d_SRC_WATERMARK_ADDRESS;
+	u_int32_t d_SRC_WATERMARK_LOW_MASK;
+	u_int32_t d_SRC_WATERMARK_HIGH_MASK;
+	u_int32_t d_DST_WATERMARK_LOW_MASK;
+	u_int32_t d_DST_WATERMARK_HIGH_MASK;
+	u_int32_t d_CURRENT_SRRI_ADDRESS;
+	u_int32_t d_CURRENT_DRRI_ADDRESS;
+	u_int32_t d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK;
+	u_int32_t d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK;
+	u_int32_t d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK;
+	u_int32_t d_HOST_IS_DST_RING_LOW_WATERMARK_MASK;
+	u_int32_t d_HOST_IS_ADDRESS;
+	u_int32_t d_HOST_IS_COPY_COMPLETE_MASK;
+	u_int32_t d_CE_WRAPPER_BASE_ADDRESS;
+	u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS;
+	u_int32_t d_HOST_IE_ADDRESS;
+	u_int32_t d_HOST_IE_COPY_COMPLETE_MASK;
+	u_int32_t d_SR_BA_ADDRESS;
+	u_int32_t d_SR_SIZE_ADDRESS;
+	u_int32_t d_CE_CTRL1_ADDRESS;
+	u_int32_t d_CE_CTRL1_DMAX_LENGTH_MASK;
+	u_int32_t d_DR_BA_ADDRESS;
+	u_int32_t d_DR_SIZE_ADDRESS;
+	u_int32_t d_MISC_IE_ADDRESS;
+	u_int32_t d_MISC_IS_AXI_ERR_MASK;
+	u_int32_t d_MISC_IS_DST_ADDR_ERR_MASK;
+	u_int32_t d_MISC_IS_SRC_LEN_ERR_MASK;
+	u_int32_t d_MISC_IS_DST_MAX_LEN_VIO_MASK;
+	u_int32_t d_MISC_IS_DST_RING_OVERFLOW_MASK;
+	u_int32_t d_MISC_IS_SRC_RING_OVERFLOW_MASK;
+	u_int32_t d_SRC_WATERMARK_LOW_LSB;
+	u_int32_t d_SRC_WATERMARK_HIGH_LSB;
+	u_int32_t d_DST_WATERMARK_LOW_LSB;
+	u_int32_t d_DST_WATERMARK_HIGH_LSB;
+	u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK;
+	u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB;
+	u_int32_t d_CE_CTRL1_DMAX_LENGTH_LSB;
+	u_int32_t d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK;
+	u_int32_t d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK;
+	u_int32_t d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB;
+	u_int32_t d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB;
+	u_int32_t d_WLAN_DEBUG_INPUT_SEL_OFFSET;
+	u_int32_t d_WLAN_DEBUG_INPUT_SEL_SRC_MSB;
+	u_int32_t d_WLAN_DEBUG_INPUT_SEL_SRC_LSB;
+	u_int32_t d_WLAN_DEBUG_INPUT_SEL_SRC_MASK;
+	u_int32_t d_WLAN_DEBUG_CONTROL_OFFSET;
+	u_int32_t d_WLAN_DEBUG_CONTROL_ENABLE_MSB;
+	u_int32_t d_WLAN_DEBUG_CONTROL_ENABLE_LSB;
+	u_int32_t d_WLAN_DEBUG_CONTROL_ENABLE_MASK;
+	u_int32_t d_WLAN_DEBUG_OUT_OFFSET;
+	u_int32_t d_WLAN_DEBUG_OUT_DATA_MSB;
+	u_int32_t d_WLAN_DEBUG_OUT_DATA_LSB;
+	u_int32_t d_WLAN_DEBUG_OUT_DATA_MASK;
+	u_int32_t d_AMBA_DEBUG_BUS_OFFSET;
+	u_int32_t d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB;
+	u_int32_t d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB;
+	u_int32_t d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK;
+	u_int32_t d_AMBA_DEBUG_BUS_SEL_MSB;
+	u_int32_t d_AMBA_DEBUG_BUS_SEL_LSB;
+	u_int32_t d_AMBA_DEBUG_BUS_SEL_MASK;
+	u_int32_t d_CE_WRAPPER_DEBUG_OFFSET;
+	u_int32_t d_CE_WRAPPER_DEBUG_SEL_MSB;
+	u_int32_t d_CE_WRAPPER_DEBUG_SEL_LSB;
+	u_int32_t d_CE_WRAPPER_DEBUG_SEL_MASK;
+	u_int32_t d_CE_DEBUG_OFFSET;
+	u_int32_t d_CE_DEBUG_SEL_MSB;
+	u_int32_t d_CE_DEBUG_SEL_LSB;
+	u_int32_t d_CE_DEBUG_SEL_MASK;
+	/* end */
+	/* PLL start */
+	u_int32_t d_EFUSE_OFFSET;
+	u_int32_t d_EFUSE_XTAL_SEL_MSB;
+	u_int32_t d_EFUSE_XTAL_SEL_LSB;
+	u_int32_t d_EFUSE_XTAL_SEL_MASK;
+	u_int32_t d_BB_PLL_CONFIG_OFFSET;
+	u_int32_t d_BB_PLL_CONFIG_OUTDIV_MSB;
+	u_int32_t d_BB_PLL_CONFIG_OUTDIV_LSB;
+	u_int32_t d_BB_PLL_CONFIG_OUTDIV_MASK;
+	u_int32_t d_BB_PLL_CONFIG_FRAC_MSB;
+	u_int32_t d_BB_PLL_CONFIG_FRAC_LSB;
+	u_int32_t d_BB_PLL_CONFIG_FRAC_MASK;
+	u_int32_t d_WLAN_PLL_SETTLE_TIME_MSB;
+	u_int32_t d_WLAN_PLL_SETTLE_TIME_LSB;
+	u_int32_t d_WLAN_PLL_SETTLE_TIME_MASK;
+	u_int32_t d_WLAN_PLL_SETTLE_OFFSET;
+	u_int32_t d_WLAN_PLL_SETTLE_SW_MASK;
+	u_int32_t d_WLAN_PLL_SETTLE_RSTMASK;
+	u_int32_t d_WLAN_PLL_SETTLE_RESET;
+	u_int32_t d_WLAN_PLL_CONTROL_NOPWD_MSB;
+	u_int32_t d_WLAN_PLL_CONTROL_NOPWD_LSB;
+	u_int32_t d_WLAN_PLL_CONTROL_NOPWD_MASK;
+	u_int32_t d_WLAN_PLL_CONTROL_BYPASS_MSB;
+	u_int32_t d_WLAN_PLL_CONTROL_BYPASS_LSB;
+	u_int32_t d_WLAN_PLL_CONTROL_BYPASS_MASK;
+	u_int32_t d_WLAN_PLL_CONTROL_BYPASS_RESET;
+	u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_MSB;
+	u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_LSB;
+	u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_MASK;
+	u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_RESET;
+	u_int32_t d_WLAN_PLL_CONTROL_REFDIV_MSB;
+	u_int32_t d_WLAN_PLL_CONTROL_REFDIV_LSB;
+	u_int32_t d_WLAN_PLL_CONTROL_REFDIV_MASK;
+	u_int32_t d_WLAN_PLL_CONTROL_REFDIV_RESET;
+	u_int32_t d_WLAN_PLL_CONTROL_DIV_MSB;
+	u_int32_t d_WLAN_PLL_CONTROL_DIV_LSB;
+	u_int32_t d_WLAN_PLL_CONTROL_DIV_MASK;
+	u_int32_t d_WLAN_PLL_CONTROL_DIV_RESET;
+	u_int32_t d_WLAN_PLL_CONTROL_OFFSET;
+	u_int32_t d_WLAN_PLL_CONTROL_SW_MASK;
+	u_int32_t d_WLAN_PLL_CONTROL_RSTMASK;
+	u_int32_t d_WLAN_PLL_CONTROL_RESET;
+	u_int32_t d_SOC_CORE_CLK_CTRL_OFFSET;
+	u_int32_t d_SOC_CORE_CLK_CTRL_DIV_MSB;
+	u_int32_t d_SOC_CORE_CLK_CTRL_DIV_LSB;
+	u_int32_t d_SOC_CORE_CLK_CTRL_DIV_MASK;
+	u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_MSB;
+	u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_LSB;
+	u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_MASK;
+	u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_RESET;
+	u_int32_t d_RTC_SYNC_STATUS_OFFSET;
+	u_int32_t d_SOC_CPU_CLOCK_OFFSET;
+	u_int32_t d_SOC_CPU_CLOCK_STANDARD_MSB;
+	u_int32_t d_SOC_CPU_CLOCK_STANDARD_LSB;
+	u_int32_t d_SOC_CPU_CLOCK_STANDARD_MASK;
+	/* PLL end */
+	u_int32_t d_SOC_POWER_REG_OFFSET;
+	u_int32_t d_PCIE_INTR_CAUSE_ADDRESS;
+	u_int32_t d_SOC_RESET_CONTROL_ADDRESS;
+	u_int32_t d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK;
+	u_int32_t d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB;
+	u_int32_t d_SOC_RESET_CONTROL_CE_RST_MASK;
+	u_int32_t d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK;
+	u_int32_t d_CPU_INTR_ADDRESS;
+	u_int32_t d_SOC_LF_TIMER_CONTROL0_ADDRESS;
+	u_int32_t d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK;
+	/* chip id start */
+	u_int32_t d_SOC_CHIP_ID_ADDRESS;
+	u_int32_t d_SOC_CHIP_ID_VERSION_MASK;
+	u_int32_t d_SOC_CHIP_ID_VERSION_LSB;
+	u_int32_t d_SOC_CHIP_ID_REVISION_MASK;
+	u_int32_t d_SOC_CHIP_ID_REVISION_LSB;
+	/* chip id end */
+} TARGET_REGISTER_TABLE;
+
+#define RTC_SOC_BASE_ADDRESS               \
+		(scn->targetdef->d_RTC_SOC_BASE_ADDRESS)
+#define RTC_WMAC_BASE_ADDRESS              \
+		(scn->targetdef->d_RTC_WMAC_BASE_ADDRESS)
+#define SYSTEM_SLEEP_OFFSET                \
+		(scn->targetdef->d_SYSTEM_SLEEP_OFFSET)
+#define WLAN_SYSTEM_SLEEP_OFFSET           \
+		(scn->targetdef->d_WLAN_SYSTEM_SLEEP_OFFSET)
+#define WLAN_SYSTEM_SLEEP_DISABLE_LSB      \
+		(scn->targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_LSB)
+#define WLAN_SYSTEM_SLEEP_DISABLE_MASK     \
+		(scn->targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_MASK)
+#define CLOCK_CONTROL_OFFSET               \
+		(scn->targetdef->d_CLOCK_CONTROL_OFFSET)
+#define CLOCK_CONTROL_SI0_CLK_MASK         \
+		(scn->targetdef->d_CLOCK_CONTROL_SI0_CLK_MASK)
+#define RESET_CONTROL_OFFSET               \
+		(scn->targetdef->d_RESET_CONTROL_OFFSET)
+#define RESET_CONTROL_MBOX_RST_MASK        \
+		(scn->targetdef->d_RESET_CONTROL_MBOX_RST_MASK)
+#define RESET_CONTROL_SI0_RST_MASK         \
+		(scn->targetdef->d_RESET_CONTROL_SI0_RST_MASK)
+#define WLAN_RESET_CONTROL_OFFSET          \
+		(scn->targetdef->d_WLAN_RESET_CONTROL_OFFSET)
+#define WLAN_RESET_CONTROL_COLD_RST_MASK   \
+		(scn->targetdef->d_WLAN_RESET_CONTROL_COLD_RST_MASK)
+#define WLAN_RESET_CONTROL_WARM_RST_MASK   \
+		(scn->targetdef->d_WLAN_RESET_CONTROL_WARM_RST_MASK)
+#define GPIO_BASE_ADDRESS                  \
+		(scn->targetdef->d_GPIO_BASE_ADDRESS)
+#define GPIO_PIN0_OFFSET                   \
+		(scn->targetdef->d_GPIO_PIN0_OFFSET)
+#define GPIO_PIN1_OFFSET                   \
+		(scn->targetdef->d_GPIO_PIN1_OFFSET)
+#define GPIO_PIN0_CONFIG_MASK              \
+		(scn->targetdef->d_GPIO_PIN0_CONFIG_MASK)
+#define GPIO_PIN1_CONFIG_MASK              \
+		(scn->targetdef->d_GPIO_PIN1_CONFIG_MASK)
+#define SI_CONFIG_BIDIR_OD_DATA_LSB        \
+		(scn->targetdef->d_SI_CONFIG_BIDIR_OD_DATA_LSB)
+#define SI_CONFIG_BIDIR_OD_DATA_MASK       \
+		(scn->targetdef->d_SI_CONFIG_BIDIR_OD_DATA_MASK)
+#define SI_CONFIG_I2C_LSB                  \
+		(scn->targetdef->d_SI_CONFIG_I2C_LSB)
+#define SI_CONFIG_I2C_MASK                 \
+		(scn->targetdef->d_SI_CONFIG_I2C_MASK)
+#define SI_CONFIG_POS_SAMPLE_LSB           \
+		(scn->targetdef->d_SI_CONFIG_POS_SAMPLE_LSB)
+#define SI_CONFIG_POS_SAMPLE_MASK          \
+		(scn->targetdef->d_SI_CONFIG_POS_SAMPLE_MASK)
+#define SI_CONFIG_INACTIVE_CLK_LSB         \
+		(scn->targetdef->d_SI_CONFIG_INACTIVE_CLK_LSB)
+#define SI_CONFIG_INACTIVE_CLK_MASK        \
+		(scn->targetdef->d_SI_CONFIG_INACTIVE_CLK_MASK)
+#define SI_CONFIG_INACTIVE_DATA_LSB        \
+		(scn->targetdef->d_SI_CONFIG_INACTIVE_DATA_LSB)
+#define SI_CONFIG_INACTIVE_DATA_MASK       \
+		(scn->targetdef->d_SI_CONFIG_INACTIVE_DATA_MASK)
+#define SI_CONFIG_DIVIDER_LSB              \
+		(scn->targetdef->d_SI_CONFIG_DIVIDER_LSB)
+#define SI_CONFIG_DIVIDER_MASK             \
+		(scn->targetdef->d_SI_CONFIG_DIVIDER_MASK)
+#define SI_BASE_ADDRESS                    \
+		(scn->targetdef->d_SI_BASE_ADDRESS)
+#define SI_CONFIG_OFFSET                   \
+		(scn->targetdef->d_SI_CONFIG_OFFSET)
+#define SI_TX_DATA0_OFFSET                 \
+		(scn->targetdef->d_SI_TX_DATA0_OFFSET)
+#define SI_TX_DATA1_OFFSET                 \
+		(scn->targetdef->d_SI_TX_DATA1_OFFSET)
+#define SI_RX_DATA0_OFFSET                 \
+		(scn->targetdef->d_SI_RX_DATA0_OFFSET)
+#define SI_RX_DATA1_OFFSET                 \
+		(scn->targetdef->d_SI_RX_DATA1_OFFSET)
+#define SI_CS_OFFSET                       \
+		(scn->targetdef->d_SI_CS_OFFSET)
+#define SI_CS_DONE_ERR_MASK                \
+		(scn->targetdef->d_SI_CS_DONE_ERR_MASK)
+#define SI_CS_DONE_INT_MASK                \
+		(scn->targetdef->d_SI_CS_DONE_INT_MASK)
+#define SI_CS_START_LSB                    \
+		(scn->targetdef->d_SI_CS_START_LSB)
+#define SI_CS_START_MASK                   \
+		(scn->targetdef->d_SI_CS_START_MASK)
+#define SI_CS_RX_CNT_LSB                   \
+		(scn->targetdef->d_SI_CS_RX_CNT_LSB)
+#define SI_CS_RX_CNT_MASK                  \
+		(scn->targetdef->d_SI_CS_RX_CNT_MASK)
+#define SI_CS_TX_CNT_LSB                   \
+		(scn->targetdef->d_SI_CS_TX_CNT_LSB)
+#define SI_CS_TX_CNT_MASK                  \
+		(scn->targetdef->d_SI_CS_TX_CNT_MASK)
+#define EEPROM_SZ                          \
+		(scn->targetdef->d_BOARD_DATA_SZ)
+#define EEPROM_EXT_SZ                      \
+		(scn->targetdef->d_BOARD_EXT_DATA_SZ)
+#define MBOX_BASE_ADDRESS                  \
+		(scn->targetdef->d_MBOX_BASE_ADDRESS)
+#define LOCAL_SCRATCH_OFFSET               \
+		(scn->targetdef->d_LOCAL_SCRATCH_OFFSET)
+#define CPU_CLOCK_OFFSET                   \
+		(scn->targetdef->d_CPU_CLOCK_OFFSET)
+#define LPO_CAL_OFFSET                     \
+		(scn->targetdef->d_LPO_CAL_OFFSET)
+#define GPIO_PIN10_OFFSET                  \
+		(scn->targetdef->d_GPIO_PIN10_OFFSET)
+#define GPIO_PIN11_OFFSET                  \
+		(scn->targetdef->d_GPIO_PIN11_OFFSET)
+#define GPIO_PIN12_OFFSET                  \
+		(scn->targetdef->d_GPIO_PIN12_OFFSET)
+#define GPIO_PIN13_OFFSET                  \
+		(scn->targetdef->d_GPIO_PIN13_OFFSET)
+#define CLOCK_GPIO_OFFSET                  \
+		(scn->targetdef->d_CLOCK_GPIO_OFFSET)
+#define CPU_CLOCK_STANDARD_LSB             \
+		(scn->targetdef->d_CPU_CLOCK_STANDARD_LSB)
+#define CPU_CLOCK_STANDARD_MASK            \
+		(scn->targetdef->d_CPU_CLOCK_STANDARD_MASK)
+#define LPO_CAL_ENABLE_LSB                 \
+		(scn->targetdef->d_LPO_CAL_ENABLE_LSB)
+#define LPO_CAL_ENABLE_MASK                \
+		(scn->targetdef->d_LPO_CAL_ENABLE_MASK)
+#define CLOCK_GPIO_BT_CLK_OUT_EN_LSB       \
+		(scn->targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB)
+#define CLOCK_GPIO_BT_CLK_OUT_EN_MASK      \
+		(scn->targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK)
+#define ANALOG_INTF_BASE_ADDRESS           \
+		(scn->targetdef->d_ANALOG_INTF_BASE_ADDRESS)
+#define WLAN_MAC_BASE_ADDRESS              \
+		(scn->targetdef->d_WLAN_MAC_BASE_ADDRESS)
+#define CE0_BASE_ADDRESS                   \
+		(scn->targetdef->d_CE0_BASE_ADDRESS)
+#define CE1_BASE_ADDRESS                   \
+		(scn->targetdef->d_CE1_BASE_ADDRESS)
+#define FW_INDICATOR_ADDRESS               \
+		(scn->targetdef->d_FW_INDICATOR_ADDRESS)
+#define DRAM_BASE_ADDRESS                  \
+		(scn->targetdef->d_DRAM_BASE_ADDRESS)
+#define SOC_CORE_BASE_ADDRESS              \
+		(scn->targetdef->d_SOC_CORE_BASE_ADDRESS)
+#define CORE_CTRL_ADDRESS                  \
+		(scn->targetdef->d_CORE_CTRL_ADDRESS)
+#define CE_COUNT                           \
+		(scn->targetdef->d_CE_COUNT)
+#define PCIE_INTR_ENABLE_ADDRESS           \
+		(scn->targetdef->d_PCIE_INTR_ENABLE_ADDRESS)
+#define PCIE_INTR_CLR_ADDRESS              \
+		(scn->targetdef->d_PCIE_INTR_CLR_ADDRESS)
+#define PCIE_INTR_FIRMWARE_MASK            \
+		(scn->targetdef->d_PCIE_INTR_FIRMWARE_MASK)
+#define PCIE_INTR_CE_MASK_ALL              \
+		(scn->targetdef->d_PCIE_INTR_CE_MASK_ALL)
+#define CORE_CTRL_CPU_INTR_MASK            \
+		(scn->targetdef->d_CORE_CTRL_CPU_INTR_MASK)
+#define PCIE_INTR_CAUSE_ADDRESS            \
+		(scn->targetdef->d_PCIE_INTR_CAUSE_ADDRESS)
+#define SOC_RESET_CONTROL_ADDRESS          \
+		(scn->targetdef->d_SOC_RESET_CONTROL_ADDRESS)
+#define SOC_RESET_CONTROL_CE_RST_MASK      \
+		(scn->targetdef->d_SOC_RESET_CONTROL_CE_RST_MASK)
+#define SOC_RESET_CONTROL_CPU_WARM_RST_MASK\
+		(scn->targetdef->d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK)
+#define CPU_INTR_ADDRESS                   \
+		(scn->targetdef->d_CPU_INTR_ADDRESS)
+#define SOC_LF_TIMER_CONTROL0_ADDRESS      \
+		(scn->targetdef->d_SOC_LF_TIMER_CONTROL0_ADDRESS)
+#define SOC_LF_TIMER_CONTROL0_ENABLE_MASK  \
+		(scn->targetdef->d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK)
+#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB \
+		(scn->targetdef->d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB)
+#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK \
+		(scn->targetdef->d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK)
+
+#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_GET(x) \
+	(((x) & SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) >> \
+		SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB)
+#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_SET(x) \
+	(((x) << SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) & \
+			SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK)
+
+/* hif_pci.c */
+#define CHIP_ID_ADDRESS                    \
+		(scn->targetdef->d_SOC_CHIP_ID_ADDRESS)
+#define SOC_CHIP_ID_REVISION_MASK          \
+		(scn->targetdef->d_SOC_CHIP_ID_REVISION_MASK)
+#define SOC_CHIP_ID_REVISION_LSB           \
+		(scn->targetdef->d_SOC_CHIP_ID_REVISION_LSB)
+#define SOC_CHIP_ID_VERSION_MASK           \
+		(scn->targetdef->d_SOC_CHIP_ID_VERSION_MASK)
+#define SOC_CHIP_ID_VERSION_LSB            \
+		(scn->targetdef->d_SOC_CHIP_ID_VERSION_LSB)
+#define CHIP_ID_REVISION_GET(x) \
+		(((x) & SOC_CHIP_ID_REVISION_MASK) >> SOC_CHIP_ID_REVISION_LSB)
+#define CHIP_ID_VERSION_GET(x) \
+	(((x) & SOC_CHIP_ID_VERSION_MASK) >> SOC_CHIP_ID_VERSION_LSB)
+/* hif_pci.c end */
+
+/* misc */
+#define SR_WR_INDEX_ADDRESS                \
+		(scn->targetdef->d_SR_WR_INDEX_ADDRESS)
+#define DST_WATERMARK_ADDRESS              \
+		(scn->targetdef->d_DST_WATERMARK_ADDRESS)
+#define SOC_POWER_REG_OFFSET               \
+		(scn->targetdef->d_SOC_POWER_REG_OFFSET)
+/* end */
+
+/* htt_rx.c */
+#define RX_MSDU_END_4_FIRST_MSDU_MASK      \
+		(pdev->targetdef->d_RX_MSDU_END_4_FIRST_MSDU_MASK)
+#define RX_MSDU_END_4_FIRST_MSDU_LSB       \
+		(pdev->targetdef->d_RX_MSDU_END_4_FIRST_MSDU_LSB)
+#define RX_MPDU_START_0_RETRY_LSB  \
+		(pdev->targetdef->d_RX_MPDU_START_0_RETRY_LSB)
+#define RX_MPDU_START_0_RETRY_MASK  \
+		(pdev->targetdef->d_RX_MPDU_START_0_RETRY_MASK)
+#define RX_MPDU_START_0_SEQ_NUM_MASK       \
+		(pdev->targetdef->d_RX_MPDU_START_0_SEQ_NUM_MASK)
+#define RX_MPDU_START_0_SEQ_NUM_LSB        \
+		(pdev->targetdef->d_RX_MPDU_START_0_SEQ_NUM_LSB)
+#define RX_MPDU_START_2_PN_47_32_LSB       \
+		(pdev->targetdef->d_RX_MPDU_START_2_PN_47_32_LSB)
+#define RX_MPDU_START_2_PN_47_32_MASK      \
+		(pdev->targetdef->d_RX_MPDU_START_2_PN_47_32_MASK)
+#define RX_MPDU_START_2_TID_LSB  \
+		(pdev->targetdef->d_RX_MPDU_START_2_TID_LSB)
+#define RX_MPDU_START_2_TID_MASK  \
+		(pdev->targetdef->d_RX_MPDU_START_2_TID_MASK)
+#define RX_MSDU_END_1_KEY_ID_OCT_MASK      \
+		(pdev->targetdef->d_RX_MSDU_END_1_KEY_ID_OCT_MASK)
+#define RX_MSDU_END_1_KEY_ID_OCT_LSB       \
+		(pdev->targetdef->d_RX_MSDU_END_1_KEY_ID_OCT_LSB)
+#define RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK \
+		(pdev->targetdef->d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK)
+#define RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB\
+		(pdev->targetdef->d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB)
+#define RX_MSDU_END_4_LAST_MSDU_MASK       \
+		(pdev->targetdef->d_RX_MSDU_END_4_LAST_MSDU_MASK)
+#define RX_MSDU_END_4_LAST_MSDU_LSB        \
+		(pdev->targetdef->d_RX_MSDU_END_4_LAST_MSDU_LSB)
+#define RX_ATTENTION_0_MCAST_BCAST_MASK    \
+		(pdev->targetdef->d_RX_ATTENTION_0_MCAST_BCAST_MASK)
+#define RX_ATTENTION_0_MCAST_BCAST_LSB     \
+		(pdev->targetdef->d_RX_ATTENTION_0_MCAST_BCAST_LSB)
+#define RX_ATTENTION_0_FRAGMENT_MASK       \
+		(pdev->targetdef->d_RX_ATTENTION_0_FRAGMENT_MASK)
+#define RX_ATTENTION_0_FRAGMENT_LSB        \
+		(pdev->targetdef->d_RX_ATTENTION_0_FRAGMENT_LSB)
+#define RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK\
+		(pdev->targetdef->d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK)
+#define RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK \
+		(pdev->targetdef->d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK)
+#define RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB\
+		(pdev->targetdef->d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB)
+#define RX_MSDU_START_0_MSDU_LENGTH_MASK   \
+		(pdev->targetdef->d_RX_MSDU_START_0_MSDU_LENGTH_MASK)
+#define RX_MSDU_START_0_MSDU_LENGTH_LSB    \
+		(pdev->targetdef->d_RX_MSDU_START_0_MSDU_LENGTH_LSB)
+#define RX_MSDU_START_2_DECAP_FORMAT_OFFSET\
+		(pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET)
+#define RX_MSDU_START_2_DECAP_FORMAT_MASK  \
+		(pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_MASK)
+#define RX_MSDU_START_2_DECAP_FORMAT_LSB   \
+		(pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_LSB)
+#define RX_MPDU_START_0_ENCRYPTED_MASK     \
+		(pdev->targetdef->d_RX_MPDU_START_0_ENCRYPTED_MASK)
+#define RX_MPDU_START_0_ENCRYPTED_LSB      \
+		(pdev->targetdef->d_RX_MPDU_START_0_ENCRYPTED_LSB)
+#define RX_ATTENTION_0_MORE_DATA_MASK      \
+		(pdev->targetdef->d_RX_ATTENTION_0_MORE_DATA_MASK)
+#define RX_ATTENTION_0_MSDU_DONE_MASK      \
+		(pdev->targetdef->d_RX_ATTENTION_0_MSDU_DONE_MASK)
+#define RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK \
+		(pdev->targetdef->d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK)
+/* end */
+
+/* copy_engine.c */
+#define DST_WR_INDEX_ADDRESS               \
+		(scn->targetdef->d_DST_WR_INDEX_ADDRESS)
+#define SRC_WATERMARK_ADDRESS              \
+		(scn->targetdef->d_SRC_WATERMARK_ADDRESS)
+#define SRC_WATERMARK_LOW_MASK             \
+		(scn->targetdef->d_SRC_WATERMARK_LOW_MASK)
+#define SRC_WATERMARK_HIGH_MASK            \
+		(scn->targetdef->d_SRC_WATERMARK_HIGH_MASK)
+#define DST_WATERMARK_LOW_MASK             \
+		(scn->targetdef->d_DST_WATERMARK_LOW_MASK)
+#define DST_WATERMARK_HIGH_MASK            \
+		(scn->targetdef->d_DST_WATERMARK_HIGH_MASK)
+#define CURRENT_SRRI_ADDRESS               \
+		(scn->targetdef->d_CURRENT_SRRI_ADDRESS)
+#define CURRENT_DRRI_ADDRESS               \
+		(scn->targetdef->d_CURRENT_DRRI_ADDRESS)
+#define HOST_IS_SRC_RING_HIGH_WATERMARK_MASK \
+		(scn->targetdef->d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK)
+#define HOST_IS_SRC_RING_LOW_WATERMARK_MASK\
+		(scn->targetdef->d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK)
+#define HOST_IS_DST_RING_HIGH_WATERMARK_MASK \
+		(scn->targetdef->d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK)
+#define HOST_IS_DST_RING_LOW_WATERMARK_MASK\
+		(scn->targetdef->d_HOST_IS_DST_RING_LOW_WATERMARK_MASK)
+#define HOST_IS_ADDRESS                    \
+		(scn->targetdef->d_HOST_IS_ADDRESS)
+#define HOST_IS_COPY_COMPLETE_MASK         \
+		(scn->targetdef->d_HOST_IS_COPY_COMPLETE_MASK)
+#define CE_WRAPPER_BASE_ADDRESS            \
+		(scn->targetdef->d_CE_WRAPPER_BASE_ADDRESS)
+#define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS \
+		(scn->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS)
+#define HOST_IE_ADDRESS                    \
+		(scn->targetdef->d_HOST_IE_ADDRESS)
+#define HOST_IE_COPY_COMPLETE_MASK         \
+		(scn->targetdef->d_HOST_IE_COPY_COMPLETE_MASK)
+#define SR_BA_ADDRESS                      \
+		(scn->targetdef->d_SR_BA_ADDRESS)
+#define SR_SIZE_ADDRESS                    \
+		(scn->targetdef->d_SR_SIZE_ADDRESS)
+#define CE_CTRL1_ADDRESS                   \
+		(scn->targetdef->d_CE_CTRL1_ADDRESS)
+#define CE_CTRL1_DMAX_LENGTH_MASK          \
+		(scn->targetdef->d_CE_CTRL1_DMAX_LENGTH_MASK)
+#define DR_BA_ADDRESS                      \
+		(scn->targetdef->d_DR_BA_ADDRESS)
+#define DR_SIZE_ADDRESS                    \
+		(scn->targetdef->d_DR_SIZE_ADDRESS)
+#define MISC_IE_ADDRESS                    \
+		(scn->targetdef->d_MISC_IE_ADDRESS)
+#define MISC_IS_AXI_ERR_MASK               \
+		(scn->targetdef->d_MISC_IS_AXI_ERR_MASK)
+#define MISC_IS_DST_ADDR_ERR_MASK          \
+		(scn->targetdef->d_MISC_IS_DST_ADDR_ERR_MASK)
+#define MISC_IS_SRC_LEN_ERR_MASK           \
+		(scn->targetdef->d_MISC_IS_SRC_LEN_ERR_MASK)
+#define MISC_IS_DST_MAX_LEN_VIO_MASK       \
+		(scn->targetdef->d_MISC_IS_DST_MAX_LEN_VIO_MASK)
+#define MISC_IS_DST_RING_OVERFLOW_MASK     \
+		(scn->targetdef->d_MISC_IS_DST_RING_OVERFLOW_MASK)
+#define MISC_IS_SRC_RING_OVERFLOW_MASK     \
+		(scn->targetdef->d_MISC_IS_SRC_RING_OVERFLOW_MASK)
+#define SRC_WATERMARK_LOW_LSB              \
+		(scn->targetdef->d_SRC_WATERMARK_LOW_LSB)
+#define SRC_WATERMARK_HIGH_LSB             \
+		(scn->targetdef->d_SRC_WATERMARK_HIGH_LSB)
+#define DST_WATERMARK_LOW_LSB              \
+		(scn->targetdef->d_DST_WATERMARK_LOW_LSB)
+#define DST_WATERMARK_HIGH_LSB             \
+		(scn->targetdef->d_DST_WATERMARK_HIGH_LSB)
+#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK \
+		(scn->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK)
+#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB  \
+		(scn->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB)
+#define CE_CTRL1_DMAX_LENGTH_LSB           \
+		(scn->targetdef->d_CE_CTRL1_DMAX_LENGTH_LSB)
+#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK\
+		(scn->targetdef->d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK)
+#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK\
+		(scn->targetdef->d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK)
+#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB \
+		(scn->targetdef->d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB)
+#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB \
+		(scn->targetdef->d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB)
+#define WLAN_DEBUG_INPUT_SEL_OFFSET        \
+		(scn->targetdef->d_WLAN_DEBUG_INPUT_SEL_OFFSET)
+#define WLAN_DEBUG_INPUT_SEL_SRC_MSB       \
+		(scn->targetdef->d_WLAN_DEBUG_INPUT_SEL_SRC_MSB)
+#define WLAN_DEBUG_INPUT_SEL_SRC_LSB       \
+		(scn->targetdef->d_WLAN_DEBUG_INPUT_SEL_SRC_LSB)
+#define WLAN_DEBUG_INPUT_SEL_SRC_MASK      \
+		(scn->targetdef->d_WLAN_DEBUG_INPUT_SEL_SRC_MASK)
+#define WLAN_DEBUG_CONTROL_OFFSET          \
+		(scn->targetdef->d_WLAN_DEBUG_CONTROL_OFFSET)
+#define WLAN_DEBUG_CONTROL_ENABLE_MSB      \
+		(scn->targetdef->d_WLAN_DEBUG_CONTROL_ENABLE_MSB)
+#define WLAN_DEBUG_CONTROL_ENABLE_LSB      \
+		(scn->targetdef->d_WLAN_DEBUG_CONTROL_ENABLE_LSB)
+#define WLAN_DEBUG_CONTROL_ENABLE_MASK     \
+		(scn->targetdef->d_WLAN_DEBUG_CONTROL_ENABLE_MASK)
+#define WLAN_DEBUG_OUT_OFFSET              \
+		(scn->targetdef->d_WLAN_DEBUG_OUT_OFFSET)
+#define WLAN_DEBUG_OUT_DATA_MSB            \
+		(scn->targetdef->d_WLAN_DEBUG_OUT_DATA_MSB)
+#define WLAN_DEBUG_OUT_DATA_LSB            \
+		(scn->targetdef->d_WLAN_DEBUG_OUT_DATA_LSB)
+#define WLAN_DEBUG_OUT_DATA_MASK           \
+		(scn->targetdef->d_WLAN_DEBUG_OUT_DATA_MASK)
+#define AMBA_DEBUG_BUS_OFFSET              \
+		(scn->targetdef->d_AMBA_DEBUG_BUS_OFFSET)
+#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB  \
+		(scn->targetdef->d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB)
+#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB  \
+		(scn->targetdef->d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB)
+#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK \
+		(scn->targetdef->d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK)
+#define AMBA_DEBUG_BUS_SEL_MSB             \
+		(scn->targetdef->d_AMBA_DEBUG_BUS_SEL_MSB)
+#define AMBA_DEBUG_BUS_SEL_LSB             \
+		(scn->targetdef->d_AMBA_DEBUG_BUS_SEL_LSB)
+#define AMBA_DEBUG_BUS_SEL_MASK            \
+		(scn->targetdef->d_AMBA_DEBUG_BUS_SEL_MASK)
+#define CE_WRAPPER_DEBUG_OFFSET            \
+		(scn->targetdef->d_CE_WRAPPER_DEBUG_OFFSET)
+#define CE_WRAPPER_DEBUG_SEL_MSB           \
+		(scn->targetdef->d_CE_WRAPPER_DEBUG_SEL_MSB)
+#define CE_WRAPPER_DEBUG_SEL_LSB           \
+		(scn->targetdef->d_CE_WRAPPER_DEBUG_SEL_LSB)
+#define CE_WRAPPER_DEBUG_SEL_MASK          \
+		(scn->targetdef->d_CE_WRAPPER_DEBUG_SEL_MASK)
+#define CE_DEBUG_OFFSET                    \
+		(scn->targetdef->d_CE_DEBUG_OFFSET)
+#define CE_DEBUG_SEL_MSB                   \
+		(scn->targetdef->d_CE_DEBUG_SEL_MSB)
+#define CE_DEBUG_SEL_LSB                   \
+		(scn->targetdef->d_CE_DEBUG_SEL_LSB)
+#define CE_DEBUG_SEL_MASK                  \
+		(scn->targetdef->d_CE_DEBUG_SEL_MASK)
+/* end */
+/* PLL start */
+#define EFUSE_OFFSET                       \
+		(scn->targetdef->d_EFUSE_OFFSET)
+#define EFUSE_XTAL_SEL_MSB                 \
+		(scn->targetdef->d_EFUSE_XTAL_SEL_MSB)
+#define EFUSE_XTAL_SEL_LSB                 \
+		(scn->targetdef->d_EFUSE_XTAL_SEL_LSB)
+#define EFUSE_XTAL_SEL_MASK                \
+		(scn->targetdef->d_EFUSE_XTAL_SEL_MASK)
+#define BB_PLL_CONFIG_OFFSET               \
+		(scn->targetdef->d_BB_PLL_CONFIG_OFFSET)
+#define BB_PLL_CONFIG_OUTDIV_MSB           \
+		(scn->targetdef->d_BB_PLL_CONFIG_OUTDIV_MSB)
+#define BB_PLL_CONFIG_OUTDIV_LSB           \
+		(scn->targetdef->d_BB_PLL_CONFIG_OUTDIV_LSB)
+#define BB_PLL_CONFIG_OUTDIV_MASK          \
+		(scn->targetdef->d_BB_PLL_CONFIG_OUTDIV_MASK)
+#define BB_PLL_CONFIG_FRAC_MSB             \
+		(scn->targetdef->d_BB_PLL_CONFIG_FRAC_MSB)
+#define BB_PLL_CONFIG_FRAC_LSB             \
+		(scn->targetdef->d_BB_PLL_CONFIG_FRAC_LSB)
+#define BB_PLL_CONFIG_FRAC_MASK            \
+		(scn->targetdef->d_BB_PLL_CONFIG_FRAC_MASK)
+#define WLAN_PLL_SETTLE_TIME_MSB           \
+		(scn->targetdef->d_WLAN_PLL_SETTLE_TIME_MSB)
+#define WLAN_PLL_SETTLE_TIME_LSB           \
+		(scn->targetdef->d_WLAN_PLL_SETTLE_TIME_LSB)
+#define WLAN_PLL_SETTLE_TIME_MASK          \
+		(scn->targetdef->d_WLAN_PLL_SETTLE_TIME_MASK)
+#define WLAN_PLL_SETTLE_OFFSET             \
+		(scn->targetdef->d_WLAN_PLL_SETTLE_OFFSET)
+#define WLAN_PLL_SETTLE_SW_MASK            \
+		(scn->targetdef->d_WLAN_PLL_SETTLE_SW_MASK)
+#define WLAN_PLL_SETTLE_RSTMASK            \
+		(scn->targetdef->d_WLAN_PLL_SETTLE_RSTMASK)
+#define WLAN_PLL_SETTLE_RESET              \
+		(scn->targetdef->d_WLAN_PLL_SETTLE_RESET)
+#define WLAN_PLL_CONTROL_NOPWD_MSB         \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_NOPWD_MSB)
+#define WLAN_PLL_CONTROL_NOPWD_LSB         \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_NOPWD_LSB)
+#define WLAN_PLL_CONTROL_NOPWD_MASK        \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_NOPWD_MASK)
+#define WLAN_PLL_CONTROL_BYPASS_MSB        \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_BYPASS_MSB)
+#define WLAN_PLL_CONTROL_BYPASS_LSB        \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_BYPASS_LSB)
+#define WLAN_PLL_CONTROL_BYPASS_MASK       \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_BYPASS_MASK)
+#define WLAN_PLL_CONTROL_BYPASS_RESET      \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_BYPASS_RESET)
+#define WLAN_PLL_CONTROL_CLK_SEL_MSB       \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_MSB)
+#define WLAN_PLL_CONTROL_CLK_SEL_LSB       \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_LSB)
+#define WLAN_PLL_CONTROL_CLK_SEL_MASK      \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_MASK)
+#define WLAN_PLL_CONTROL_CLK_SEL_RESET     \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_RESET)
+#define WLAN_PLL_CONTROL_REFDIV_MSB        \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_REFDIV_MSB)
+#define WLAN_PLL_CONTROL_REFDIV_LSB        \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_REFDIV_LSB)
+#define WLAN_PLL_CONTROL_REFDIV_MASK       \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_REFDIV_MASK)
+#define WLAN_PLL_CONTROL_REFDIV_RESET      \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_REFDIV_RESET)
+#define WLAN_PLL_CONTROL_DIV_MSB           \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_DIV_MSB)
+#define WLAN_PLL_CONTROL_DIV_LSB           \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_DIV_LSB)
+#define WLAN_PLL_CONTROL_DIV_MASK          \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_DIV_MASK)
+#define WLAN_PLL_CONTROL_DIV_RESET         \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_DIV_RESET)
+#define WLAN_PLL_CONTROL_OFFSET            \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_OFFSET)
+#define WLAN_PLL_CONTROL_SW_MASK           \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_SW_MASK)
+#define WLAN_PLL_CONTROL_RSTMASK           \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_RSTMASK)
+#define WLAN_PLL_CONTROL_RESET             \
+		(scn->targetdef->d_WLAN_PLL_CONTROL_RESET)
+#define SOC_CORE_CLK_CTRL_OFFSET           \
+		(scn->targetdef->d_SOC_CORE_CLK_CTRL_OFFSET)
+#define SOC_CORE_CLK_CTRL_DIV_MSB          \
+		(scn->targetdef->d_SOC_CORE_CLK_CTRL_DIV_MSB)
+#define SOC_CORE_CLK_CTRL_DIV_LSB          \
+		(scn->targetdef->d_SOC_CORE_CLK_CTRL_DIV_LSB)
+#define SOC_CORE_CLK_CTRL_DIV_MASK         \
+		(scn->targetdef->d_SOC_CORE_CLK_CTRL_DIV_MASK)
+#define RTC_SYNC_STATUS_PLL_CHANGING_MSB   \
+		(scn->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_MSB)
+#define RTC_SYNC_STATUS_PLL_CHANGING_LSB   \
+		(scn->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_LSB)
+#define RTC_SYNC_STATUS_PLL_CHANGING_MASK  \
+		(scn->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_MASK)
+#define RTC_SYNC_STATUS_PLL_CHANGING_RESET \
+		(scn->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_RESET)
+#define RTC_SYNC_STATUS_OFFSET             \
+		(scn->targetdef->d_RTC_SYNC_STATUS_OFFSET)
+#define SOC_CPU_CLOCK_OFFSET               \
+		(scn->targetdef->d_SOC_CPU_CLOCK_OFFSET)
+#define SOC_CPU_CLOCK_STANDARD_MSB         \
+		(scn->targetdef->d_SOC_CPU_CLOCK_STANDARD_MSB)
+#define SOC_CPU_CLOCK_STANDARD_LSB         \
+		(scn->targetdef->d_SOC_CPU_CLOCK_STANDARD_LSB)
+#define SOC_CPU_CLOCK_STANDARD_MASK        \
+		(scn->targetdef->d_SOC_CPU_CLOCK_STANDARD_MASK)
+/* PLL end */
+
+/* SET macros */
+#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x)       \
+		(((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & \
+				 WLAN_SYSTEM_SLEEP_DISABLE_MASK)
+#define SI_CONFIG_BIDIR_OD_DATA_SET(x)         \
+		(((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & \
+				 SI_CONFIG_BIDIR_OD_DATA_MASK)
+#define SI_CONFIG_I2C_SET(x)                   \
+		(((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK)
+#define SI_CONFIG_POS_SAMPLE_SET(x)            \
+		(((x) << SI_CONFIG_POS_SAMPLE_LSB) & \
+				 SI_CONFIG_POS_SAMPLE_MASK)
+#define SI_CONFIG_INACTIVE_CLK_SET(x)          \
+		(((x) << SI_CONFIG_INACTIVE_CLK_LSB) & \
+				 SI_CONFIG_INACTIVE_CLK_MASK)
+#define SI_CONFIG_INACTIVE_DATA_SET(x)         \
+		(((x) << SI_CONFIG_INACTIVE_DATA_LSB) & \
+				 SI_CONFIG_INACTIVE_DATA_MASK)
+#define SI_CONFIG_DIVIDER_SET(x)               \
+		(((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK)
+#define SI_CS_START_SET(x)                     \
+		(((x) << SI_CS_START_LSB) & SI_CS_START_MASK)
+#define SI_CS_RX_CNT_SET(x)                    \
+		(((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK)
+#define SI_CS_TX_CNT_SET(x)                    \
+		(((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK)
+#define LPO_CAL_ENABLE_SET(x)                  \
+		(((x) << LPO_CAL_ENABLE_LSB) & LPO_CAL_ENABLE_MASK)
+#define CPU_CLOCK_STANDARD_SET(x)              \
+		(((x) << CPU_CLOCK_STANDARD_LSB) & CPU_CLOCK_STANDARD_MASK)
+#define CLOCK_GPIO_BT_CLK_OUT_EN_SET(x)        \
+		(((x) << CLOCK_GPIO_BT_CLK_OUT_EN_LSB) & \
+				 CLOCK_GPIO_BT_CLK_OUT_EN_MASK)
+/* copy_engine.c */
+#define SRC_WATERMARK_LOW_SET(x)               \
+		(((x) << SRC_WATERMARK_LOW_LSB) & SRC_WATERMARK_LOW_MASK)
+#define SRC_WATERMARK_HIGH_SET(x)              \
+		(((x) << SRC_WATERMARK_HIGH_LSB) & SRC_WATERMARK_HIGH_MASK)
+#define DST_WATERMARK_LOW_SET(x)               \
+		(((x) << DST_WATERMARK_LOW_LSB) & DST_WATERMARK_LOW_MASK)
+#define DST_WATERMARK_HIGH_SET(x)              \
+		(((x) << DST_WATERMARK_HIGH_LSB) & DST_WATERMARK_HIGH_MASK)
+#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(x) (((x) & \
+			CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> \
+				CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB)
+#define CE_CTRL1_DMAX_LENGTH_SET(x)            \
+		(((x) << CE_CTRL1_DMAX_LENGTH_LSB) & CE_CTRL1_DMAX_LENGTH_MASK)
+#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_SET(x)  \
+		(((x) << CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB) & \
+				 CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK)
+#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_SET(x)  \
+		(((x) << CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB) & \
+				 CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK)
+#define WLAN_DEBUG_INPUT_SEL_SRC_GET(x)        \
+		(((x) & \
+			 WLAN_DEBUG_INPUT_SEL_SRC_MASK) >> \
+					WLAN_DEBUG_INPUT_SEL_SRC_LSB)
+#define WLAN_DEBUG_INPUT_SEL_SRC_SET(x)        \
+		(((x) << WLAN_DEBUG_INPUT_SEL_SRC_LSB) & \
+				 WLAN_DEBUG_INPUT_SEL_SRC_MASK)
+#define WLAN_DEBUG_CONTROL_ENABLE_GET(x)       \
+		(((x) & \
+			WLAN_DEBUG_CONTROL_ENABLE_MASK) >> \
+					WLAN_DEBUG_CONTROL_ENABLE_LSB)
+#define WLAN_DEBUG_CONTROL_ENABLE_SET(x)       \
+		(((x) << WLAN_DEBUG_CONTROL_ENABLE_LSB) & \
+				 WLAN_DEBUG_CONTROL_ENABLE_MASK)
+#define WLAN_DEBUG_OUT_DATA_GET(x)             \
+		(((x) & WLAN_DEBUG_OUT_DATA_MASK) >> WLAN_DEBUG_OUT_DATA_LSB)
+#define WLAN_DEBUG_OUT_DATA_SET(x)             \
+		(((x) << WLAN_DEBUG_OUT_DATA_LSB) & WLAN_DEBUG_OUT_DATA_MASK)
+#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_GET(x)   \
+		(((x) & \
+			AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK) >> \
+					AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB)
+#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_SET(x)   \
+		(((x) << AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB) & \
+				 AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK)
+#define AMBA_DEBUG_BUS_SEL_GET(x)              \
+		(((x) & AMBA_DEBUG_BUS_SEL_MASK) >> AMBA_DEBUG_BUS_SEL_LSB)
+#define AMBA_DEBUG_BUS_SEL_SET(x)              \
+		(((x) << AMBA_DEBUG_BUS_SEL_LSB) & AMBA_DEBUG_BUS_SEL_MASK)
+#define CE_WRAPPER_DEBUG_SEL_GET(x)            \
+		(((x) & CE_WRAPPER_DEBUG_SEL_MASK) >> CE_WRAPPER_DEBUG_SEL_LSB)
+#define CE_WRAPPER_DEBUG_SEL_SET(x)            \
+		(((x) << CE_WRAPPER_DEBUG_SEL_LSB) & CE_WRAPPER_DEBUG_SEL_MASK)
+#define CE_DEBUG_SEL_GET(x)                    \
+		(((x) & CE_DEBUG_SEL_MASK) >> CE_DEBUG_SEL_LSB)
+#define CE_DEBUG_SEL_SET(x)                    \
+		(((x) << CE_DEBUG_SEL_LSB) & CE_DEBUG_SEL_MASK)
+/* end */
+/* PLL start */
+#define EFUSE_XTAL_SEL_GET(x)                  \
+		(((x) & EFUSE_XTAL_SEL_MASK) >> EFUSE_XTAL_SEL_LSB)
+#define EFUSE_XTAL_SEL_SET(x)                  \
+		(((x) << EFUSE_XTAL_SEL_LSB) & EFUSE_XTAL_SEL_MASK)
+#define BB_PLL_CONFIG_OUTDIV_GET(x)            \
+		(((x) & BB_PLL_CONFIG_OUTDIV_MASK) >> BB_PLL_CONFIG_OUTDIV_LSB)
+#define BB_PLL_CONFIG_OUTDIV_SET(x)            \
+		(((x) << BB_PLL_CONFIG_OUTDIV_LSB) & BB_PLL_CONFIG_OUTDIV_MASK)
+#define BB_PLL_CONFIG_FRAC_GET(x)              \
+		(((x) & BB_PLL_CONFIG_FRAC_MASK) >> BB_PLL_CONFIG_FRAC_LSB)
+#define BB_PLL_CONFIG_FRAC_SET(x)              \
+		(((x) << BB_PLL_CONFIG_FRAC_LSB) & BB_PLL_CONFIG_FRAC_MASK)
+#define WLAN_PLL_SETTLE_TIME_GET(x)            \
+		(((x) & WLAN_PLL_SETTLE_TIME_MASK) >> WLAN_PLL_SETTLE_TIME_LSB)
+#define WLAN_PLL_SETTLE_TIME_SET(x)            \
+		(((x) << WLAN_PLL_SETTLE_TIME_LSB) & WLAN_PLL_SETTLE_TIME_MASK)
+#define WLAN_PLL_CONTROL_NOPWD_GET(x)          \
+		(((x) & \
+				 WLAN_PLL_CONTROL_NOPWD_MASK) >> \
+						WLAN_PLL_CONTROL_NOPWD_LSB)
+#define WLAN_PLL_CONTROL_NOPWD_SET(x)          \
+		(((x) << WLAN_PLL_CONTROL_NOPWD_LSB) & \
+				 WLAN_PLL_CONTROL_NOPWD_MASK)
+#define WLAN_PLL_CONTROL_BYPASS_GET(x)         \
+		(((x) & \
+				 WLAN_PLL_CONTROL_BYPASS_MASK) >> \
+						WLAN_PLL_CONTROL_BYPASS_LSB)
+#define WLAN_PLL_CONTROL_BYPASS_SET(x)         \
+		(((x) << WLAN_PLL_CONTROL_BYPASS_LSB) & \
+				 WLAN_PLL_CONTROL_BYPASS_MASK)
+#define WLAN_PLL_CONTROL_CLK_SEL_GET(x)        \
+		(((x) & \
+				 WLAN_PLL_CONTROL_CLK_SEL_MASK) >> \
+						WLAN_PLL_CONTROL_CLK_SEL_LSB)
+#define WLAN_PLL_CONTROL_CLK_SEL_SET(x)        \
+		(((x) << WLAN_PLL_CONTROL_CLK_SEL_LSB) & \
+				 WLAN_PLL_CONTROL_CLK_SEL_MASK)
+#define WLAN_PLL_CONTROL_REFDIV_GET(x)         \
+		(((x) & \
+				 WLAN_PLL_CONTROL_REFDIV_MASK) >> \
+						WLAN_PLL_CONTROL_REFDIV_LSB)
+#define WLAN_PLL_CONTROL_REFDIV_SET(x)         \
+		(((x) << WLAN_PLL_CONTROL_REFDIV_LSB) & \
+				 WLAN_PLL_CONTROL_REFDIV_MASK)
+#define WLAN_PLL_CONTROL_DIV_GET(x)            \
+		(((x) & \
+			 WLAN_PLL_CONTROL_DIV_MASK) >> \
+					WLAN_PLL_CONTROL_DIV_LSB)
+#define WLAN_PLL_CONTROL_DIV_SET(x)            \
+		(((x) << WLAN_PLL_CONTROL_DIV_LSB) & \
+			 WLAN_PLL_CONTROL_DIV_MASK)
+#define SOC_CORE_CLK_CTRL_DIV_GET(x)           \
+		(((x) & \
+			 SOC_CORE_CLK_CTRL_DIV_MASK) >> \
+					SOC_CORE_CLK_CTRL_DIV_LSB)
+#define SOC_CORE_CLK_CTRL_DIV_SET(x)           \
+		(((x) << SOC_CORE_CLK_CTRL_DIV_LSB) & \
+			 SOC_CORE_CLK_CTRL_DIV_MASK)
+#define RTC_SYNC_STATUS_PLL_CHANGING_GET(x)    \
+		(((x) & \
+			 RTC_SYNC_STATUS_PLL_CHANGING_MASK) >> \
+					RTC_SYNC_STATUS_PLL_CHANGING_LSB)
+#define RTC_SYNC_STATUS_PLL_CHANGING_SET(x)    \
+		(((x) << RTC_SYNC_STATUS_PLL_CHANGING_LSB) & \
+			 RTC_SYNC_STATUS_PLL_CHANGING_MASK)
+#define SOC_CPU_CLOCK_STANDARD_GET(x)          \
+		(((x) & \
+			 SOC_CPU_CLOCK_STANDARD_MASK) >> \
+				 SOC_CPU_CLOCK_STANDARD_LSB)
+#define SOC_CPU_CLOCK_STANDARD_SET(x)          \
+		(((x) << SOC_CPU_CLOCK_STANDARD_LSB) & \
+			 SOC_CPU_CLOCK_STANDARD_MASK)
+/* PLL end */
+
+typedef struct hostdef_s {
+	uint32_t d_INT_STATUS_ENABLE_ERROR_LSB;
+	uint32_t d_INT_STATUS_ENABLE_ERROR_MASK;
+	uint32_t d_INT_STATUS_ENABLE_CPU_LSB;
+	uint32_t d_INT_STATUS_ENABLE_CPU_MASK;
+	uint32_t d_INT_STATUS_ENABLE_COUNTER_LSB;
+	uint32_t d_INT_STATUS_ENABLE_COUNTER_MASK;
+	uint32_t d_INT_STATUS_ENABLE_MBOX_DATA_LSB;
+	uint32_t d_INT_STATUS_ENABLE_MBOX_DATA_MASK;
+	uint32_t d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB;
+	uint32_t d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK;
+	uint32_t d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB;
+	uint32_t d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK;
+	uint32_t d_COUNTER_INT_STATUS_ENABLE_BIT_LSB;
+	uint32_t d_COUNTER_INT_STATUS_ENABLE_BIT_MASK;
+	uint32_t d_INT_STATUS_ENABLE_ADDRESS;
+	uint32_t d_CPU_INT_STATUS_ENABLE_BIT_LSB;
+	uint32_t d_CPU_INT_STATUS_ENABLE_BIT_MASK;
+	uint32_t d_HOST_INT_STATUS_ADDRESS;
+	uint32_t d_CPU_INT_STATUS_ADDRESS;
+	uint32_t d_ERROR_INT_STATUS_ADDRESS;
+	uint32_t d_ERROR_INT_STATUS_WAKEUP_MASK;
+	uint32_t d_ERROR_INT_STATUS_WAKEUP_LSB;
+	uint32_t d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK;
+	uint32_t d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB;
+	uint32_t d_ERROR_INT_STATUS_TX_OVERFLOW_MASK;
+	uint32_t d_ERROR_INT_STATUS_TX_OVERFLOW_LSB;
+	uint32_t d_COUNT_DEC_ADDRESS;
+	uint32_t d_HOST_INT_STATUS_CPU_MASK;
+	uint32_t d_HOST_INT_STATUS_CPU_LSB;
+	uint32_t d_HOST_INT_STATUS_ERROR_MASK;
+	uint32_t d_HOST_INT_STATUS_ERROR_LSB;
+	uint32_t d_HOST_INT_STATUS_COUNTER_MASK;
+	uint32_t d_HOST_INT_STATUS_COUNTER_LSB;
+	uint32_t d_RX_LOOKAHEAD_VALID_ADDRESS;
+	uint32_t d_WINDOW_DATA_ADDRESS;
+	uint32_t d_WINDOW_READ_ADDR_ADDRESS;
+	uint32_t d_WINDOW_WRITE_ADDR_ADDRESS;
+	uint32_t d_SOC_GLOBAL_RESET_ADDRESS;
+	uint32_t d_RTC_STATE_ADDRESS;
+	uint32_t d_RTC_STATE_COLD_RESET_MASK;
+	uint32_t d_PCIE_LOCAL_BASE_ADDRESS;
+	uint32_t d_PCIE_SOC_WAKE_RESET;
+	uint32_t d_PCIE_SOC_WAKE_ADDRESS;
+	uint32_t d_PCIE_SOC_WAKE_V_MASK;
+	uint32_t d_RTC_STATE_V_MASK;
+	uint32_t d_RTC_STATE_V_LSB;
+	uint32_t d_FW_IND_EVENT_PENDING;
+	uint32_t d_FW_IND_INITIALIZED;
+	uint32_t d_RTC_STATE_V_ON;
+#if defined(SDIO_3_0)
+	uint32_t d_HOST_INT_STATUS_MBOX_DATA_MASK;
+	uint32_t d_HOST_INT_STATUS_MBOX_DATA_LSB;
+#endif
+	uint32_t d_PCIE_SOC_RDY_STATUS_ADDRESS;
+	uint32_t d_PCIE_SOC_RDY_STATUS_BAR_MASK;
+	uint32_t d_SOC_PCIE_BASE_ADDRESS;
+	uint32_t d_MSI_MAGIC_ADR_ADDRESS;
+	uint32_t d_MSI_MAGIC_ADDRESS;
+} HOST_REGISTER_TABLE;
+
+#define INT_STATUS_ENABLE_ERROR_LSB        \
+		(scn->hostdef->d_INT_STATUS_ENABLE_ERROR_LSB)
+#define INT_STATUS_ENABLE_ERROR_MASK       \
+		(scn->hostdef->d_INT_STATUS_ENABLE_ERROR_MASK)
+#define INT_STATUS_ENABLE_CPU_LSB          \
+		(scn->hostdef->d_INT_STATUS_ENABLE_CPU_LSB)
+#define INT_STATUS_ENABLE_CPU_MASK         \
+		(scn->hostdef->d_INT_STATUS_ENABLE_CPU_MASK)
+#define INT_STATUS_ENABLE_COUNTER_LSB      \
+		(scn->hostdef->d_INT_STATUS_ENABLE_COUNTER_LSB)
+#define INT_STATUS_ENABLE_COUNTER_MASK     \
+		(scn->hostdef->d_INT_STATUS_ENABLE_COUNTER_MASK)
+#define INT_STATUS_ENABLE_MBOX_DATA_LSB    \
+		(scn->hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_LSB)
+#define INT_STATUS_ENABLE_MBOX_DATA_MASK   \
+		(scn->hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_MASK)
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB     \
+		(scn->hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK    \
+		(scn->hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK)
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB\
+		(scn->hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK     \
+		(scn->hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
+#define COUNTER_INT_STATUS_ENABLE_BIT_LSB  \
+		(scn->hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_LSB)
+#define COUNTER_INT_STATUS_ENABLE_BIT_MASK \
+		(scn->hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_MASK)
+#define INT_STATUS_ENABLE_ADDRESS          \
+		(scn->hostdef->d_INT_STATUS_ENABLE_ADDRESS)
+#define CPU_INT_STATUS_ENABLE_BIT_LSB      \
+		(scn->hostdef->d_CPU_INT_STATUS_ENABLE_BIT_LSB)
+#define CPU_INT_STATUS_ENABLE_BIT_MASK     \
+		(scn->hostdef->d_CPU_INT_STATUS_ENABLE_BIT_MASK)
+#define HOST_INT_STATUS_ADDRESS            \
+		(scn->hostdef->d_HOST_INT_STATUS_ADDRESS)
+#define CPU_INT_STATUS_ADDRESS             \
+		(scn->hostdef->d_CPU_INT_STATUS_ADDRESS)
+#define ERROR_INT_STATUS_ADDRESS           \
+		(scn->hostdef->d_ERROR_INT_STATUS_ADDRESS)
+#define ERROR_INT_STATUS_WAKEUP_MASK       \
+		(scn->hostdef->d_ERROR_INT_STATUS_WAKEUP_MASK)
+#define ERROR_INT_STATUS_WAKEUP_LSB        \
+		(scn->hostdef->d_ERROR_INT_STATUS_WAKEUP_LSB)
+#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK \
+		(scn->hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK)
+#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB  \
+		(scn->hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB)
+#define ERROR_INT_STATUS_TX_OVERFLOW_MASK  \
+		(scn->hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_MASK)
+#define ERROR_INT_STATUS_TX_OVERFLOW_LSB   \
+		(scn->hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_LSB)
+#define COUNT_DEC_ADDRESS                  \
+		(scn->hostdef->d_COUNT_DEC_ADDRESS)
+#define HOST_INT_STATUS_CPU_MASK           \
+		(scn->hostdef->d_HOST_INT_STATUS_CPU_MASK)
+#define HOST_INT_STATUS_CPU_LSB            \
+		(scn->hostdef->d_HOST_INT_STATUS_CPU_LSB)
+#define HOST_INT_STATUS_ERROR_MASK         \
+		(scn->hostdef->d_HOST_INT_STATUS_ERROR_MASK)
+#define HOST_INT_STATUS_ERROR_LSB          \
+		(scn->hostdef->d_HOST_INT_STATUS_ERROR_LSB)
+#define HOST_INT_STATUS_COUNTER_MASK       \
+		(scn->hostdef->d_HOST_INT_STATUS_COUNTER_MASK)
+#define HOST_INT_STATUS_COUNTER_LSB        \
+		(scn->hostdef->d_HOST_INT_STATUS_COUNTER_LSB)
+#define RX_LOOKAHEAD_VALID_ADDRESS         \
+		(scn->hostdef->d_RX_LOOKAHEAD_VALID_ADDRESS)
+#define WINDOW_DATA_ADDRESS                \
+		(scn->hostdef->d_WINDOW_DATA_ADDRESS)
+#define WINDOW_READ_ADDR_ADDRESS           \
+		(scn->hostdef->d_WINDOW_READ_ADDR_ADDRESS)
+#define WINDOW_WRITE_ADDR_ADDRESS          \
+		(scn->hostdef->d_WINDOW_WRITE_ADDR_ADDRESS)
+#define SOC_GLOBAL_RESET_ADDRESS           \
+		(scn->hostdef->d_SOC_GLOBAL_RESET_ADDRESS)
+#define RTC_STATE_ADDRESS                  \
+		(scn->hostdef->d_RTC_STATE_ADDRESS)
+#define RTC_STATE_COLD_RESET_MASK          \
+		(scn->hostdef->d_RTC_STATE_COLD_RESET_MASK)
+#define PCIE_LOCAL_BASE_ADDRESS            \
+		(scn->hostdef->d_PCIE_LOCAL_BASE_ADDRESS)
+#define PCIE_SOC_WAKE_RESET                \
+		(scn->hostdef->d_PCIE_SOC_WAKE_RESET)
+#define PCIE_SOC_WAKE_ADDRESS              \
+		(scn->hostdef->d_PCIE_SOC_WAKE_ADDRESS)
+#define PCIE_SOC_WAKE_V_MASK               \
+		(scn->hostdef->d_PCIE_SOC_WAKE_V_MASK)
+#define RTC_STATE_V_MASK                   \
+		(scn->hostdef->d_RTC_STATE_V_MASK)
+#define RTC_STATE_V_LSB                    \
+		(scn->hostdef->d_RTC_STATE_V_LSB)
+#define FW_IND_EVENT_PENDING               \
+		(scn->hostdef->d_FW_IND_EVENT_PENDING)
+#define FW_IND_INITIALIZED                 \
+		(scn->hostdef->d_FW_IND_INITIALIZED)
+#define RTC_STATE_V_ON                     \
+		(scn->hostdef->d_RTC_STATE_V_ON)
+#if defined(SDIO_3_0)
+#define HOST_INT_STATUS_MBOX_DATA_MASK     \
+		(scn->hostdef->d_HOST_INT_STATUS_MBOX_DATA_MASK)
+#define HOST_INT_STATUS_MBOX_DATA_LSB      \
+		(scn->hostdef->d_HOST_INT_STATUS_MBOX_DATA_LSB)
+#endif
+
+#if !defined(SOC_PCIE_BASE_ADDRESS)
+#define SOC_PCIE_BASE_ADDRESS 0
+#endif
+
+#if !defined(PCIE_SOC_RDY_STATUS_ADDRESS)
+#define PCIE_SOC_RDY_STATUS_ADDRESS 0
+#define PCIE_SOC_RDY_STATUS_BAR_MASK 0
+#endif
+
+#if !defined(MSI_MAGIC_ADR_ADDRESS)
+#define MSI_MAGIC_ADR_ADDRESS 0
+#define MSI_MAGIC_ADDRESS 0
+#endif
+
+/* SET/GET macros */
+#define INT_STATUS_ENABLE_ERROR_SET(x)        \
+		(((x) << INT_STATUS_ENABLE_ERROR_LSB) & \
+					INT_STATUS_ENABLE_ERROR_MASK)
+#define INT_STATUS_ENABLE_CPU_SET(x)          \
+		(((x) << INT_STATUS_ENABLE_CPU_LSB) & \
+				INT_STATUS_ENABLE_CPU_MASK)
+#define INT_STATUS_ENABLE_COUNTER_SET(x)      \
+		(((x) << INT_STATUS_ENABLE_COUNTER_LSB) & \
+				INT_STATUS_ENABLE_COUNTER_MASK)
+#define INT_STATUS_ENABLE_MBOX_DATA_SET(x)    \
+		(((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & \
+				INT_STATUS_ENABLE_MBOX_DATA_MASK)
+#define CPU_INT_STATUS_ENABLE_BIT_SET(x)      \
+		(((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & \
+				CPU_INT_STATUS_ENABLE_BIT_MASK)
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) \
+		(((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & \
+				ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK)
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x)\
+		(((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & \
+				ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
+#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x)  \
+		(((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & \
+					COUNTER_INT_STATUS_ENABLE_BIT_MASK)
+#define ERROR_INT_STATUS_WAKEUP_GET(x)        \
+		(((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> \
+				ERROR_INT_STATUS_WAKEUP_LSB)
+#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x)  \
+		(((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> \
+					ERROR_INT_STATUS_RX_UNDERFLOW_LSB)
+#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x)   \
+		(((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> \
+					ERROR_INT_STATUS_TX_OVERFLOW_LSB)
+#define HOST_INT_STATUS_CPU_GET(x)            \
+		(((x) & HOST_INT_STATUS_CPU_MASK) >> \
+					HOST_INT_STATUS_CPU_LSB)
+#define HOST_INT_STATUS_ERROR_GET(x)          \
+		(((x) & HOST_INT_STATUS_ERROR_MASK) >> \
+					HOST_INT_STATUS_ERROR_LSB)
+#define HOST_INT_STATUS_COUNTER_GET(x)        \
+		(((x) & HOST_INT_STATUS_COUNTER_MASK) >> \
+					HOST_INT_STATUS_COUNTER_LSB)
+#define RTC_STATE_V_GET(x)                    \
+		(((x) & RTC_STATE_V_MASK) >> RTC_STATE_V_LSB)
+#if defined(SDIO_3_0)
+#define HOST_INT_STATUS_MBOX_DATA_GET(x)      \
+		(((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> \
+					HOST_INT_STATUS_MBOX_DATA_LSB)
+#endif
+
+#define INVALID_REG_LOC_DUMMY_DATA 0xAA
+
+
+
+#define ROME_USB_RTC_SOC_BASE_ADDRESS		0x00000800
+#define ROME_USB_SOC_RESET_CONTROL_COLD_RST_LSB	0x0
+#define SOC_RESET_CONTROL_COLD_RST_LSB		8
+#define SOC_RESET_CONTROL_COLD_RST_MASK		0x00000100
+#define SOC_RESET_CONTROL_COLD_RST_SET(x)	\
+	(((x) << SOC_RESET_CONTROL_COLD_RST_LSB) & \
+	 SOC_RESET_CONTROL_COLD_RST_MASK)
+
+#define AR6320_CORE_CLK_DIV_ADDR	0x403fa8
+#define AR6320_CPU_PLL_INIT_DONE_ADDR	0x403fd0
+#define AR6320_CPU_SPEED_ADDR		0x403fa4
+#define AR6320V2_CORE_CLK_DIV_ADDR	0x403fd8
+#define AR6320V2_CPU_PLL_INIT_DONE_ADDR	0x403fd0
+#define AR6320V2_CPU_SPEED_ADDR		0x403fd4
+#define AR6320V3_CORE_CLK_DIV_ADDR	0x404028
+#define AR6320V3_CPU_PLL_INIT_DONE_ADDR	0x404020
+#define AR6320V3_CPU_SPEED_ADDR		0x404024
+
+typedef enum {
+	/* Unsupported ref clock -- use PLL Bypass */
+	SOC_REFCLK_UNKNOWN   = -1,
+	SOC_REFCLK_48_MHZ    = 0,
+	SOC_REFCLK_19_2_MHZ  = 1,
+	SOC_REFCLK_24_MHZ    = 2,
+	SOC_REFCLK_26_MHZ    = 3,
+	SOC_REFCLK_37_4_MHZ  = 4,
+	SOC_REFCLK_38_4_MHZ  = 5,
+	SOC_REFCLK_40_MHZ    = 6,
+	SOC_REFCLK_52_MHZ    = 7,
+} A_refclk_speed_t;
+
+#define A_REFCLK_UNKNOWN    SOC_REFCLK_UNKNOWN
+#define A_REFCLK_48_MHZ     SOC_REFCLK_48_MHZ
+#define A_REFCLK_19_2_MHZ   SOC_REFCLK_19_2_MHZ
+#define A_REFCLK_24_MHZ     SOC_REFCLK_24_MHZ
+#define A_REFCLK_26_MHZ     SOC_REFCLK_26_MHZ
+#define A_REFCLK_37_4_MHZ   SOC_REFCLK_37_4_MHZ
+#define A_REFCLK_38_4_MHZ   SOC_REFCLK_38_4_MHZ
+#define A_REFCLK_40_MHZ     SOC_REFCLK_40_MHZ
+#define A_REFCLK_52_MHZ     SOC_REFCLK_52_MHZ
+
+#define TARGET_CPU_FREQ 176000000
+
+struct wlan_pll_s {
+	u_int32_t refdiv;
+	u_int32_t div;
+	u_int32_t rnfrac;
+	u_int32_t outdiv;
+};
+
+struct cmnos_clock_s {
+	A_refclk_speed_t refclk_speed;
+	u_int32_t         refclk_hz;
+	u_int32_t         pll_settling_time; /* 50us */
+	struct wlan_pll_s   wlan_pll;
+};
+
+typedef struct TGT_REG_SECTION {
+	u_int32_t start_addr;
+	u_int32_t end_addr;
+} tgt_reg_section;
+
+typedef struct TGT_REG_TABLE {
+	tgt_reg_section *section;
+	u_int32_t section_size;
+} tgt_reg_table;
+void target_register_tbl_attach(struct hif_softc *scn,
+					uint32_t target_type);
+void hif_register_tbl_attach(struct hif_softc *scn,
+					uint32_t target_type);
+#endif

+ 1267 - 0
hif/src/usb/usbdrv.c

@@ -0,0 +1,1267 @@
+/*
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#define ATH_MODULE_NAME hif
+#include "a_debug.h"
+#include "hif_usb_internal.h"
+#include "if_usb.h"
+#include "cds_api.h"
+#include "hif_debug.h"
+
+#define IS_BULK_EP(attr) (((attr) & 3) == 0x02)
+#define IS_INT_EP(attr) (((attr) & 3) == 0x03)
+#define IS_ISOC_EP(attr) (((attr) & 3) == 0x01)
+#define IS_DIR_IN(addr) ((addr) & 0x80)
+
+#define IS_FW_CRASH_DUMP(x)(((x == FW_ASSERT_PATTERN) || \
+				(x == FW_REG_PATTERN) || \
+				((x & FW_RAMDUMP_PATTERN_MASK) ==  \
+						FW_RAMDUMP_PATTERN)) ? 1 : 0)
+
+static void usb_hif_post_recv_transfers(HIF_USB_PIPE *recv_pipe,
+					int buffer_length);
+static void usb_hif_post_recv_bundle_transfers
+						(HIF_USB_PIPE *recv_pipe,
+						int buffer_length);
+static void usb_hif_cleanup_recv_urb(HIF_URB_CONTEXT *urb_context);
+
+
+/**
+ * usb_hif_free_urb_to_pipe() - add urb back to urb list of a pipe
+ * @pipe: pointer to HIF_USB_PIPE
+ * @urb_context: pointer to HIF_URB_CONTEXT
+ *
+ * Return: none
+ */
+static void usb_hif_free_urb_to_pipe(HIF_USB_PIPE *pipe,
+						HIF_URB_CONTEXT *urb_context)
+{
+	qdf_spin_lock_irqsave(&pipe->device->cs_lock);
+	pipe->urb_cnt++;
+	DL_ListAdd(&pipe->urb_list_head, &urb_context->link);
+	qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
+}
+
+/**
+ * usb_hif_alloc_urb_from_pipe() - remove urb back from urb list of a pipe
+ * @pipe: pointer to HIF_USB_PIPE
+ *
+ * Return: HIF_URB_CONTEXT urb context removed from the urb list
+ */
+HIF_URB_CONTEXT *usb_hif_alloc_urb_from_pipe(HIF_USB_PIPE *pipe)
+{
+	HIF_URB_CONTEXT *urb_context = NULL;
+	DL_LIST *item;
+
+	qdf_spin_lock_irqsave(&pipe->device->cs_lock);
+	item = dl_list_remove_item_from_head(&pipe->urb_list_head);
+	if (item != NULL) {
+		urb_context = A_CONTAINING_STRUCT(item, HIF_URB_CONTEXT, link);
+		pipe->urb_cnt--;
+	}
+	qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
+
+	return urb_context;
+}
+
+/**
+ * usb_hif_dequeue_pending_transfer() - remove urb from pending xfer list
+ * @pipe: pointer to HIF_USB_PIPE
+ *
+ * Return: HIF_URB_CONTEXT urb context removed from the pending xfer list
+ */
+static HIF_URB_CONTEXT *usb_hif_dequeue_pending_transfer
+							(HIF_USB_PIPE *pipe)
+{
+	HIF_URB_CONTEXT *urb_context = NULL;
+	DL_LIST *item;
+
+	qdf_spin_lock_irqsave(&pipe->device->cs_lock);
+	item = dl_list_remove_item_from_head(&pipe->urb_pending_list);
+	if (item != NULL)
+		urb_context = A_CONTAINING_STRUCT(item, HIF_URB_CONTEXT, link);
+	qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
+
+	return urb_context;
+}
+
+/**
+ * usb_hif_enqueue_pending_transfer() - add urb to pending xfer list
+ * @pipe: pointer to HIF_USB_PIPE
+ * @urb_context: pointer to HIF_URB_CONTEXT to be added to the xfer list
+ *
+ * Return: none
+ */
+void usb_hif_enqueue_pending_transfer(HIF_USB_PIPE *pipe,
+						HIF_URB_CONTEXT *urb_context)
+{
+	qdf_spin_lock_irqsave(&pipe->device->cs_lock);
+	dl_list_insert_tail(&pipe->urb_pending_list, &urb_context->link);
+	qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
+}
+
+
+/**
+ * usb_hif_remove_pending_transfer() - remove urb from its own list
+ * @urb_context: pointer to HIF_URB_CONTEXT to be removed
+ *
+ * Return: none
+ */
+void
+usb_hif_remove_pending_transfer(HIF_URB_CONTEXT *urb_context)
+{
+	qdf_spin_lock_irqsave(&urb_context->pipe->device->cs_lock);
+	dl_list_remove(&urb_context->link);
+	qdf_spin_unlock_irqrestore(&urb_context->pipe->device->cs_lock);
+}
+
+/**
+ * usb_hif_alloc_pipe_resources() - allocate urb_cnt urbs to a HIF pipe
+ * @pipe: pointer to HIF_USB_PIPE to which resources will be allocated
+ * @urb_cnt: number of urbs to be added to the HIF pipe
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+static QDF_STATUS usb_hif_alloc_pipe_resources
+					(HIF_USB_PIPE *pipe, int urb_cnt)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	int i;
+	HIF_URB_CONTEXT *urb_context;
+
+	DL_LIST_INIT(&pipe->urb_list_head);
+	DL_LIST_INIT(&pipe->urb_pending_list);
+
+	for (i = 0; i < urb_cnt; i++) {
+		urb_context = qdf_mem_malloc(sizeof(*urb_context));
+		if (NULL == urb_context) {
+			status = QDF_STATUS_E_NOMEM;
+			HIF_ERROR("urb_context is null");
+			break;
+		}
+		urb_context->pipe = pipe;
+		urb_context->urb = usb_alloc_urb(0, GFP_KERNEL);
+
+		if (NULL == urb_context->urb) {
+			status = QDF_STATUS_E_NOMEM;
+			qdf_mem_free(urb_context);
+			HIF_ERROR("urb_context->urb is null");
+			break;
+		}
+
+		/* note we are only allocate the urb contexts here, the actual
+		 * URB is
+		 * allocated from the kernel as needed to do a transaction
+		 */
+		pipe->urb_alloc++;
+
+		usb_hif_free_urb_to_pipe(pipe, urb_context);
+	}
+
+	HIF_DBG("athusb: alloc resources lpipe:%d hpipe:0x%X urbs:%d",
+		pipe->logical_pipe_num,
+		pipe->usb_pipe_handle,
+		pipe->urb_alloc);
+	return status;
+}
+
+/**
+ * usb_hif_free_pipe_resources() - free urb resources allocated to a HIF pipe
+ * @pipe: pointer to HIF_USB_PIPE
+ *
+ * Return: none
+ */
+static void usb_hif_free_pipe_resources(HIF_USB_PIPE *pipe)
+{
+	HIF_URB_CONTEXT *urb_context;
+
+	if (NULL == pipe->device) {
+		/* nothing allocated for this pipe */
+		HIF_ERROR("pipe->device is null");
+		return;
+	}
+
+	HIF_TRACE("athusb: free resources lpipe:%d hpipe:0x%X urbs:%d avail:%d",
+			 pipe->logical_pipe_num,
+			 pipe->usb_pipe_handle, pipe->urb_alloc,
+			 pipe->urb_cnt);
+
+	if (pipe->urb_alloc != pipe->urb_cnt) {
+		HIF_ERROR("athusb: urb leak! lpipe:%d hpipe:0x%X urbs:%d avail:%d",
+				 pipe->logical_pipe_num,
+				 pipe->usb_pipe_handle, pipe->urb_alloc,
+				 pipe->urb_cnt);
+	}
+
+	while (true) {
+		urb_context = usb_hif_alloc_urb_from_pipe(pipe);
+		if (NULL == urb_context)
+			break;
+
+		if (urb_context->buf) {
+			qdf_nbuf_free(urb_context->buf);
+			urb_context->buf = NULL;
+		}
+
+		usb_free_urb(urb_context->urb);
+		urb_context->urb = NULL;
+		qdf_mem_free(urb_context);
+	}
+
+}
+
+/**
+ * usb_hif_get_logical_pipe_num() - get pipe number for a particular enpoint
+ * @device: pointer to HIF_DEVICE_USB structure
+ * @ep_address: endpoint address
+ * @urb_count: number of urb resources to be allocated to the pipe
+ *
+ * Return: uint8_t pipe number corresponding to ep_address
+ */
+static uint8_t usb_hif_get_logical_pipe_num
+					(HIF_DEVICE_USB *device,
+					uint8_t ep_address,
+					int *urb_count)
+{
+	uint8_t pipe_num = HIF_USB_PIPE_INVALID;
+
+	switch (ep_address) {
+	case USB_EP_ADDR_APP_CTRL_IN:
+		pipe_num = HIF_RX_CTRL_PIPE;
+		*urb_count = RX_URB_COUNT;
+		break;
+	case USB_EP_ADDR_APP_DATA_IN:
+		pipe_num = HIF_RX_DATA_PIPE;
+		*urb_count = RX_URB_COUNT;
+		break;
+	case USB_EP_ADDR_APP_INT_IN:
+		pipe_num = HIF_RX_INT_PIPE;
+		*urb_count = RX_URB_COUNT;
+		break;
+	case USB_EP_ADDR_APP_DATA2_IN:
+		pipe_num = HIF_RX_DATA2_PIPE;
+		*urb_count = RX_URB_COUNT;
+		break;
+	case USB_EP_ADDR_APP_CTRL_OUT:
+		pipe_num = HIF_TX_CTRL_PIPE;
+		*urb_count = TX_URB_COUNT;
+		break;
+	case USB_EP_ADDR_APP_DATA_LP_OUT:
+		pipe_num = HIF_TX_DATA_LP_PIPE;
+		*urb_count = TX_URB_COUNT;
+		break;
+	case USB_EP_ADDR_APP_DATA_MP_OUT:
+		pipe_num = HIF_TX_DATA_MP_PIPE;
+		*urb_count = TX_URB_COUNT;
+		break;
+	case USB_EP_ADDR_APP_DATA_HP_OUT:
+		pipe_num = HIF_TX_DATA_HP_PIPE;
+		*urb_count = TX_URB_COUNT;
+		break;
+	default:
+		/* note: there may be endpoints not currently used */
+		break;
+	}
+
+	return pipe_num;
+}
+
+/**
+ * usb_hif_get_logical_pipe_num() - setup urb resources for all pipes
+ * @device: pointer to HIF_DEVICE_USB structure
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+QDF_STATUS usb_hif_setup_pipe_resources(HIF_DEVICE_USB *device)
+{
+	struct usb_interface *interface = device->interface;
+	struct usb_host_interface *iface_desc = interface->cur_altsetting;
+	struct usb_endpoint_descriptor *endpoint;
+	int i;
+	int urbcount;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	HIF_USB_PIPE *pipe;
+	uint8_t pipe_num;
+
+	/* walk decriptors and setup pipes */
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+		endpoint = &iface_desc->endpoint[i].desc;
+
+		if (IS_BULK_EP(endpoint->bmAttributes)) {
+			HIF_DBG("%s Bulk Ep:0x%2.2X " "maxpktsz:%d",
+				IS_DIR_IN(endpoint->bEndpointAddress) ?
+								"RX" : "TX",
+				endpoint->bEndpointAddress,
+				qdf_le16_to_cpu(endpoint->wMaxPacketSize));
+		} else if (IS_INT_EP(endpoint->bmAttributes)) {
+			HIF_DBG("%s Int Ep:0x%2.2X maxpktsz:%d interval:%d",
+				IS_DIR_IN(endpoint->bEndpointAddress) ?
+								"RX" : "TX",
+				endpoint->bEndpointAddress,
+				qdf_le16_to_cpu(endpoint->wMaxPacketSize),
+				endpoint->bInterval);
+		} else if (IS_ISOC_EP(endpoint->bmAttributes)) {
+			/* TODO for ISO */
+			HIF_DBG("%s ISOC Ep:0x%2.2X maxpktsz:%d interval:%d",
+				IS_DIR_IN(endpoint->bEndpointAddress) ?
+								"RX" : "TX",
+				endpoint->bEndpointAddress,
+				qdf_le16_to_cpu(endpoint->wMaxPacketSize),
+				endpoint->bInterval);
+		}
+		urbcount = 0;
+
+		pipe_num = usb_hif_get_logical_pipe_num(device,
+						endpoint->bEndpointAddress,
+						&urbcount);
+		if (HIF_USB_PIPE_INVALID == pipe_num)
+			continue;
+
+		pipe = &device->pipes[pipe_num];
+		if (pipe->device != NULL) {
+			/*pipe was already setup */
+			continue;
+		}
+
+		pipe->device = device;
+		pipe->logical_pipe_num = pipe_num;
+		pipe->ep_address = endpoint->bEndpointAddress;
+		pipe->max_packet_size =
+			qdf_le16_to_cpu(endpoint->wMaxPacketSize);
+
+		if (IS_BULK_EP(endpoint->bmAttributes)) {
+			if (IS_DIR_IN(pipe->ep_address)) {
+				pipe->usb_pipe_handle =
+					usb_rcvbulkpipe(device->udev,
+							pipe->ep_address);
+			} else {
+				pipe->usb_pipe_handle =
+					usb_sndbulkpipe(device->udev,
+						pipe->ep_address);
+			}
+		} else if (IS_INT_EP(endpoint->bmAttributes)) {
+			if (IS_DIR_IN(pipe->ep_address)) {
+				pipe->usb_pipe_handle =
+					usb_rcvintpipe(device->udev,
+						pipe->ep_address);
+			} else {
+				pipe->usb_pipe_handle =
+					usb_sndintpipe(device->udev,
+						pipe->ep_address);
+			}
+		} else if (IS_ISOC_EP(endpoint->bmAttributes)) {
+			/* TODO for ISO */
+			if (IS_DIR_IN(pipe->ep_address)) {
+				pipe->usb_pipe_handle =
+					usb_rcvisocpipe(device->udev,
+						pipe->ep_address);
+			} else {
+				pipe->usb_pipe_handle =
+					usb_sndisocpipe(device->udev,
+						pipe->ep_address);
+			}
+		}
+		pipe->ep_desc = endpoint;
+
+		if (!IS_DIR_IN(pipe->ep_address))
+			pipe->flags |= HIF_USB_PIPE_FLAG_TX;
+
+		status = usb_hif_alloc_pipe_resources(pipe, urbcount);
+
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+
+	}
+
+	return status;
+}
+
+
+/**
+ * usb_hif_cleanup_pipe_resources() - free urb resources for all pipes
+ * @device: pointer to HIF_DEVICE_USB structure
+ *
+ * Return: none
+ */
+void usb_hif_cleanup_pipe_resources(HIF_DEVICE_USB *device)
+{
+	int i;
+
+	for (i = 0; i < HIF_USB_PIPE_MAX; i++)
+		usb_hif_free_pipe_resources(&device->pipes[i]);
+}
+
+/**
+ * usb_hif_flush_pending_transfers() - kill pending urbs for a pipe
+ * @pipe: pointer to HIF_USB_PIPE structure
+ *
+ * Return: none
+ */
+static void usb_hif_flush_pending_transfers(HIF_USB_PIPE *pipe)
+{
+	HIF_URB_CONTEXT *urb_context;
+
+	HIF_TRACE("+%s pipe : %d", __func__, pipe->logical_pipe_num);
+
+	while (1) {
+		urb_context = usb_hif_dequeue_pending_transfer(pipe);
+		if (NULL == urb_context) {
+			HIF_WARN("urb_context is NULL");
+			break;
+		}
+		HIF_TRACE("  pending urb ctxt: 0x%p", urb_context);
+		if (urb_context->urb != NULL) {
+			HIF_TRACE("  killing urb: 0x%p", urb_context->urb);
+			/* killing the URB will cause the completion routines to
+			 * run
+			 */
+			usb_kill_urb(urb_context->urb);
+		}
+	}
+	HIF_TRACE("-%s", __func__);
+}
+
+/**
+ * usb_hif_flush_all() - flush pending transfers for all pipes for a usb bus
+ * @device: pointer to HIF_DEVICE_USB structure
+ *
+ * Return: none
+ */
+void usb_hif_flush_all(HIF_DEVICE_USB *device)
+{
+	int i;
+	HIF_USB_PIPE *pipe;
+	HIF_TRACE("+%s", __func__);
+
+	for (i = 0; i < HIF_USB_PIPE_MAX; i++) {
+		if (device->pipes[i].device != NULL) {
+			usb_hif_flush_pending_transfers(&device->pipes[i]);
+			pipe = &device->pipes[i];
+
+		HIF_USB_FLUSH_WORK(pipe);
+		}
+	}
+
+	HIF_TRACE("-%s", __func__);
+}
+
+/**
+ * usb_hif_cleanup_recv_urb() - cleanup recv urb
+ * @urb_context: pointer to HIF_URB_CONTEXT structure
+ *
+ * Return: none
+ */
+static void usb_hif_cleanup_recv_urb(HIF_URB_CONTEXT *urb_context)
+{
+	HIF_TRACE("+%s", __func__);
+
+	if (urb_context->buf != NULL) {
+		qdf_nbuf_free(urb_context->buf);
+		urb_context->buf = NULL;
+	}
+
+	usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context);
+	HIF_TRACE("-%s", __func__);
+}
+
+/**
+ * usb_hif_cleanup_transmit_urb() - cleanup transmit urb
+ * @urb_context: pointer to HIF_URB_CONTEXT structure
+ *
+ * Return: none
+ */
+void usb_hif_cleanup_transmit_urb(HIF_URB_CONTEXT *urb_context)
+{
+	usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context);
+}
+
+/**
+ * usb_hif_usb_recv_prestart_complete() - completion routine for prestart rx urb
+ * @urb: urb for which the completion routine is being called
+ *
+ * Return: none
+ */
+static void usb_hif_usb_recv_prestart_complete
+							(struct urb *urb)
+{
+	HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	qdf_nbuf_t buf = NULL;
+	HIF_USB_PIPE *pipe = urb_context->pipe;
+
+	HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%p",
+		__func__,
+		pipe->logical_pipe_num,
+		urb->status, urb->actual_length,
+		urb);
+
+	/* this urb is not pending anymore */
+	usb_hif_remove_pending_transfer(urb_context);
+
+	do {
+		if (urb->status != 0) {
+			status = A_ECOMM;
+			switch (urb->status) {
+			case -ECONNRESET:
+			case -ENOENT:
+			case -ESHUTDOWN:
+				/* NOTE: no need to spew these errors when
+				 * device is removed
+				 * or urb is killed due to driver shutdown
+				 */
+				status = A_ECANCELED;
+				break;
+			default:
+				HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
+					__func__,
+					pipe->logical_pipe_num,
+					pipe->ep_address,
+					urb->status);
+				break;
+			}
+			break;
+		}
+
+		if (urb->actual_length == 0)
+			break;
+
+		buf = urb_context->buf;
+		/* we are going to pass it up */
+		urb_context->buf = NULL;
+		qdf_nbuf_put_tail(buf, urb->actual_length);
+
+		if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
+			uint8_t *data;
+			uint32_t len;
+			qdf_nbuf_peek_header(buf, &data, &len);
+			debug_dump_bytes(data, len, "hif recv data");
+		}
+		/* note: queue implements a lock */
+		skb_queue_tail(&pipe->io_comp_queue, buf);
+
+		HIF_USB_SCHEDULE_WORK(pipe);
+	} while (false);
+
+	usb_hif_cleanup_recv_urb(urb_context);
+
+	/* Prestart URBs runs out and now start working receive pipe. */
+	if (--pipe->urb_prestart_cnt == 0)
+		usb_hif_start_recv_pipes(pipe->device);
+
+	HIF_DBG("-%s", __func__);
+}
+
+/**
+ * usb_hif_usb_recv_complete() - completion routine for rx urb
+ * @urb: urb for which the completion routine is being called
+ *
+ * Return: none
+ */
+static void usb_hif_usb_recv_complete(struct urb *urb)
+{
+	HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	qdf_nbuf_t buf = NULL;
+	HIF_USB_PIPE *pipe = urb_context->pipe;
+	struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device);
+
+	HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%p",
+		__func__,
+		pipe->logical_pipe_num,
+		urb->status, urb->actual_length,
+		urb);
+
+	/* this urb is not pending anymore */
+	usb_hif_remove_pending_transfer(urb_context);
+
+	do {
+
+		if (urb->status != 0) {
+			status = A_ECOMM;
+			switch (urb->status) {
+#ifdef RX_SG_SUPPORT
+			case -EOVERFLOW:
+				urb->actual_length = HIF_USB_RX_BUFFER_SIZE;
+				status = QDF_STATUS_SUCCESS;
+				break;
+#endif
+			case -ECONNRESET:
+			case -ENOENT:
+			case -ESHUTDOWN:
+				/* NOTE: no need to spew these errors when
+				 * device is removed
+				 * or urb is killed due to driver shutdown
+				 */
+				status = A_ECANCELED;
+				break;
+			default:
+				HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
+					__func__,
+					pipe->logical_pipe_num,
+					pipe->ep_address,
+					urb->status);
+				break;
+			}
+			break;
+		}
+
+		if (urb->actual_length == 0)
+			break;
+
+		buf = urb_context->buf;
+		/* we are going to pass it up */
+		urb_context->buf = NULL;
+		qdf_nbuf_put_tail(buf, urb->actual_length);
+		if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
+			uint8_t *data;
+			uint32_t len;
+			qdf_nbuf_peek_header(buf, &data, &len);
+			debug_dump_bytes(data, len, "hif recv data");
+		}
+
+		/* note: queue implements a lock */
+		skb_queue_tail(&pipe->io_comp_queue, buf);
+		HIF_USB_SCHEDULE_WORK(pipe);
+	} while (false);
+
+	usb_hif_cleanup_recv_urb(urb_context);
+
+	/* Only re-submit URB when STATUS is success and HIF is not at the
+	   suspend state.
+	 */
+	if (QDF_IS_STATUS_SUCCESS(status) && !sc->suspend_state) {
+		if (pipe->urb_cnt >= pipe->urb_cnt_thresh) {
+			/* our free urbs are piling up, post more transfers */
+			usb_hif_post_recv_transfers(pipe,
+						HIF_USB_RX_BUFFER_SIZE);
+		}
+	} else {
+		HIF_ERROR("%s:  pipe: %d, fail to post URB: status(%d) suspend (%d)",
+				__func__,
+				pipe->logical_pipe_num,
+				urb->status,
+				sc->suspend_state);
+	}
+
+	HIF_DBG("-%s", __func__);
+}
+
+/**
+ * usb_hif_usb_recv_bundle_complete() - completion routine for rx bundling urb
+ * @urb: urb for which the completion routine is being called
+ *
+ * Return: none
+ */
+static void usb_hif_usb_recv_bundle_complete(struct urb *urb)
+{
+	HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	qdf_nbuf_t buf = NULL;
+	HIF_USB_PIPE *pipe = urb_context->pipe;
+	uint8_t *netdata, *netdata_new;
+	uint32_t netlen, netlen_new;
+	HTC_FRAME_HDR *HtcHdr;
+	uint16_t payloadLen;
+	qdf_nbuf_t new_skb = NULL;
+
+	HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%p",
+		__func__,
+		pipe->logical_pipe_num,
+		urb->status, urb->actual_length,
+		urb);
+
+	/* this urb is not pending anymore */
+	usb_hif_remove_pending_transfer(urb_context);
+
+	do {
+
+		if (urb->status != 0) {
+			status = A_ECOMM;
+			switch (urb->status) {
+			case -ECONNRESET:
+			case -ENOENT:
+			case -ESHUTDOWN:
+				/* NOTE: no need to spew these errors when
+				 * device is removed
+				 * or urb is killed due to driver shutdown
+				 */
+				status = A_ECANCELED;
+				break;
+			default:
+				HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
+					__func__,
+					pipe->logical_pipe_num,
+					pipe->ep_address,
+					urb->status);
+				break;
+			}
+			break;
+		}
+
+		if (urb->actual_length == 0)
+			break;
+
+		buf = urb_context->buf;
+
+		if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
+			uint8_t *data;
+			uint32_t len;
+			qdf_nbuf_peek_header(buf, &data, &len);
+			debug_dump_bytes(data, len, "hif recv data");
+		}
+
+		qdf_nbuf_peek_header(buf, &netdata, &netlen);
+		netlen = urb->actual_length;
+
+		do {
+			uint16_t frame_len;
+
+			if (IS_FW_CRASH_DUMP(*(uint32_t *) netdata))
+				frame_len = netlen;
+			else {
+				/* Hack into HTC header for bundle processing */
+				HtcHdr = (HTC_FRAME_HDR *) netdata;
+				if (HtcHdr->EndpointID >= ENDPOINT_MAX) {
+					HIF_ERROR("athusb: Rx: invalid EndpointID=%d",
+						HtcHdr->EndpointID);
+					break;
+				}
+
+				payloadLen = HtcHdr->PayloadLen;
+				payloadLen = qdf_le16_to_cpu(payloadLen);
+
+				if (payloadLen > HIF_USB_RX_BUFFER_SIZE) {
+					HIF_ERROR("athusb: payloadLen too long %u",
+						payloadLen);
+					break;
+				}
+				frame_len = (HTC_HDR_LENGTH + payloadLen);
+			}
+
+			if (netlen < frame_len) {
+				HIF_ERROR("athusb: subframe length %d not fitted into bundle packet length %d"
+					, netlen, frame_len);
+				break;
+			}
+
+			/* allocate a new skb and copy */
+			new_skb =
+				qdf_nbuf_alloc(NULL, frame_len, 0, 4, false);
+			if (new_skb == NULL) {
+				HIF_ERROR("athusb: allocate skb (len=%u) failed"
+						, frame_len);
+				break;
+			}
+
+			qdf_nbuf_peek_header(new_skb, &netdata_new,
+						&netlen_new);
+			qdf_mem_copy(netdata_new, netdata, frame_len);
+			qdf_nbuf_put_tail(new_skb, frame_len);
+			skb_queue_tail(&pipe->io_comp_queue, new_skb);
+			new_skb = NULL;
+			netdata += frame_len;
+			netlen -= frame_len;
+		} while (netlen);
+		HIF_USB_SCHEDULE_WORK(pipe);
+	} while (false);
+
+	if (urb_context->buf == NULL)
+		HIF_ERROR("athusb: buffer in urb_context is NULL");
+
+	/* reset urb_context->buf ==> seems not necessary */
+	usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context);
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (pipe->urb_cnt >= pipe->urb_cnt_thresh) {
+			/* our free urbs are piling up, post more transfers */
+			usb_hif_post_recv_bundle_transfers(pipe,
+					pipe->device->rx_bundle_buf_len);
+		}
+	}
+
+	HIF_DBG("-%s", __func__);
+}
+
+/**
+ * usb_hif_post_recv_prestart_transfers() - post prestart recv urbs for a pipe
+ * @recv_pipe: rx data pipe
+ * @prestart_urb: number of prestart recv urbs to be posted
+ *
+ * Return: none
+ */
+static void usb_hif_post_recv_prestart_transfers
+						(HIF_USB_PIPE *recv_pipe,
+						int prestart_urb)
+{
+	HIF_URB_CONTEXT *urb_context;
+	uint8_t *data;
+	uint32_t len;
+	struct urb *urb;
+	int i, usb_status, buffer_length = HIF_USB_RX_BUFFER_SIZE;
+
+	HIF_TRACE("+%s", __func__);
+
+	for (i = 0; i < prestart_urb; i++) {
+		urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
+		if (NULL == urb_context)
+			break;
+
+		urb_context->buf =
+			qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false);
+		if (NULL == urb_context->buf) {
+			usb_hif_cleanup_recv_urb(urb_context);
+			break;
+		}
+
+		qdf_nbuf_peek_header(urb_context->buf, &data, &len);
+
+		urb = urb_context->urb;
+
+		usb_fill_bulk_urb(urb,
+				recv_pipe->device->udev,
+				recv_pipe->usb_pipe_handle,
+				data,
+				buffer_length,
+				usb_hif_usb_recv_prestart_complete,
+				urb_context);
+
+		HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%p",
+			recv_pipe->logical_pipe_num,
+			recv_pipe->usb_pipe_handle,
+			recv_pipe->ep_address, buffer_length,
+			urb_context->buf);
+
+		usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
+
+		usb_status = usb_submit_urb(urb, GFP_ATOMIC);
+
+		if (usb_status) {
+			HIF_ERROR("athusb : usb bulk recv failed %d",
+				usb_status);
+			usb_hif_remove_pending_transfer(urb_context);
+			usb_hif_cleanup_recv_urb(urb_context);
+			break;
+		} else
+			recv_pipe->urb_prestart_cnt++;
+
+	}
+
+	HIF_TRACE("-%s", __func__);
+}
+
+/**
+ * usb_hif_post_recv_transfers() - post recv urbs for a given pipe
+ * @recv_pipe: recv pipe for which urbs need to be posted
+ * @buffer_length: buffer length of the recv urbs
+ *
+ * Return: none
+ */
+static void usb_hif_post_recv_transfers(HIF_USB_PIPE *recv_pipe,
+							int buffer_length)
+{
+	HIF_URB_CONTEXT *urb_context;
+	uint8_t *data;
+	uint32_t len;
+	struct urb *urb;
+	int usb_status;
+
+	HIF_TRACE("+%s", __func__);
+
+	while (1) {
+
+		urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
+		if (NULL == urb_context)
+			break;
+
+		urb_context->buf = qdf_nbuf_alloc(NULL, buffer_length, 0,
+						4, false);
+		if (NULL == urb_context->buf) {
+			usb_hif_cleanup_recv_urb(urb_context);
+			break;
+		}
+
+		qdf_nbuf_peek_header(urb_context->buf, &data, &len);
+
+		urb = urb_context->urb;
+
+		usb_fill_bulk_urb(urb,
+				recv_pipe->device->udev,
+				recv_pipe->usb_pipe_handle,
+				data,
+				buffer_length,
+				usb_hif_usb_recv_complete, urb_context);
+
+		HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%p",
+			recv_pipe->logical_pipe_num,
+			recv_pipe->usb_pipe_handle,
+			recv_pipe->ep_address, buffer_length,
+			urb_context->buf);
+
+		usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
+
+		usb_status = usb_submit_urb(urb, GFP_ATOMIC);
+
+		if (usb_status) {
+			HIF_ERROR("athusb : usb bulk recv failed %d",
+				usb_status);
+			usb_hif_remove_pending_transfer(urb_context);
+			usb_hif_cleanup_recv_urb(urb_context);
+			break;
+		}
+	}
+
+	HIF_TRACE("-%s", __func__);
+
+}
+
+/**
+ * usb_hif_post_recv_bundle_transfers() - post recv urbs for a given pipe
+ * @recv_pipe: recv pipe for which urbs need to be posted
+ * @buffer_length: maximum length of rx bundle
+ *
+ * Return: none
+ */
+static void usb_hif_post_recv_bundle_transfers
+						(HIF_USB_PIPE *recv_pipe,
+						int buffer_length)
+{
+	HIF_URB_CONTEXT *urb_context;
+	uint8_t *data;
+	uint32_t len;
+	struct urb *urb;
+	int usb_status;
+
+	HIF_TRACE("+%s", __func__);
+
+	while (1) {
+
+		urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
+		if (NULL == urb_context)
+			break;
+
+		if (NULL == urb_context->buf) {
+			urb_context->buf =
+			qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false);
+			if (NULL == urb_context->buf) {
+				usb_hif_cleanup_recv_urb(urb_context);
+				break;
+			}
+		}
+
+		qdf_nbuf_peek_header(urb_context->buf, &data, &len);
+
+		urb = urb_context->urb;
+		usb_fill_bulk_urb(urb,
+				recv_pipe->device->udev,
+				recv_pipe->usb_pipe_handle,
+				data,
+				buffer_length,
+				usb_hif_usb_recv_bundle_complete,
+				urb_context);
+
+		HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%p",
+			recv_pipe->logical_pipe_num,
+			recv_pipe->usb_pipe_handle,
+			recv_pipe->ep_address, buffer_length,
+			urb_context->buf);
+
+		usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
+
+		usb_status = usb_submit_urb(urb, GFP_ATOMIC);
+
+		if (usb_status) {
+			HIF_ERROR("athusb : usb bulk recv failed %d",
+				usb_status);
+			usb_hif_remove_pending_transfer(urb_context);
+			usb_hif_free_urb_to_pipe(urb_context->pipe,
+						urb_context);
+			break;
+		}
+
+	}
+
+	HIF_TRACE("-%s", __func__);
+
+}
+
+/**
+ * usb_hif_prestart_recv_pipes() - post prestart recv urbs
+ * @device: HIF device for which prestart recv urbs need to be posted
+ *
+ * Return: none
+ */
+void usb_hif_prestart_recv_pipes(HIF_DEVICE_USB *device)
+{
+	HIF_USB_PIPE *pipe = &device->pipes[HIF_RX_DATA_PIPE];
+
+	/*
+	 * USB driver learn to support bundle or not until the firmware
+	 * download and ready. Only allocate some URBs for control message
+	 * communication during the initial phase then start the final
+	 * working pipe after all information understood.
+	 */
+	usb_hif_post_recv_prestart_transfers(pipe, 8);
+}
+
+/**
+ * usb_hif_start_recv_pipes() - start recv urbs
+ * @device: HIF device for which recv urbs need to be posted
+ *
+ * This function is called after all prestart recv urbs are exhausted
+ *
+ * Return: none
+ */
+void usb_hif_start_recv_pipes(HIF_DEVICE_USB *device)
+{
+	HIF_USB_PIPE *pipe;
+	uint32_t buf_len;
+
+	HIF_ENTER();
+	pipe = &device->pipes[HIF_RX_DATA_PIPE];
+	pipe->urb_cnt_thresh = pipe->urb_alloc / 2;
+
+	HIF_TRACE("Post URBs to RX_DATA_PIPE: %d",
+		device->pipes[HIF_RX_DATA_PIPE].urb_cnt);
+	if (device->is_bundle_enabled) {
+		usb_hif_post_recv_bundle_transfers(pipe,
+					pipe->device->rx_bundle_buf_len);
+	} else {
+		buf_len = HIF_USB_RX_BUFFER_SIZE;
+		usb_hif_post_recv_transfers(pipe, buf_len);
+	}
+
+	HIF_DBG("athusb bulk recv len %d", buf_len);
+
+	if (!hif_usb_disable_rxdata2) {
+		HIF_TRACE("Post URBs to RX_DATA2_PIPE: %d",
+			device->pipes[HIF_RX_DATA2_PIPE].urb_cnt);
+
+		pipe = &device->pipes[HIF_RX_DATA2_PIPE];
+		pipe->urb_cnt_thresh = pipe->urb_alloc / 2;
+		usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE);
+	}
+
+	HIF_EXIT();
+}
+
+/**
+ * usb_hif_submit_ctrl_out() - send out a ctrl urb
+ * @device: HIF device for which urb needs to be posted
+ * @req: request value for the ctrl message
+ * @value: USB message value
+ * @index: USB message index value
+ * @data: pointer to data containing ctrl message to send
+ * @size: size of the control message to send
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+QDF_STATUS usb_hif_submit_ctrl_out(HIF_DEVICE_USB *device,
+						uint8_t req,
+						uint16_t value,
+						uint16_t index,
+						void *data,
+						uint32_t size)
+{
+	int32_t result = 0;
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+	uint8_t *buf = NULL;
+
+	do {
+
+		if (size > 0) {
+			buf = qdf_mem_malloc(size);
+			if (NULL == buf) {
+				ret = QDF_STATUS_E_NOMEM;
+				break;
+			}
+			qdf_mem_copy(buf, (uint8_t *) data, size);
+		}
+
+		HIF_DBG("ctrl-out req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d",
+				req, value, index, size);
+
+		result = usb_control_msg(device->udev,
+					usb_sndctrlpipe(device->udev, 0),
+					req,
+					USB_DIR_OUT | USB_TYPE_VENDOR |
+					USB_RECIP_DEVICE, value, index, buf,
+					size, 2 * HZ);
+
+		if (result < 0) {
+			HIF_ERROR("%s failed,result = %d", __func__, result);
+			ret = QDF_STATUS_E_FAILURE;
+		}
+
+	} while (false);
+
+	if (buf != NULL)
+		qdf_mem_free(buf);
+
+	return ret;
+}
+
+/**
+ * usb_hif_submit_ctrl_in() - recv a resonse to the ctrl message sent out
+ * @device: HIF device for which urb needs to be received
+ * @req: request value for the ctrl message
+ * @value: USB message value
+ * @index: USB message index value
+ * @data: pointer to data containing ctrl message to be received
+ * @size: size of the control message to be received
+ *
+ * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
+ */
+QDF_STATUS usb_hif_submit_ctrl_in(HIF_DEVICE_USB *device,
+						uint8_t req,
+						uint16_t value,
+						uint16_t index,
+						void *data,
+						uint32_t size)
+{
+	int32_t result = 0;
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+	uint8_t *buf = NULL;
+
+	do {
+
+		if (size > 0) {
+			buf = qdf_mem_malloc(size);
+			if (NULL == buf) {
+				ret = QDF_STATUS_E_NOMEM;
+				break;
+			}
+		}
+
+		HIF_DBG("ctrl-in req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d",
+				 req, value, index, size);
+
+		result = usb_control_msg(device->udev,
+					usb_rcvctrlpipe(device->udev, 0),
+					req,
+					USB_DIR_IN | USB_TYPE_VENDOR |
+					USB_RECIP_DEVICE, value, index, buf,
+					size, 2 * HZ);
+
+		if (result < 0) {
+			HIF_ERROR("%s failed, result = %d", __func__, result);
+			ret = QDF_STATUS_E_FAILURE;
+			break;
+		}
+
+		qdf_mem_copy((uint8_t *) data, buf, size);
+
+	} while (false);
+
+	if (buf != NULL)
+		qdf_mem_free(buf);
+
+	return ret;
+}
+
+/**
+ * usb_hif_io_complete() - transmit call back for tx urb
+ * @pipe: pointer to HIF_USB_PIPE
+ *
+ * Return: none
+ */
+void usb_hif_io_complete(HIF_USB_PIPE *pipe)
+{
+	qdf_nbuf_t buf;
+	HIF_DEVICE_USB *device;
+	HTC_FRAME_HDR *HtcHdr;
+	uint8_t *data;
+	uint32_t len;
+	struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device);
+	device = pipe->device;
+
+	HIF_ENTER();
+
+	while ((buf = skb_dequeue(&pipe->io_comp_queue))) {
+		if (pipe->flags & HIF_USB_PIPE_FLAG_TX) {
+			HIF_DBG("+athusb xmit callback " "buf:0x%p", buf);
+			HtcHdr = (HTC_FRAME_HDR *)
+					qdf_nbuf_get_frag_vaddr(buf, 0);
+
+#ifdef ATH_11AC_TXCOMPACT
+/* ATH_11AC_TXCOMPACT does not support High Latency mode */
+#else
+			device->htc_callbacks.txCompletionHandler(device->
+								htc_callbacks.
+								Context, buf,
+								HtcHdr->
+								EndpointID, 0);
+#endif
+			HIF_DBG("-athusb xmit callback");
+		} else {
+			HIF_DBG("+athusb recv callback buf:" "0x%p", buf);
+			qdf_nbuf_peek_header(buf, &data, &len);
+
+			if (IS_FW_CRASH_DUMP(*((uint32_t *) data))) {
+				sc->fw_data = data;
+				sc->fw_data_len = len;
+				device->htc_callbacks.fwEventHandler(
+					device->htc_callbacks.Context,
+					QDF_STATUS_E_USB_ERROR);
+				qdf_nbuf_free(buf);
+			} else {
+				device->htc_callbacks.rxCompletionHandler(
+				device->htc_callbacks.Context, buf,
+				pipe->logical_pipe_num);
+			}
+			HIF_DBG("-athusb recv callback");
+		}
+	}
+
+	HIF_EXIT();
+}
+
+#ifdef HIF_USB_TASKLET
+/**
+ * usb_hif_io_comp_tasklet() - per pipe tasklet routine
+ * @context: pointer to HIF USB pipe
+ *
+ * Return: none
+ */
+void usb_hif_io_comp_tasklet(long unsigned int context)
+{
+	HIF_USB_PIPE *pipe = (HIF_USB_PIPE *) context;
+	usb_hif_io_complete(pipe);
+}
+
+#else
+/**
+ * usb_hif_io_comp_work() - per pipe work queue
+ * @work: pointer to struct work_struct
+ *
+ * Return: none
+ */
+void usb_hif_io_comp_work(struct work_struct *work)
+{
+	HIF_USB_PIPE *pipe = container_of(work, HIF_USB_PIPE, io_complete_work);
+	usb_hif_io_complete(pipe);
+}
+#endif