/*
 * Header file describing the internal (inter-module) DHD interfaces.
 *
 * Provides type definitions and function prototypes used to link the
 * DHD OS, bus, and protocol modules.
 *
 * Copyright (C) 1999-2016, Broadcom Corporation
 * 
 *      Unless you and Broadcom execute a separate written software license
 * agreement governing use of this software, this software is licensed to you
 * under the terms of the GNU General Public License version 2 (the "GPL"),
 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
 * following added to such license:
 * 
 *      As a special exception, the copyright holders of this software give you
 * permission to link this software with independent modules, and to copy and
 * distribute the resulting executable under terms of your choice, provided that
 * you also meet, for each linked independent module, the terms and conditions of
 * the license of that module.  An independent module is a module which is not
 * derived from this software.  The special exception does not apply to any
 * modifications of the software.
 * 
 *      Notwithstanding the above, under no circumstances may you combine this
 * software in any way with any other Broadcom software provided under a license
 * other than the GPL, without Broadcom's express prior written consent.
 *
 * $Id: dhd_msgbuf.c 452261 2014-01-29 19:30:23Z $
 */
#include <typedefs.h>
#include <osl.h>

#include <bcmutils.h>
#include <circularbuf.h>
#include <bcmmsgbuf.h>
#include <bcmendian.h>

#include <dngl_stats.h>
#include <dhd.h>
#include <dhd_proto.h>
#include <dhd_bus.h>
#include <dhd_dbg.h>


#ifdef PROP_TXSTATUS
#include <wlfc_proto.h>
#include <dhd_wlfc.h>
#endif
#include <pcie_core.h>
#include <bcmpcie.h>

#define RETRIES 2		/* # of retries to retrieve matching ioctl response */
#define IOCTL_HDR_LEN	12

#define DEFAULT_RX_BUFFERS_TO_POST	255
#define RXBUFPOST_THRESHOLD			16
#define RX_BUF_BURST				8

#define DHD_STOP_QUEUE_THRESHOLD	24
#define DHD_START_QUEUE_THRESHOLD	32
#define MAX_INLINE_IOCTL_LEN	64	/* anything beyond this len will not be inline reqst */

/* Required for Native to PktId mapping incase of 64bit hosts */
#define MAX_PKTID_ITEMS		(2048)

/* Given packet pointer and physical address, macro should return unique 32 bit pktid */
/* And given 32bit pktid, macro should return packet pointer and physical address */
extern void *pktid_map_init(void *osh, uint32 count);
extern void pktid_map_uninit(void *pktid_map_handle);
extern uint32 pktid_map_unique(void *pktid_map_handle,
	void *pkt, dmaaddr_t physaddr, uint32 physlen, uint32 dma);
extern void *pktid_get_packet(void *pktid_map_handle,
	uint32 id, dmaaddr_t *physaddr, uint32 *physlen);

#define NATIVE_TO_PKTID_INIT(osh, count)	pktid_map_init(osh, count)
#define NATIVE_TO_PKTID_UNINIT(pktid_map_handle)	pktid_map_uninit(pktid_map_handle)

#define NATIVE_TO_PKTID(pktid_map_handle, pkt, pa, pa_len, dma)	\
	pktid_map_unique((pktid_map_handle), (void *)(pkt), (pa), (uint32) (pa_len), (uint32)dma)
#define PKTID_TO_NATIVE(pktid_map_handle, id, pa, pa_len)		\
	pktid_get_packet((pktid_map_handle), (uint32)(id), (void *)&(pa), (uint32 *) &(pa_len))

#define MODX(x, n)	((x) & ((n) -1))
#define align(x, n)	(MODX(x, n) ? ((x) - MODX(x, n) + (n)) : ((x) - MODX(x, n)))
#define RX_DMA_OFFSET	8
#define IOCT_RETBUF_SIZE	(RX_DMA_OFFSET + WLC_IOCTL_MAXLEN)

typedef struct dhd_prot {
	uint32 reqid;
	uint16 hdr_len;
	uint32 lastcmd;
	uint32 pending;
	uint16 rxbufpost;
	uint16 max_rxbufpost;
	uint16 active_tx_count;
	uint16 max_tx_count;
	dmaaddr_t htod_physaddr;
	dmaaddr_t dtoh_physaddr;
	bool txflow_en;
	circularbuf_t *dtohbuf;
	circularbuf_t *htodbuf;
	uint32	rx_dataoffset;
	void*	retbuf;
	dmaaddr_t retbuf_phys;
	void*	ioctbuf;	/* For holding ioct request buf */
	dmaaddr_t ioctbuf_phys;	/* physical address for ioctbuf */
	dhd_mb_ring_t mb_ring_fn;
	void *htod_ring;
	void *dtoh_ring;
	/* Flag to check if splitbuf support is enabled. */
	/* Set to False at dhd_prot_attach. Set to True at dhd_prot_init */
	bool htodsplit;
	bool dtohsplit;
	/* H2D/D2H Ctrl rings */
	dmaaddr_t htod_ctrl_physaddr;	/* DMA mapped physical addr ofr H2D ctrl ring */
	dmaaddr_t dtoh_ctrl_physaddr;	/* DMA mapped phys addr for D2H ctrl ring */
	circularbuf_t *htod_ctrlbuf;	/* Cbuf handle for H2D ctrl ring */
	circularbuf_t *dtoh_ctrlbuf;	/* Cbuf handle for D2H ctrl ring */
	void *htod_ctrl_ring; /* address for H2D control buf */
	void *dtoh_ctrl_ring; /* address for D2H control buf */


	uint16	ioctl_seq_no;
	uint16	data_seq_no;
	void *pktid_map_handle;
} dhd_prot_t;

static int dhdmsgbuf_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd,
	void *buf, uint len, uint8 action);
static int dhd_msgbuf_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd,
	void *buf, uint len, uint8 action);
static int dhdmsgbuf_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len, void* buf, void* retbuf);
static int dhd_msgbuf_init_dtoh(dhd_pub_t *dhd);

static int dhd_msgbuf_rxbuf_post(dhd_pub_t *dhd);
static int dhd_msgbuf_init_htod(dhd_pub_t *dhd);
static int dhd_msgbuf_init_htod_ctrl(dhd_pub_t *dhd);
static int dhd_msgbuf_init_dtoh_ctrl(dhd_pub_t *dhd);
static int dhd_prot_rxbufpost(dhd_pub_t *dhd, uint32 count);
static void dhd_prot_return_rxbuf(dhd_pub_t *dhd, uint16 rxcnt);
static void dhd_prot_rxcmplt_process(dhd_pub_t *dhd, void* buf);
static void dhd_prot_event_process(dhd_pub_t *dhd, uint8* buf, uint16 len);
static void dhd_prot_process_msgtype(dhd_pub_t *dhd, uint8* buf, uint16 len);
static void dhd_process_msgtype(dhd_pub_t *dhd, uint8* buf, uint16 len);

static void dhd_prot_txstatus_process(dhd_pub_t *dhd, void * buf);
static void dhd_prot_ioctcmplt_process(dhd_pub_t *dhd, void * buf);
void* dhd_alloc_circularbuf_space(dhd_pub_t *dhd, circularbuf_t *handle, uint16 msglen, uint path);
static int dhd_fillup_ioct_reqst(dhd_pub_t *dhd, uint16 len, uint cmd, void* buf, int ifidx);
static int dhd_fillup_ioct_reqst_ptrbased(dhd_pub_t *dhd, uint16 len, uint cmd, void* buf,
	int ifidx);
static INLINE void dhd_prot_packet_free(dhd_pub_t *dhd, uint32 pktid);
static INLINE void *dhd_prot_packet_get(dhd_pub_t *dhd, uint32 pktid);

/* Linkage, sets prot link and updates hdrlen in pub */
int dhd_prot_attach(dhd_pub_t *dhd)
{
	uint alloced = 0;

	dhd_prot_t *msg_buf;
	if (!(msg_buf = (dhd_prot_t *)DHD_OS_PREALLOC(dhd, DHD_PREALLOC_PROT,
		sizeof(dhd_prot_t)))) {
			DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
			goto fail;
		}
	memset(msg_buf, 0, sizeof(dhd_prot_t));

	msg_buf->hdr_len = sizeof(ioctl_req_hdr_t) + sizeof(cmn_msg_hdr_t) + sizeof(ret_buf_t);
	msg_buf->dtohbuf = MALLOC(dhd->osh, sizeof(circularbuf_t));
	msg_buf->htodbuf = MALLOC(dhd->osh, sizeof(circularbuf_t));

	memset(msg_buf->dtohbuf, 0, sizeof(circularbuf_t));
	memset(msg_buf->htodbuf, 0, sizeof(circularbuf_t));

	dhd->prot = msg_buf;
	dhd->maxctl = WLC_IOCTL_MAXLEN + msg_buf->hdr_len;

	/* ret buf for ioctl */
	msg_buf->retbuf = DMA_ALLOC_CONSISTENT(dhd->osh, IOCT_RETBUF_SIZE, 4,
		&alloced, &msg_buf->retbuf_phys, NULL);
	if (msg_buf->retbuf ==  NULL) {
		ASSERT(0);
		return BCME_NOMEM;
	}

	ASSERT(MODX((unsigned long)msg_buf->retbuf, 4) == 0);

	msg_buf->ioctbuf = DMA_ALLOC_CONSISTENT(dhd->osh, MSGBUF_MAX_MSG_SIZE, 4,
		&alloced, &msg_buf->ioctbuf_phys, NULL);

	if (msg_buf->ioctbuf ==  NULL) {
		ASSERT(0);
		return BCME_NOMEM;
	}

	ASSERT(MODX((unsigned long)msg_buf->ioctbuf, 4) == 0);

	msg_buf->pktid_map_handle = NATIVE_TO_PKTID_INIT(dhd->osh, MAX_PKTID_ITEMS);
	if (msg_buf->pktid_map_handle == NULL) {
		ASSERT(0);
		return BCME_NOMEM;
	}

	msg_buf->htod_ring = DMA_ALLOC_CONSISTENT(dhd->osh, HOST_TO_DNGL_MSGBUF_SZ, 4,
		&alloced, &msg_buf->htod_physaddr, NULL);
	if (msg_buf->htod_ring ==  NULL) {
		ASSERT(0);
		return BCME_NOMEM;
	}

	ASSERT(MODX((unsigned long)msg_buf->htod_ring, 4) == 0);

	msg_buf->dtoh_ring = DMA_ALLOC_CONSISTENT(dhd->osh, DNGL_TO_HOST_MSGBUF_SZ, 4,
		&alloced, &msg_buf->dtoh_physaddr, NULL);
	if (msg_buf->dtoh_ring ==  NULL) {
		ASSERT(0);
		return BCME_NOMEM;
	}

	ASSERT(MODX((unsigned long)msg_buf->dtoh_ring, 4) == 0);

	/* At this point we assume splitbuf is not supported by dongle */
	msg_buf->htodsplit = FALSE;
	msg_buf->dtohsplit = FALSE;


	return 0;

fail:
#ifndef CONFIG_DHD_USE_STATIC_BUF
	if (msg_buf != NULL)
		MFREE(dhd->osh, msg_buf, sizeof(dhd_prot_t));
#endif /* CONFIG_DHD_USE_STATIC_BUF */
	return BCME_NOMEM;
}

/* Unlink, frees allocated protocol memory (including dhd_prot) */
void dhd_prot_detach(dhd_pub_t *dhd)
{
	 /* Stop the protocol module */
	if (dhd->prot) {

		if (dhd->prot->dtoh_ring) {
			DMA_FREE_CONSISTENT(dhd->osh, dhd->prot->dtoh_ring,
				DNGL_TO_HOST_MSGBUF_SZ, dhd->prot->dtoh_physaddr, NULL);

			dhd->prot->dtoh_ring = NULL;
			PHYSADDRHISET(dhd->prot->dtoh_physaddr, 0);
			PHYSADDRLOSET(dhd->prot->dtoh_physaddr, 0);
		}

		if (dhd->prot->htod_ring) {
			DMA_FREE_CONSISTENT(dhd->osh, dhd->prot->htod_ring,
				HOST_TO_DNGL_MSGBUF_SZ, dhd->prot->htod_physaddr, NULL);

			dhd->prot->htod_ring =  NULL;
			PHYSADDRHISET(dhd->prot->htod_physaddr, 0);
			PHYSADDRLOSET(dhd->prot->htod_physaddr, 0);
		}

		if (dhd->prot->dtohbuf) {
			MFREE(dhd->osh, dhd->prot->dtohbuf, sizeof(circularbuf_t));
			dhd->prot->dtohbuf = NULL;
		}

		if (dhd->prot->htodbuf) {
			MFREE(dhd->osh, dhd->prot->htodbuf, sizeof(circularbuf_t));
			dhd->prot->htodbuf = NULL;
		}

		if (dhd->prot->htod_ctrl_ring) {
			DMA_FREE_CONSISTENT(dhd->osh, dhd->prot->htod_ctrl_ring,
				HOST_TO_DNGL_CTRLRING_SZ, dhd->prot->htod_ctrl_physaddr, NULL);

			dhd->prot->htod_ctrl_ring = NULL;
			dhd->prot->htod_ctrl_physaddr = 0;
		}

		if (dhd->prot->dtoh_ctrl_ring) {
			DMA_FREE_CONSISTENT(dhd->osh, dhd->prot->dtoh_ctrl_ring,
				DNGL_TO_HOST_CTRLRING_SZ, dhd->prot->dtoh_ctrl_physaddr, NULL);

			dhd->prot->dtoh_ctrl_ring = NULL;
			dhd->prot->dtoh_ctrl_physaddr = 0;
		}

		if (dhd->prot->htod_ctrlbuf) {
			MFREE(dhd->osh, dhd->prot->htod_ctrlbuf, sizeof(circularbuf_t));
			dhd->prot->htod_ctrlbuf = NULL;
		}

		if (dhd->prot->dtoh_ctrlbuf) {
			MFREE(dhd->osh, dhd->prot->dtoh_ctrlbuf, sizeof(circularbuf_t));
			dhd->prot->dtoh_ctrlbuf = NULL;
		}

		if (dhd->prot->retbuf) {
			DMA_FREE_CONSISTENT(dhd->osh, dhd->prot->retbuf,
			IOCT_RETBUF_SIZE, dhd->prot->retbuf_phys, NULL);
			dhd->prot->retbuf = NULL;
		}

		if (dhd->prot->ioctbuf) {
			DMA_FREE_CONSISTENT(dhd->osh, dhd->prot->ioctbuf,
			MSGBUF_MAX_MSG_SIZE, dhd->prot->ioctbuf_phys, NULL);

			dhd->prot->ioctbuf = NULL;
		}

		NATIVE_TO_PKTID_UNINIT(dhd->prot->pktid_map_handle);

#ifndef CONFIG_DHD_USE_STATIC_BUF
		MFREE(dhd->osh, dhd->prot, sizeof(dhd_prot_t));
#endif /* CONFIG_DHD_USE_STATIC_BUF */

		dhd->prot = NULL;
	}
}

void
dhd_prot_rx_dataoffset(dhd_pub_t *dhd, uint32 rx_offset)
{
	dhd_prot_t *prot = dhd->prot;
	prot->rx_dataoffset = rx_offset;
}


/* Initialize protocol: sync w/dongle state.
 * Sets dongle media info (iswl, drv_version, mac address).
 */
int dhd_prot_init(dhd_pub_t *dhd)
{
	int ret = 0;
	wlc_rev_info_t revinfo;
	dhd_prot_t *prot = dhd->prot;
	uint32 shared_flags;
	DHD_TRACE(("%s: Enter\n", __FUNCTION__));

	dhd_bus_cmn_readshared(dhd->bus, &prot->max_tx_count, TOTAL_LFRAG_PACKET_CNT);
	if (prot->max_tx_count == 0) {
		/* This can happen if LFrag pool is not enabled for the LFRAG's */
		/* on the dongle. Let's use some default value */
		prot->max_tx_count = 64;
	}
	DHD_INFO(("%s:%d: MAX_TX_COUNT = %d\n", __FUNCTION__, __LINE__, prot->max_tx_count));

	dhd_bus_cmn_readshared(dhd->bus, &prot->max_rxbufpost, MAX_HOST_RXBUFS);
	if (prot->max_rxbufpost == 0) {
		/* This would happen if the dongle firmware is not */
		/* using the latest shared structure template */
		prot->max_rxbufpost = DEFAULT_RX_BUFFERS_TO_POST;
	}
	DHD_INFO(("%s:%d: MAX_RXBUFPOST = %d\n", __FUNCTION__, __LINE__, prot->max_rxbufpost));

	prot->active_tx_count = 0;
	prot->txflow_en = FALSE;
	prot->mb_ring_fn = dhd_bus_get_mbintr_fn(dhd->bus);
	prot->data_seq_no = 0;
	prot->ioctl_seq_no = 0;
	/* initialise msgbufs */
	shared_flags = dhd_bus_get_sharedflags(dhd->bus);
	if (shared_flags & PCIE_SHARED_HTOD_SPLIT) {
		prot->htodsplit = TRUE;
		if (dhd_msgbuf_init_htod_ctrl(dhd) == BCME_NOMEM)
		{
			prot->htodsplit = FALSE;
			DHD_ERROR(("%s:%d: HTOD ctrl ring alloc failed!\n",
				__FUNCTION__, __LINE__));
		}
	}
	if (shared_flags & PCIE_SHARED_DTOH_SPLIT) {
		prot->dtohsplit = TRUE;
		if (dhd_msgbuf_init_dtoh_ctrl(dhd) == BCME_NOMEM)
		{
			prot->dtohsplit = FALSE;
			DHD_ERROR(("%s:%d: DTOH ctrl ring alloc failed!\n",
				__FUNCTION__, __LINE__));
		}
	}
	ret = dhd_msgbuf_init_htod(dhd);
	ret = dhd_msgbuf_init_dtoh(dhd);
	ret = dhd_msgbuf_rxbuf_post(dhd);


	/* Get the device rev info */
	memset(&revinfo, 0, sizeof(revinfo));
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_REVINFO, &revinfo, sizeof(revinfo), FALSE, 0);
	if (ret < 0)
		goto done;
#if defined(WL_CFG80211)
	if (dhd_download_fw_on_driverload)
#endif /* defined(WL_CFG80211) */
		ret = dhd_preinit_ioctls(dhd);
	/* Always assumes wl for now */
	dhd->iswl = TRUE;
done:
	return ret;

}

static INLINE void BCMFASTPATH
dhd_prot_packet_free(dhd_pub_t *dhd, uint32 pktid)
{
	void *PKTBUF;
	dmaaddr_t pa;
	uint32 pa_len;
	PKTBUF = PKTID_TO_NATIVE(dhd->prot->pktid_map_handle, pktid, pa, pa_len);
	DMA_UNMAP(dhd->osh, (uint) pa, (uint) pa_len, DMA_TX, 0, 0);
	PKTFREE(dhd->osh, PKTBUF, TRUE);
	return;
}

static INLINE void * BCMFASTPATH
dhd_prot_packet_get(dhd_pub_t *dhd, uint32 pktid)
{
	void *PKTBUF;
	ulong pa;
	uint32 pa_len;
	PKTBUF = PKTID_TO_NATIVE(dhd->prot->pktid_map_handle, pktid, pa, pa_len);
	DMA_UNMAP(dhd->osh, (uint) pa, (uint) pa_len, DMA_RX, 0, 0);
	return PKTBUF;
}

static int BCMFASTPATH
dhd_msgbuf_rxbuf_post(dhd_pub_t *dhd)
{
	dhd_prot_t *prot = dhd->prot;
	unsigned long flags;
	uint32 fillbufs;
	uint32 i;
	fillbufs = prot->max_rxbufpost - prot->rxbufpost;

	for (i = 0; i < fillbufs; ) {
		int retcount;
		uint32 buf_count = (fillbufs - i) > RX_BUF_BURST ? RX_BUF_BURST : (fillbufs - i);

		flags = dhd_os_spin_lock(dhd);
		retcount = dhd_prot_rxbufpost(dhd, buf_count);
		if (retcount > 0) {
			prot->rxbufpost += (uint16)retcount;
			i += (uint16)retcount;
			dhd_os_spin_unlock(dhd, flags);
		} else {
			dhd_os_spin_unlock(dhd, flags);
			break;
		}
	}

	return 0;
}

static int BCMFASTPATH
dhd_prot_rxbufpost(dhd_pub_t *dhd, uint32 count)
{
	void *p;
	uint16 pktsz = 2048;
	uint32 i;
	rxdesc_msghdr_t *rxbuf_post;
	rx_lenptr_tup_t *rx_tup;
	dmaaddr_t physaddr;
	uint32 pktlen;
	uint32 msglen = sizeof(rxdesc_msghdr_t) + count * sizeof(rx_lenptr_tup_t);

	dhd_prot_t *prot = dhd->prot;
	circularbuf_t *htod_msgbuf = (circularbuf_t *)prot->htodbuf;

	rxbuf_post = (rxdesc_msghdr_t *)dhd_alloc_circularbuf_space(dhd,
		htod_msgbuf, (uint16)msglen, HOST_TO_DNGL_DATA);
	if (rxbuf_post == NULL) {
		DHD_INFO(("%s:%d: HTOD Msgbuf Not available\n",
			__FUNCTION__, __LINE__));
		return -1;
	}

	/* CMN msg header */
	rxbuf_post->msg.msglen = htol16((uint16)msglen);
	rxbuf_post->msg.msgtype = MSG_TYPE_RXBUF_POST;
	rxbuf_post->msg.ifidx = 0;
	rxbuf_post->msg.u.seq.seq_no = htol16(++prot->data_seq_no);

	/* RX specific hdr */
	rxbuf_post->rsvd0 = 0;
	rxbuf_post->rsvd1 = 0;
	rxbuf_post->descnt = (uint8)count;

	rx_tup = (rx_lenptr_tup_t *) &(rxbuf_post->rx_tup[0]);

	for (i = 0; i < count; i++) {
		if ((p = PKTGET(dhd->osh, pktsz, FALSE)) == NULL) {
			DHD_ERROR(("%s:%d: PKTGET for rxbuf failed\n", __FUNCTION__, __LINE__));
			printf("%s:%d: PKTGET for rxbuf failed. Need to handle this gracefully\n",
				__FUNCTION__, __LINE__);
			return -1;
		}

		pktlen = PKTLEN(dhd->osh, p);
		physaddr = DMA_MAP(dhd->osh, PKTDATA(dhd->osh, p), pktlen, DMA_RX, 0, 0);
		if (physaddr == 0) {
			DHD_ERROR(("Something really bad, unless 0 is a valid phyaddr\n"));
			ASSERT(0);
		}
		/* Each bufid-len-ptr tuple */
		rx_tup->rxbufid = htol32(NATIVE_TO_PKTID(dhd->prot->pktid_map_handle,
			p, physaddr, pktlen, DMA_RX));
		rx_tup->len = htol16((uint16)PKTLEN(dhd->osh, p));
		rx_tup->rsvd2 = 0;
		rx_tup->ret_buf.high_addr = htol32(PHYSADDRHI(physaddr));
		rx_tup->ret_buf.low_addr  = htol32(PHYSADDRLO(physaddr));

		rx_tup++;
	}

	/* Since, we are filling the data directly into the bufptr obtained
	 * from the msgbuf, we can directly call the write_complete
	 */
	circularbuf_write_complete(htod_msgbuf, (uint16)msglen);

	return count;
}

void BCMFASTPATH
dhd_msgbuf_ringbell(void *ctx)
{
	dhd_pub_t *dhd = (dhd_pub_t *) ctx;
	dhd_prot_t *prot = dhd->prot;
	circularbuf_t *htod_msgbuf = (circularbuf_t *)prot->htodbuf;

	/* Following will take care of writing both the Write and End pointers (32 bits) */
	dhd_bus_cmn_writeshared(dhd->bus, &(CIRCULARBUF_WRITE_PTR(htod_msgbuf)),
		sizeof(uint32), HOST_TO_DNGL_WPTR);

	prot->mb_ring_fn(dhd->bus, *(uint32 *) &(CIRCULARBUF_WRITE_PTR(htod_msgbuf)));
}

void BCMFASTPATH
dhd_ctrlbuf_ringbell(void *ctx)
{
	dhd_pub_t *dhd = (dhd_pub_t *) ctx;
	dhd_prot_t *prot = dhd->prot;
	circularbuf_t *htod_ctrlbuf = (circularbuf_t *)prot->htod_ctrlbuf;

	/* Following will take care of writing both the Write and End pointers (32 bits) */
	dhd_bus_cmn_writeshared(dhd->bus, &(CIRCULARBUF_WRITE_PTR(htod_ctrlbuf)),
		sizeof(uint32), HTOD_CTRL_WPTR);

	prot->mb_ring_fn(dhd->bus, *(uint32 *) &(CIRCULARBUF_WRITE_PTR(htod_ctrlbuf)));
}

static int
dhd_msgbuf_init_htod(dhd_pub_t *dhd)
{
	dhd_prot_t *prot = dhd->prot;
	circularbuf_t *htod_msgbuf = (circularbuf_t *)prot->htodbuf;

	circularbuf_init(htod_msgbuf, prot->htod_ring, HOST_TO_DNGL_MSGBUF_SZ);
	circularbuf_register_cb(htod_msgbuf, dhd_msgbuf_ringbell, (void *)dhd);
	dhd_bus_cmn_writeshared(dhd->bus, &prot->htod_physaddr,
		sizeof(prot->htod_physaddr), HOST_TO_DNGL_BUF_ADDR);

	dhd_bus_cmn_writeshared(dhd->bus, &(CIRCULARBUF_WRITE_PTR(htod_msgbuf)),
		sizeof(uint32), HOST_TO_DNGL_WPTR);

	return 0;

}
static int
dhd_msgbuf_init_dtoh(dhd_pub_t *dhd)
{
	dhd_prot_t *prot = dhd->prot;
	circularbuf_t *dtoh_msgbuf = (circularbuf_t *)prot->dtohbuf;

	prot->rxbufpost = 0;
	circularbuf_init(dtoh_msgbuf, prot->dtoh_ring, DNGL_TO_HOST_MSGBUF_SZ);
	dhd_bus_cmn_writeshared(dhd->bus, &prot->dtoh_physaddr,
		sizeof(prot->dtoh_physaddr), DNGL_TO_HOST_BUF_ADDR);

	dhd_bus_cmn_writeshared(dhd->bus, &CIRCULARBUF_READ_PTR(dtoh_msgbuf),
		sizeof(uint16), DNGL_TO_HOST_RPTR);

	/* One dummy interrupt to the device. This would trigger */
	/* the msgbuf initializations at the device side.        */
	/* Send dummy intr to device here, only if support for split data/ctrl rings is disabled */
	/* Else send the dummy initialization intr at dtoh ctrl buf init */

	dhd_bus_ringbell(dhd->bus, PCIE_INTB);
	return 0;
}

/* Allocate space for HTOD ctrl ring on host and initialize handle/doorbell for the same */
static int dhd_msgbuf_init_htod_ctrl(dhd_pub_t *dhd)
{
	uint alloced;
	dhd_prot_t *prot = dhd->prot;
	prot->htod_ctrlbuf = MALLOC(dhd->osh, sizeof(circularbuf_t));
	memset(prot->htod_ctrlbuf, 0, sizeof(circularbuf_t));

	prot->htod_ctrl_ring = DMA_ALLOC_CONSISTENT(dhd->osh, HOST_TO_DNGL_CTRLRING_SZ, 4,
		&alloced, &prot->htod_ctrl_physaddr, NULL);
	if (prot->htod_ctrl_ring ==  NULL) {
		return BCME_NOMEM;
	}

	ASSERT(MODX((unsigned long)prot->htod_ctrl_ring, 4) == 0);

	circularbuf_init(prot->htod_ctrlbuf, prot->htod_ctrl_ring, HOST_TO_DNGL_CTRLRING_SZ);
	circularbuf_register_cb(prot->htod_ctrlbuf, dhd_ctrlbuf_ringbell, (void *)dhd);
	dhd_bus_cmn_writeshared(dhd->bus, &prot->htod_ctrl_physaddr,
		sizeof(prot->htod_ctrl_physaddr), HOST_TO_DNGL_CTRLBUF_ADDR);

	dhd_bus_cmn_writeshared(dhd->bus, &(CIRCULARBUF_WRITE_PTR(prot->htod_ctrlbuf)),
		sizeof(uint32), HTOD_CTRL_WPTR);

	return 0;
}
/* Allocate space for DTOH ctrl ring on host and initialize msgbuf handle in dhd_prot_t */
static int dhd_msgbuf_init_dtoh_ctrl(dhd_pub_t *dhd)
{
	uint alloced;
	dhd_prot_t *prot = dhd->prot;
	prot->dtoh_ctrlbuf = MALLOC(dhd->osh, sizeof(circularbuf_t));
	memset(prot->dtoh_ctrlbuf, 0, sizeof(circularbuf_t));

	prot->dtoh_ctrl_ring = DMA_ALLOC_CONSISTENT(dhd->osh, DNGL_TO_HOST_CTRLRING_SZ, 4,
		&alloced, &prot->dtoh_ctrl_physaddr, NULL);
	if (prot->dtoh_ctrl_ring ==  NULL) {
		return BCME_NOMEM;
	}
	ASSERT(MODX((unsigned long)prot->dtoh_ctrl_ring, 4) == 0);

	circularbuf_init(prot->dtoh_ctrlbuf, prot->dtoh_ctrl_ring, DNGL_TO_HOST_CTRLRING_SZ);
	dhd_bus_cmn_writeshared(dhd->bus, &prot->dtoh_ctrl_physaddr,
		sizeof(prot->dtoh_ctrl_physaddr), DNGL_TO_HOST_CTRLBUF_ADDR);

	dhd_bus_cmn_writeshared(dhd->bus, &(CIRCULARBUF_READ_PTR(prot->dtoh_ctrlbuf)),
		sizeof(uint32), DTOH_CTRL_RPTR);
	return 0;
}

int BCMFASTPATH
dhd_prot_process_msgbuf(dhd_pub_t *dhd)
{
	dhd_prot_t *prot = dhd->prot;
	circularbuf_t *dtoh_msgbuf = (circularbuf_t *)prot->dtohbuf;

	dhd_bus_cmn_readshared(dhd->bus, &CIRCULARBUF_WRITE_PTR(dtoh_msgbuf), DNGL_TO_HOST_WPTR);

	/* Process all the messages - DTOH direction */
	while (TRUE) {
		uint8 *src_addr;
		uint16 src_len;

		src_addr = circularbuf_get_read_ptr(dtoh_msgbuf, &src_len);
		if (src_addr == NULL)
			break;

		/* Prefetch data to populate the cache */
		OSL_PREFETCH(src_addr);

		dhd_prot_process_msgtype(dhd, src_addr, src_len);
		circularbuf_read_complete(dtoh_msgbuf, src_len);

		/* Write to dngl rd ptr */
		dhd_bus_cmn_writeshared(dhd->bus, &CIRCULARBUF_READ_PTR(dtoh_msgbuf),
			sizeof(uint16), DNGL_TO_HOST_RPTR);
	}

	return 0;
}

int BCMFASTPATH
dhd_prot_process_ctrlbuf(dhd_pub_t * dhd)
{
	dhd_prot_t *prot = dhd->prot;
	circularbuf_t *dtoh_ctrlbuf = (circularbuf_t *)prot->dtoh_ctrlbuf;

	dhd_bus_cmn_readshared(dhd->bus, &CIRCULARBUF_WRITE_PTR(dtoh_ctrlbuf), DTOH_CTRL_WPTR);

	/* Process all the messages - DTOH direction */
	while (TRUE) {
		uint8 *src_addr;
		uint16 src_len;

		src_addr = circularbuf_get_read_ptr(dtoh_ctrlbuf, &src_len);
		if (src_addr == NULL) {
			break;
		}
		/* Prefetch data to populate the cache */
		OSL_PREFETCH(src_addr);

		dhd_prot_process_msgtype(dhd, src_addr, src_len);
		circularbuf_read_complete(dtoh_ctrlbuf, src_len);

		/* Write to dngl rd ptr */
		dhd_bus_cmn_writeshared(dhd->bus, &CIRCULARBUF_READ_PTR(dtoh_ctrlbuf),
			sizeof(uint16), DTOH_CTRL_RPTR);
	}

	return 0;
}

static void BCMFASTPATH
dhd_prot_process_msgtype(dhd_pub_t *dhd, uint8* buf, uint16 len)
{
	dhd_prot_t *prot = dhd->prot;
	uint32 cur_dma_len = 0;

	DHD_TRACE(("%s: process msgbuf of len %d\n", __FUNCTION__, len));

	while (len > 0) {
		ASSERT(len > (sizeof(cmn_msg_hdr_t) + prot->rx_dataoffset));
		if (prot->rx_dataoffset) {
			cur_dma_len = *(uint32 *) buf;
			ASSERT(cur_dma_len <= len);
			buf += prot->rx_dataoffset;
			len -= (uint16)prot->rx_dataoffset;
		}
		else {
			cur_dma_len = len;
		}
		dhd_process_msgtype(dhd, buf, (uint16)cur_dma_len);
		len -= (uint16)cur_dma_len;
		buf += cur_dma_len;
	}
}


static void
dhd_check_sequence_num(cmn_msg_hdr_t *msg)
{
	static uint32 ioctl_seq_no_old = 0;
	static uint32 data_seq_no_old = 0;

	switch (msg->msgtype) {
		case MSG_TYPE_IOCTL_CMPLT:
			if (msg->u.seq.seq_no && msg->u.seq.seq_no != (ioctl_seq_no_old + 1))
			{
				DHD_ERROR(("Error in IOCTL MsgBuf Sequence number!!"
				"new seq no %u, old seq number %u\n",
				msg->u.seq.seq_no, ioctl_seq_no_old));
			}
			ioctl_seq_no_old  = msg->u.seq.seq_no;
			break;

		case MSG_TYPE_RX_CMPLT:
		case MSG_TYPE_WL_EVENT :
		case MSG_TYPE_TX_STATUS :
		case MSG_TYPE_LOOPBACK:
			if (msg->u.seq.seq_no && msg->u.seq.seq_no != (data_seq_no_old + 1))
			{
				DHD_ERROR(("Error in DATA MsgBuf Sequence number!!"
					"new seq no %u	 old seq number %u\n",
					msg->u.seq.seq_no, data_seq_no_old));
			}
			data_seq_no_old = msg->u.seq.seq_no;
			break;

		default:
			printf("Unknown MSGTYPE in %s \n", __FUNCTION__);
			break;

	}
}

static void BCMFASTPATH
dhd_process_msgtype(dhd_pub_t *dhd, uint8* buf, uint16 len)
{
	uint16 pktlen = len;
	uint16 msglen;
	uint8 msgtype;
	cmn_msg_hdr_t *msg = NULL;
	while (pktlen > 0) {
		msg = (cmn_msg_hdr_t *)buf;
		msgtype = msg->msgtype;
		msglen = msg->msglen;

		/* Prefetch data to populate the cache */
		OSL_PREFETCH(buf+msglen);

		dhd_check_sequence_num(msg);

		DHD_INFO(("msgtype %d, msglen is %d \n", msgtype, msglen));
		switch (msgtype) {
			case MSG_TYPE_IOCTL_CMPLT:
				DHD_INFO((" MSG_TYPE_IOCTL_CMPLT\n"));
				dhd_prot_ioctcmplt_process(dhd, buf);
				break;
			case MSG_TYPE_RX_CMPLT:
				DHD_INFO((" MSG_TYPE_RX_CMPLT\n"));
				dhd_prot_rxcmplt_process(dhd, buf);
				break;
			case MSG_TYPE_WL_EVENT:
				DHD_INFO((" MSG_TYPE_WL_EVENT\n"));
				dhd_prot_event_process(dhd, buf, msglen);
				break;
			case MSG_TYPE_TX_STATUS:
				DHD_INFO((" MSG_TYPE_TX_STATUS\n"));
				dhd_prot_txstatus_process(dhd, buf);
				break;
			case MSG_TYPE_LOOPBACK:
				bcm_print_bytes("LPBK RESP: ", (uint8 *)msg, msglen);
				DHD_ERROR((" MSG_TYPE_LOOPBACK, len %d\n", msglen));
				break;
			default :
				DHD_ERROR(("Unknown state in %s,"
				"rxoffset %d\n", __FUNCTION__, dhd->prot->rx_dataoffset));
				bcm_print_bytes("UNKNOWN msg", (uchar *)msg, msglen);
				break;

		}

		DHD_INFO(("pktlen is %d, msglen is %d\n", pktlen, msglen));
		if (pktlen < msglen)  {
			return;
		}
		pktlen = pktlen - msglen;
		buf = buf + msglen;
	}
}
static void
dhd_prot_ioctcmplt_process(dhd_pub_t *dhd, void * buf)
{
	uint32 retlen, status, inline_data = 0;
	uint32 pkt_id, xt_id;

	ioct_resp_hdr_t * ioct_resp = (ioct_resp_hdr_t *)buf;
	retlen = ltoh32(ioct_resp->ret_len);
	pkt_id = ltoh32(ioct_resp->pkt_id);
	xt_id = ltoh32(ioct_resp->xt_id);
	status = ioct_resp->status;
	if (retlen <= 4) {
		inline_data = ltoh32(ioct_resp->inline_data);
	} else {
		OSL_CACHE_INV((void *) dhd->prot->retbuf, retlen);
	}
	DHD_CTL(("status from the pkt_id is %d, ioctl is %d, ret_len is %d, xt_id %d\n",
		pkt_id, status, retlen, xt_id));

	if (retlen == 0)
		retlen = 1;

	dhd_bus_update_retlen(dhd->bus, retlen, pkt_id, status, inline_data);
	dhd_os_ioctl_resp_wake(dhd);
}

static void BCMFASTPATH
dhd_prot_txstatus_process(dhd_pub_t *dhd, void * buf)
{
	dhd_prot_t *prot = dhd->prot;
	txstatus_hdr_t * txstatus;
	unsigned long flags;
	uint32 pktid;

	/* locks required to protect circular buffer accesses */
	flags = dhd_os_spin_lock(dhd);

	txstatus = (txstatus_hdr_t *)buf;
	pktid = ltoh32(txstatus->pktid);

	prot->active_tx_count--;

	ASSERT(pktid != 0);
	dhd_prot_packet_free(dhd, pktid);

	if (prot->txflow_en == TRUE) {
		/* If the pktpool availability is above the high watermark, */
		/* let's resume the flow of packets to dongle. */
		if ((prot->max_tx_count - prot->active_tx_count) > DHD_START_QUEUE_THRESHOLD) {
			dhd_bus_start_queue(dhd->bus);
			prot->txflow_en = FALSE;
		}
	}

	dhd_os_spin_unlock(dhd, flags);
	return;
}

static void
dhd_prot_event_process(dhd_pub_t *dhd, uint8* buf, uint16 len)
{
	wl_event_hdr_t * evnt;
	uint32 bufid;
	uint16 buflen;
	int ifidx = 0;
	uint pkt_count = 1;
	void* pkt;
	unsigned long flags;

	/* Event complete header */
	evnt = (wl_event_hdr_t *)buf;
	bufid = ltoh32(evnt->rxbufid);
	buflen = ltoh16(evnt->retbuf_len);

	/* Post another rxbuf to the device */
	dhd_prot_return_rxbuf(dhd, 1);

	/* locks required to protect pktid_map */
	flags = dhd_os_spin_lock(dhd);

	pkt = dhd_prot_packet_get(dhd, ltoh32(bufid));

	dhd_os_spin_unlock(dhd, flags);

	/* DMA RX offset updated through shared area */
	if (dhd->prot->rx_dataoffset)
		PKTPULL(dhd->osh, pkt, dhd->prot->rx_dataoffset);

	PKTSETLEN(dhd->osh, pkt, buflen);

	/* remove WL header */
	PKTPULL(dhd->osh, pkt, 4); /* WL Header */

	dhd_bus_rx_frame(dhd->bus, pkt, ifidx, pkt_count);
}

static void BCMFASTPATH
dhd_prot_rxcmplt_process(dhd_pub_t *dhd, void* buf)
{
	rxcmplt_hdr_t *rxcmplt_h;
	rxcmplt_tup_t *rx_tup;
	uint32 bufid;
	uint16 buflen, cmpltcnt;
	uint16 data_offset;             /* offset at which data starts */
	void * pkt;
	int ifidx = 0;
	uint pkt_count = 0;
	uint32 i;
	void *pkthead = NULL;
	void *pkttail = NULL;

	/* RXCMPLT HDR */
	rxcmplt_h = (rxcmplt_hdr_t *)buf;
	cmpltcnt = ltoh16(rxcmplt_h->rxcmpltcnt);

	/* Post another set of rxbufs to the device */
	dhd_prot_return_rxbuf(dhd, cmpltcnt);
	ifidx = rxcmplt_h->msg.ifidx;

	rx_tup = (rxcmplt_tup_t *) &(rxcmplt_h->rx_tup[0]);
	for (i = 0; i < cmpltcnt; i++) {
		unsigned long flags;

		bufid = ltoh32(rx_tup->rxbufid);
		buflen = ltoh16(rx_tup->retbuf_len);

		/* offset from which data starts is populated in rxstatus0 */
		data_offset = ltoh16(rx_tup->data_offset);

		/* locks required to protect pktid_map */
		flags = dhd_os_spin_lock(dhd);
		pkt = dhd_prot_packet_get(dhd, ltoh32(bufid));
		dhd_os_spin_unlock(dhd, flags);

		/* data_offset from buf start */
		if (data_offset) {
			/* data offset given from dongle after split rx */
			PKTPULL(dhd->osh, pkt, data_offset); /* data offset */
		} else {
			/* DMA RX offset updated through shared area */
			if (dhd->prot->rx_dataoffset)
				PKTPULL(dhd->osh, pkt, dhd->prot->rx_dataoffset);
		}

		/* Actual length of the packet */
		PKTSETLEN(dhd->osh, pkt, buflen);

		/* remove WL header */
		PKTPULL(dhd->osh, pkt, 4); /* WL Header */

		pkt_count++;
		rx_tup++;

		/* Chain the packets and release in one shot to dhd_linux. */
		/* Interface and destination checks are not required here. */
		PKTSETNEXT(dhd->osh, pkt, NULL);
		if (pkttail == NULL) {
			pkthead = pkttail = pkt;
		} else {
			PKTSETNEXT(dhd->osh, pkttail, pkt);
			pkttail = pkt;
		}
	}

	if (pkthead) {
		/* Release the packets to dhd_linux */
		dhd_bus_rx_frame(dhd->bus, pkthead, ifidx, pkt_count);
	}
}
/* Stop protocol: sync w/dongle state. */
void dhd_prot_stop(dhd_pub_t *dhd)
{
	/* nothing to do for pcie */
}

/* Add any protocol-specific data header.
 * Caller must reserve prot_hdrlen prepend space.
 */
void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *PKTBUF)
{
	return;
}

#define PKTBUF pktbuf

int BCMFASTPATH
dhd_prot_txdata(dhd_pub_t *dhd, void *PKTBUF, uint8 ifidx)
{
	unsigned long flags;
	dhd_prot_t *prot = dhd->prot;
	circularbuf_t *htod_msgbuf = (circularbuf_t *)prot->htodbuf;
	txdescr_msghdr_t *txdesc = NULL;
	tx_lenptr_tup_t *tx_tup;
	dmaaddr_t physaddr;
	uint8 *pktdata;
	uint8 *etherhdr;
	uint16 pktlen;
	uint16 hdrlen;
	uint32 pktid;

	/* Extract the data pointer and length information */
	pktdata = PKTDATA(dhd->osh, PKTBUF);
	pktlen  = (uint16)PKTLEN(dhd->osh, PKTBUF);

	/* Extract the ethernet header and adjust the data pointer and length */
	etherhdr = pktdata;
	pktdata += ETHER_HDR_LEN;
	pktlen  -= ETHER_HDR_LEN;


	flags = dhd_os_spin_lock(dhd);

	/* Map the data pointer to a DMA-able address */
	physaddr = DMA_MAP(dhd->osh, pktdata, pktlen, DMA_TX, 0, 0);
	if (physaddr == 0) {
		DHD_ERROR(("Something really bad, unless 0 is a valid phyaddr\n"));
		ASSERT(0);
	}

	/* Create a unique 32-bit packet id */
	pktid = NATIVE_TO_PKTID(dhd->prot->pktid_map_handle, PKTBUF, physaddr, pktlen, DMA_TX);

	/* Reserve space in the circular buffer */
	hdrlen =  sizeof(txdescr_msghdr_t) + (1 * sizeof(tx_lenptr_tup_t));

	txdesc = (txdescr_msghdr_t *)dhd_alloc_circularbuf_space(dhd,
		htod_msgbuf, hdrlen, HOST_TO_DNGL_DATA);
	if (txdesc == NULL) {
		dhd_prot_packet_free(dhd, pktid);
		dhd_os_spin_unlock(dhd, flags);

		DHD_INFO(("%s:%d: HTOD Msgbuf Not available TxCount = %d\n",
			__FUNCTION__, __LINE__, prot->active_tx_count));
		return BCME_NORESOURCE;
	}

	/* Form the Tx descriptor message buffer */

	/* Common message hdr */
	txdesc->txcmn.msg.msglen = htol16(hdrlen);
	txdesc->txcmn.msg.msgtype = MSG_TYPE_TX_POST;
	txdesc->txcmn.msg.u.seq.seq_no = htol16(++prot->data_seq_no);

	/* Ethernet header */
	txdesc->txcmn.hdrlen = htol16(ETHER_HDR_LEN);
	bcopy(etherhdr, txdesc->txhdr, ETHER_HDR_LEN);

	/* Packet ID */
	txdesc->txcmn.pktid = htol32(pktid);

	/* Descriptor count - Linux needs only one */
	txdesc->txcmn.descrcnt = 0x1;

	tx_tup = (tx_lenptr_tup_t *) &(txdesc->tx_tup);

	/* Descriptor - 0 */
	tx_tup->pktlen = htol16(pktlen);
	tx_tup->ret_buf.high_addr = htol32(PHYSADDRHI(physaddr));
	tx_tup->ret_buf.low_addr  = htol32(PHYSADDRLO(physaddr));
	/* Descriptor 1 - should be filled here - if required */

	/* Reserved for future use */
	txdesc->txcmn.priority = (uint8)PKTPRIO(PKTBUF);
	txdesc->txcmn.flowid   = 0;
	txdesc->txcmn.msg.ifidx = ifidx;

	/* Since, we are filling the data directly into the bufptr obtained
	 * from the circularbuf, we can directly call the write_complete
	 */
	circularbuf_write_complete(htod_msgbuf, hdrlen);

	prot->active_tx_count++;

	/* If we have accounted for most of the lfrag packets on the dongle, */
	/* it's time to stop the packet flow - Assert flow control. */
	if ((prot->max_tx_count - prot->active_tx_count) < DHD_STOP_QUEUE_THRESHOLD) {
		dhd_bus_stop_queue(dhd->bus);
		prot->txflow_en = TRUE;
	}

	dhd_os_spin_unlock(dhd, flags);

	return BCME_OK;
}

#undef PKTBUF	/* Only defined in the above routine */
int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pkt, uchar *buf, uint *len)
{
	return 0;
}

static void BCMFASTPATH
dhd_prot_return_rxbuf(dhd_pub_t *dhd, uint16 rxcnt)
{
	dhd_prot_t *prot = dhd->prot;

	prot->rxbufpost -= rxcnt;
	if (prot->rxbufpost <= (prot->max_rxbufpost - RXBUFPOST_THRESHOLD))
		dhd_msgbuf_rxbuf_post(dhd);

	return;
}

/* Use protocol to issue ioctl to dongle */
int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len)
{
	dhd_prot_t *prot = dhd->prot;
	int ret = -1;
	uint8 action;

	if ((dhd->busstate == DHD_BUS_DOWN) || dhd->hang_was_sent) {
		DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__));
		goto done;
	}

	DHD_TRACE(("%s: Enter\n", __FUNCTION__));

	ASSERT(len <= WLC_IOCTL_MAXLEN);

	if (len > WLC_IOCTL_MAXLEN)
		goto done;

	if (prot->pending == TRUE) {
		DHD_ERROR(("packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
			ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
			(unsigned long)prot->lastcmd));
		if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) {
			DHD_TRACE(("iovar cmd=%s\n", (char*)buf));
		}
		goto done;
	}

	prot->pending = TRUE;
	prot->lastcmd = ioc->cmd;
	action = ioc->set;
	if (action & WL_IOCTL_ACTION_SET) {
		ret = dhd_msgbuf_set_ioctl(dhd, ifidx, ioc->cmd, buf, len, action);
	} else {
		ret = dhdmsgbuf_query_ioctl(dhd, ifidx, ioc->cmd, buf, len, action);
		if (ret > 0)
			ioc->used = ret;
	}
	/* Too many programs assume ioctl() returns 0 on success */
	if (ret >= 0)
		ret = 0;
	else {
		DHD_INFO(("%s: status ret value is %d \n", __FUNCTION__, ret));
		dhd->dongle_error = ret;
	}

	/* Intercept the wme_dp ioctl here */
	if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) {
		int slen, val = 0;

		slen = strlen("wme_dp") + 1;
		if (len >= (int)(slen + sizeof(int)))
			bcopy(((char *)buf + slen), &val, sizeof(int));
		dhd->wme_dp = (uint8) ltoh32(val);
	}

	prot->pending = FALSE;

done:
	return ret;

}

int
dhdmsgbuf_lpbk_req(dhd_pub_t *dhd, uint len)
{
	unsigned long flags;
	dhd_prot_t *prot = dhd->prot;
	circularbuf_t *htod_msgbuf;

	ioct_reqst_hdr_t *ioct_rqst;

	uint16 hdrlen = sizeof(ioct_reqst_hdr_t);
	uint16 msglen = len + hdrlen;

	if (dhd->prot->htodsplit)
		htod_msgbuf = (circularbuf_t *) prot->htod_ctrlbuf;
	else
		htod_msgbuf = (circularbuf_t *) prot->htodbuf;

	if (msglen  > MSGBUF_MAX_MSG_SIZE)
		msglen = MSGBUF_MAX_MSG_SIZE;

	msglen = align(msglen, 4);

	/* locks required to protect circular buffer accesses */
	flags = dhd_os_spin_lock(dhd);

	if (dhd->prot->htodsplit) {
		ioct_rqst = (ioct_reqst_hdr_t *)dhd_alloc_circularbuf_space(dhd,
			htod_msgbuf, msglen, HOST_TO_DNGL_CTRL);
	}
	else {
		ioct_rqst = (ioct_reqst_hdr_t *)dhd_alloc_circularbuf_space(dhd,
			htod_msgbuf, msglen, HOST_TO_DNGL_DATA);
	}

	if (ioct_rqst == NULL) {
		dhd_os_spin_unlock(dhd, flags);
		return 0;
	}

	{
		uint8 *ptr;
		uint16 i;

		ptr = (uint8 *)ioct_rqst;
		for (i = 0; i < msglen; i++) {
			ptr[i] = i % 256;
		}
	}


	/* Common msg buf hdr */
	ioct_rqst->msg.msglen = htol16(msglen);
	ioct_rqst->msg.msgtype = MSG_TYPE_LOOPBACK;
	ioct_rqst->msg.ifidx = 0;
	ioct_rqst->msg.u.seq.seq_no = htol16(++prot->data_seq_no);

	bcm_print_bytes("LPBK REQ: ", (uint8 *)ioct_rqst, msglen);

	circularbuf_write_complete(htod_msgbuf, msglen);

	dhd_os_spin_unlock(dhd, flags);

	return 0;
}


static int
dhdmsgbuf_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
{
	dhd_prot_t *prot = dhd->prot;

	int ret = 0;

	DHD_TRACE(("%s: Enter\n", __FUNCTION__));

	/* Respond "bcmerror" and "bcmerrorstr" with local cache */
	if (cmd == WLC_GET_VAR && buf)
	{
		if (!strcmp((char *)buf, "bcmerrorstr"))
		{
			strncpy((char *)buf, bcmerrorstr(dhd->dongle_error), BCME_STRLEN);
			goto done;
		}
		else if (!strcmp((char *)buf, "bcmerror"))
		{
			*(int *)buf = dhd->dongle_error;
			goto done;
		}
	}

	/* Fill up msgbuf for ioctl req */
	if (len < MAX_INLINE_IOCTL_LEN) {
		/* Inline ioct resuest */
		ret = dhd_fillup_ioct_reqst(dhd, (uint16)len, cmd, buf, ifidx);
	} else {
		/* Non inline ioct resuest */
		ret = dhd_fillup_ioct_reqst_ptrbased(dhd, (uint16)len, cmd, buf, ifidx);
	}

	DHD_INFO(("ACTION %d ifdix %d cmd %d len %d \n",
		action, ifidx, cmd, len));

	/* wait for interrupt and get first fragment */
	ret = dhdmsgbuf_cmplt(dhd, prot->reqid, len, buf, prot->retbuf);

done:
	return ret;
}
static int
dhdmsgbuf_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len, void* buf, void* retbuf)
{
	dhd_prot_t *prot = dhd->prot;
	ioct_resp_hdr_t  ioct_resp;
	uint8* data;
	int retlen;
	int msgbuf_len = 0;

	DHD_TRACE(("%s: Enter\n", __FUNCTION__));

	retlen = dhd_bus_rxctl(dhd->bus, (uchar*)&ioct_resp, msgbuf_len);

	if (retlen <= 0)
		return -1;

	/* get ret buf */
	if (buf != NULL) {
		if (retlen <= 4) {
			bcopy((void*)&ioct_resp.inline_data, buf, retlen);
			DHD_INFO(("%s: data is %d, ret_len is %d\n",
				__FUNCTION__, ioct_resp.inline_data, retlen));
		}
		else {
			data = (uint8*)retbuf;
			bcopy((void*)&data[prot->rx_dataoffset], buf, retlen);
		}
	}
	return ioct_resp.status;
}
static int
dhd_msgbuf_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
{
	dhd_prot_t *prot = dhd->prot;

	int ret = 0;

	DHD_TRACE(("%s: Enter \n", __FUNCTION__));
	DHD_TRACE(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len));

	if (dhd->busstate == DHD_BUS_DOWN) {
		DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__));
		return -EIO;
	}

	/* don't talk to the dongle if fw is about to be reloaded */
	if (dhd->hang_was_sent) {
		DHD_ERROR(("%s: HANG was sent up earlier. Not talking to the chip\n",
			__FUNCTION__));
		return -EIO;
	}

	/* Fill up msgbuf for ioctl req */
	if (len < MAX_INLINE_IOCTL_LEN) {
		/* Inline ioct resuest */
		ret = dhd_fillup_ioct_reqst(dhd, (uint16)len, cmd, buf, ifidx);
	} else {
		/* Non inline ioct resuest */
		ret = dhd_fillup_ioct_reqst_ptrbased(dhd, (uint16)len, cmd, buf, ifidx);
	}

	DHD_INFO(("ACTIOn %d ifdix %d cmd %d len %d \n",
		action, ifidx, cmd, len));

	ret = dhdmsgbuf_cmplt(dhd, prot->reqid, len, buf, prot->retbuf);

	return ret;
}
/* Handles a protocol control response asynchronously */
int dhd_prot_ctl_complete(dhd_pub_t *dhd)
{
	return 0;
}

/* Check for and handle local prot-specific iovar commands */
int dhd_prot_iovar_op(dhd_pub_t *dhd, const char *name,
                             void *params, int plen, void *arg, int len, bool set)
{
	return BCME_UNSUPPORTED;
}

/* Add prot dump output to a buffer */
void dhd_prot_dump(dhd_pub_t *dhd, struct bcmstrbuf *strbuf)
{

}

/* Update local copy of dongle statistics */
void dhd_prot_dstats(dhd_pub_t *dhd)
{
		return;
}

int dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf,
	uint reorder_info_len, void **pkt, uint32 *free_buf_count)
{
	return 0;
}
/* post a dummy message to interrupt dongle */
/* used to process cons commands */
int
dhd_post_dummy_msg(dhd_pub_t *dhd)
{
	unsigned long flags;
	hostevent_hdr_t *hevent = NULL;
	uint16 msglen = sizeof(hostevent_hdr_t);

	dhd_prot_t *prot = dhd->prot;
	circularbuf_t *htod_msgbuf;

	/* locks required to protect circular buffer accesses */
	flags = dhd_os_spin_lock(dhd);
	if (dhd->prot->htodsplit) {
		htod_msgbuf = (circularbuf_t *)prot->htod_ctrlbuf;
		hevent = (hostevent_hdr_t *)dhd_alloc_circularbuf_space(dhd,
			htod_msgbuf, msglen, HOST_TO_DNGL_CTRL);
	}
	else {
		htod_msgbuf = (circularbuf_t *)prot->htodbuf;
		hevent = (hostevent_hdr_t *)dhd_alloc_circularbuf_space(dhd,
			htod_msgbuf, msglen, HOST_TO_DNGL_DATA);
	}

	if (hevent == NULL) {
		dhd_os_spin_unlock(dhd, flags);
		return -1;
	}

	/* CMN msg header */
	hevent->msg.msglen = htol16(msglen);
	hevent->msg.msgtype = MSG_TYPE_HOST_EVNT;
	hevent->msg.ifidx = 0;
	hevent->msg.u.seq.seq_no = htol16(++prot->data_seq_no);

	/* Event payload */
	hevent->evnt_pyld = htol32(HOST_EVENT_CONS_CMD);

	/* Since, we are filling the data directly into the bufptr obtained
	 * from the msgbuf, we can directly call the write_complete
	 */
	circularbuf_write_complete(htod_msgbuf, msglen);
	dhd_os_spin_unlock(dhd, flags);

	return 0;
}
void * BCMFASTPATH
dhd_alloc_circularbuf_space(dhd_pub_t *dhd, circularbuf_t *handle, uint16 msglen, uint path)
{
	void * ret_buf;

	ret_buf = circularbuf_reserve_for_write(handle, msglen);
	if (ret_buf == NULL) {
		/* Try again after updating the read ptr from dongle */
		if (path == HOST_TO_DNGL_DATA)
			dhd_bus_cmn_readshared(dhd->bus, &(CIRCULARBUF_READ_PTR(handle)),
			HOST_TO_DNGL_RPTR);
		else if (path == HOST_TO_DNGL_CTRL)
			dhd_bus_cmn_readshared(dhd->bus, &(CIRCULARBUF_READ_PTR(handle)),
			HTOD_CTRL_RPTR);
		else
			DHD_ERROR(("%s:%d: Unknown path value \n", __FUNCTION__, __LINE__));
		ret_buf = circularbuf_reserve_for_write(handle, msglen);
		if (ret_buf == NULL) {
			DHD_INFO(("%s:%d: HTOD Msgbuf Not available \n", __FUNCTION__, __LINE__));
			return NULL;
		}
	}

	return ret_buf;
}
INLINE bool
dhd_prot_dtohsplit(dhd_pub_t* dhd)
{
	return dhd->prot->dtohsplit;
}
static int
dhd_fillup_ioct_reqst(dhd_pub_t *dhd, uint16 len, uint cmd, void* buf, int ifidx)
{
	dhd_prot_t *prot = dhd->prot;
	ioct_reqst_hdr_t *ioct_rqst;
	uint16 hdrlen = sizeof(ioct_reqst_hdr_t);
	uint16 msglen = len + hdrlen;
	circularbuf_t *htod_msgbuf;
	unsigned long flags;
	uint16 rqstlen = len;

	/* Limit ioct request to MSGBUF_MAX_MSG_SIZE bytes including hdrs */
	if (rqstlen + hdrlen > MSGBUF_MAX_MSG_SIZE)
		rqstlen = MSGBUF_MAX_MSG_SIZE - hdrlen;

	/* Messge = hdr + rqstbuf */
	msglen = rqstlen + hdrlen;

	/* align it to 4 bytes, so that all start addr form cbuf is 4 byte aligned */
	msglen = align(msglen, 4);

	/* locks required to protect circular buffer accesses */
	flags = dhd_os_spin_lock(dhd);

	/* Request for cbuf space */
	if (dhd->prot->htodsplit) {
		htod_msgbuf = (circularbuf_t *)prot->htod_ctrlbuf;
		ioct_rqst = (ioct_reqst_hdr_t *)dhd_alloc_circularbuf_space(dhd,
			htod_msgbuf, msglen, HOST_TO_DNGL_CTRL);
	}
	else {
		htod_msgbuf = (circularbuf_t *)prot->htodbuf;
		ioct_rqst = (ioct_reqst_hdr_t *)dhd_alloc_circularbuf_space(dhd,
			htod_msgbuf, msglen, HOST_TO_DNGL_DATA);
	}

	if (ioct_rqst == NULL) {
		dhd_os_spin_unlock(dhd, flags);
		return -1;
	}

	/* Common msg buf hdr */
	ioct_rqst->msg.msglen = htol16(msglen);
	ioct_rqst->msg.msgtype = MSG_TYPE_IOCTL_REQ;
	ioct_rqst->msg.ifidx = (uint8)ifidx;
	ioct_rqst->msg.u.seq.seq_no = htol16(++prot->ioctl_seq_no);

	/* Ioctl specific Message buf header */
	ioct_rqst->ioct_hdr.cmd = htol32(cmd);
	ioct_rqst->ioct_hdr.pkt_id = htol32(++prot->reqid);
	ioct_rqst->ioct_hdr.retbuf_len = htol16(len);
	ioct_rqst->ioct_hdr.xt_id = (uint16)ioct_rqst->ioct_hdr.pkt_id;
	DHD_CTL(("sending IOCTL_REQ cmd %d, pkt_id %d  xt_id %d\n",
		ioct_rqst->ioct_hdr.cmd, ioct_rqst->ioct_hdr.pkt_id, ioct_rqst->ioct_hdr.xt_id));

	/* Ret buf ptr */
	ioct_rqst->ret_buf.high_addr = htol32(PHYSADDRHI(prot->retbuf_phys));
	ioct_rqst->ret_buf.low_addr  = htol32(PHYSADDRLO(prot->retbuf_phys));

	/* copy ioct payload */
	if (buf)
		memcpy(&ioct_rqst[1], buf, rqstlen);

	/* upd wrt ptr and raise interrupt */
	circularbuf_write_complete(htod_msgbuf, msglen);
	dhd_os_spin_unlock(dhd, flags);

	return 0;
}
/* Non inline ioct request */
/* Form a ioctl request first as per ioctptr_reqst_hdr_t header in the circular buffer */
/* Form a separate request buffer where a 4 byte cmn header is added in the front */
/* buf contents from parent function is copied to remaining section of this buffer */
static int
dhd_fillup_ioct_reqst_ptrbased(dhd_pub_t *dhd, uint16 len, uint cmd, void* buf, int ifidx)
{
	dhd_prot_t *prot = dhd->prot;
	ioctptr_reqst_hdr_t *ioct_rqst;
	uint16 msglen = sizeof(ioctptr_reqst_hdr_t);
	circularbuf_t * htod_msgbuf;
	cmn_msg_hdr_t * ioct_buf;	/* For ioctl payload */
	uint16 alignlen, rqstlen = len;
	unsigned long flags;

	/* Limit ioct request to MSGBUF_MAX_MSG_SIZE bytes including hdrs */
	if ((rqstlen  + sizeof(cmn_msg_hdr_t)) > MSGBUF_MAX_MSG_SIZE)
		rqstlen = MSGBUF_MAX_MSG_SIZE - sizeof(cmn_msg_hdr_t);

	/* align it to 4 bytes, so that all start addr form cbuf is 4 byte aligned */
	alignlen = align(rqstlen, 4);

	/* locks required to protect circular buffer accesses */
	flags = dhd_os_spin_lock(dhd);
	/* Request for cbuf space */
	if (dhd->prot->htodsplit) {
		htod_msgbuf = (circularbuf_t *)prot->htod_ctrlbuf;
		ioct_rqst = (ioctptr_reqst_hdr_t*)dhd_alloc_circularbuf_space(dhd,
			htod_msgbuf, msglen, HOST_TO_DNGL_CTRL);
	}
	else {
		htod_msgbuf = (circularbuf_t *)prot->htodbuf;
		ioct_rqst = (ioctptr_reqst_hdr_t*)dhd_alloc_circularbuf_space(dhd,
			htod_msgbuf, msglen, HOST_TO_DNGL_DATA);
	}
	if (ioct_rqst == NULL) {
		dhd_os_spin_unlock(dhd, flags);
		return -1;
	}

	/* Common msg buf hdr */
	ioct_rqst->msg.msglen = htol16(msglen);
	ioct_rqst->msg.msgtype = MSG_TYPE_IOCTLPTR_REQ;
	ioct_rqst->msg.ifidx = (uint8)ifidx;
	ioct_rqst->msg.u.seq.seq_no = htol16(++prot->ioctl_seq_no);

	/* Ioctl specific Message buf header */
	ioct_rqst->ioct_hdr.cmd = htol32(cmd);
	ioct_rqst->ioct_hdr.pkt_id = htol32(++prot->reqid);
	ioct_rqst->ioct_hdr.retbuf_len = htol16(len);
	ioct_rqst->ioct_hdr.xt_id = (uint16)ioct_rqst->ioct_hdr.pkt_id;

	DHD_CTL(("sending IOCTL_PTRREQ cmd %d, pkt_id %d  xt_id %d\n",
		ioct_rqst->ioct_hdr.cmd, ioct_rqst->ioct_hdr.pkt_id, ioct_rqst->ioct_hdr.xt_id));

	/* Ret buf ptr */
	ioct_rqst->ret_buf.high_addr = htol32(PHYSADDRHI(prot->retbuf_phys));
	ioct_rqst->ret_buf.low_addr  = htol32(PHYSADDRLO(prot->retbuf_phys));

	/* copy ioct payload */
	ioct_buf = (cmn_msg_hdr_t *) prot->ioctbuf;
	ioct_buf->msglen = htol16(alignlen + sizeof(cmn_msg_hdr_t));
	ioct_buf->msgtype = MSG_TYPE_IOCT_PYLD;

	if (buf) {
		memcpy(&ioct_buf[1], buf, rqstlen);
		OSL_CACHE_FLUSH((void *) prot->ioctbuf, rqstlen+sizeof(cmn_msg_hdr_t));
	}

	if ((ulong)ioct_buf % 4)
		printf("host ioct address unaligned !!!!! \n");

	/* populate ioctl buffer info */
	ioct_rqst->ioct_hdr.buflen = htol16(alignlen + sizeof(cmn_msg_hdr_t));
	ioct_rqst->ioct_buf.high_addr = htol32(PHYSADDRHI(prot->ioctbuf_phys));
	ioct_rqst->ioct_buf.low_addr  = htol32(PHYSADDRLO(prot->ioctbuf_phys));

	/* upd wrt ptr and raise interrupt */
	circularbuf_write_complete(htod_msgbuf, msglen);

	dhd_os_spin_unlock(dhd, flags);

	return 0;
}

/* Packet to PacketID mapper */
typedef struct {
	ulong native;
	dmaaddr_t pa;
	uint32 pa_len;
	uchar dma;
} pktid_t;

typedef struct {
	void	*osh;
	void	*mwbmap_hdl;
	pktid_t *pktid_list;
	uint32	count;
} pktid_map_t;


void *pktid_map_init(void *osh, uint32 count)
{
	pktid_map_t *handle;

	handle = (pktid_map_t *) MALLOC(osh, sizeof(pktid_map_t));
	if (handle == NULL) {
		printf("%s:%d: MALLOC failed for size %d\n",
			__FUNCTION__, __LINE__, (uint32) sizeof(pktid_map_t));
		return NULL;
	}
	handle->osh = osh;
	handle->count = count;
	handle->mwbmap_hdl = bcm_mwbmap_init(osh, count);
	if (handle->mwbmap_hdl == NULL) {
		printf("%s:%d: bcm_mwbmap_init failed for count %d\n",
			__FUNCTION__, __LINE__, count);
		MFREE(osh, handle, sizeof(pktid_map_t));
		return NULL;
	}

	handle->pktid_list = (pktid_t *) MALLOC(osh, sizeof(pktid_t) * (count+1));
	if (handle->pktid_list == NULL) {
		printf("%s:%d: MALLOC failed for count %d / total = %d\n",
			__FUNCTION__, __LINE__, count, (uint32) sizeof(pktid_t) * count);
		bcm_mwbmap_fini(osh, handle->mwbmap_hdl);
		MFREE(osh, handle, sizeof(pktid_map_t));
		return NULL;
	}

	return handle;
}

void
pktid_map_uninit(void *pktid_map_handle)
{
	pktid_map_t *handle = (pktid_map_t *) pktid_map_handle;
	uint32 ix;

	if (handle != NULL) {
		void *osh = handle->osh;
		for (ix = 0; ix < MAX_PKTID_ITEMS; ix++)
		{
			if (!bcm_mwbmap_isfree(handle->mwbmap_hdl, ix)) {
				/* Mark the slot as free */
				bcm_mwbmap_free(handle->mwbmap_hdl, ix);
				/*
				Here we can do dma unmapping for 32 bit also.
				Since this in removal path, it will not affect performance
				*/
				DMA_UNMAP(osh, (uint) handle->pktid_list[ix+1].pa,
					(uint) handle->pktid_list[ix+1].pa_len,
					handle->pktid_list[ix+1].dma, 0, 0);
				PKTFREE(osh,
					(unsigned long*)handle->pktid_list[ix+1].native, TRUE);
			}
		}
		bcm_mwbmap_fini(osh, handle->mwbmap_hdl);
		MFREE(osh, handle->pktid_list, sizeof(pktid_t) * (handle->count+1));
		MFREE(osh, handle, sizeof(pktid_map_t));
	}
	return;
}

uint32 BCMFASTPATH
pktid_map_unique(void *pktid_map_handle, void *pkt, dmaaddr_t physaddr, uint32 physlen, uint32 dma)
{
	uint32 id;
	pktid_map_t *handle = (pktid_map_t *) pktid_map_handle;

	if (handle == NULL) {
		printf("%s:%d: Error !!! pktid_map_unique called without initing pktid_map\n",
			__FUNCTION__, __LINE__);
		return 0;
	}
	id = bcm_mwbmap_alloc(handle->mwbmap_hdl);
	if (id == BCM_MWBMAP_INVALID_IDX) {
		printf("%s:%d: bcm_mwbmap_alloc failed. Free Count = %d\n",
			__FUNCTION__, __LINE__, bcm_mwbmap_free_cnt(handle->mwbmap_hdl));
		return 0;
	}

	/* id=0 is invalid as we use this for error checking in the dongle */
	id += 1;
	handle->pktid_list[id].native = (ulong) pkt;
	handle->pktid_list[id].pa     = physaddr;
	handle->pktid_list[id].pa_len = (uint32) physlen;
	handle->pktid_list[id].dma = dma;

	return id;
}

void * BCMFASTPATH
pktid_get_packet(void *pktid_map_handle, uint32 id, dmaaddr_t *physaddr, uint32 *physlen)
{
	void *native = NULL;
	pktid_map_t *handle = (pktid_map_t *) pktid_map_handle;
	if (handle == NULL) {
		printf("%s:%d: Error !!! pktid_get_packet called without initing pktid_map\n",
			__FUNCTION__, __LINE__);
		return NULL;
	}

	/* Debug check */
	if (bcm_mwbmap_isfree(handle->mwbmap_hdl, (id-1))) {
		printf("%s:%d: Error !!!. How can the slot (%d) be free if the app is using it.\n",
			__FUNCTION__, __LINE__, (id-1));
		return NULL;
	}

	native = (void *) handle->pktid_list[id].native;
	*physaddr = handle->pktid_list[id].pa;
	*physlen  = (uint32) handle->pktid_list[id].pa_len;

	/* Mark the slot as free */
	bcm_mwbmap_free(handle->mwbmap_hdl, (id-1));

	return native;
}
