/*
 * DHD PROP_TXSTATUS Module.
 *
 * Copyright (C) 2020, Broadcom.
 *
 *      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.
 *
 *
 * <<Broadcom-WL-IPTag/Open:>>
 *
 * $Id$
 *
 */

/** XXX Twiki [PropTxStatus] */

#include <typedefs.h>
#include <osl.h>

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

#include <dngl_stats.h>
#include <dhd.h>

#include <dhd_bus.h>

#include <dhd_dbg.h>
#include <dhd_config.h>
#include <wl_android.h>

#ifdef PROP_TXSTATUS /* a form of flow control between host and dongle */
#include <wlfc_proto.h>
#include <dhd_wlfc.h>
#endif

#ifdef DHDTCPACK_SUPPRESS
#include <dhd_ip.h>
#endif /* DHDTCPACK_SUPPRESS */

/*
 * wlfc naming and lock rules:
 *
 * 1. Private functions name like _dhd_wlfc_XXX, declared as static and avoid wlfc lock operation.
 * 2. Public functions name like dhd_wlfc_XXX, use wlfc lock if needed.
 * 3. Non-Proptxstatus module call public functions only and avoid wlfc lock operation.
 *
 */

#if defined (DHD_WLFC_THREAD)
#define WLFC_THREAD_QUICK_RETRY_WAIT_MS    10      /* 10 msec */
#define WLFC_THREAD_RETRY_WAIT_MS          10000   /* 10 sec */
#endif /* defined (DHD_WLFC_THREAD) */

#ifdef PROP_TXSTATUS

#ifdef QMONITOR
#define DHD_WLFC_QMON_COMPLETE(entry) dhd_qmon_txcomplete(&entry->qmon)
#else
#define DHD_WLFC_QMON_COMPLETE(entry)
#endif /* QMONITOR */

#if defined(BCMINTERNAL) && defined(OOO_DEBUG)

/** for 'out of order' debug */
static void
_dhd_wlfc_bprint(athost_wl_status_info_t* wlfc, const char *fmt, ...)
{
	va_list ap;
	int r, size;
	uint8 *buf;
	bool bRetry = FALSE;

	if (!wlfc || !wlfc->log_buf) {
		return;
	}

	va_start(ap, fmt);

retry:
	buf = wlfc->log_buf + wlfc->log_buf_offset;
	size = WLFC_LOG_BUF_SIZE -1 - wlfc->log_buf_offset;

	r = vsnprintf(buf, size, fmt, ap);
	/* Non Ansi C99 compliant returns -1,
	 * Ansi compliant return r >= b->size,
	 * bcmstdlib returns 0, handle all
	 */
	/* r == 0 is also the case when strlen(fmt) is zero.
	 * typically the case when "" is passed as argument.
	 */
	if ((r == -1) || (r >= size)) {
		bRetry = TRUE;
	} else {
		wlfc->log_buf_offset += r;
	}

	if ((wlfc->log_buf_offset >= (WLFC_LOG_BUF_SIZE -1)) || bRetry) {
		wlfc->log_buf[wlfc->log_buf_offset] = 0;
		wlfc->log_buf_offset = 0;
		if (!wlfc->log_buf_full) {
			wlfc->log_buf_full = TRUE;
		}

		if (bRetry) {
			bRetry = FALSE;
			goto retry;
		}
	}

	va_end(ap);

	return;
} /* _dhd_wlfc_bprint */

/** for 'out of order' debug */
static void _dhd_wlfc_print_1k_buf(uint8* buf, int size)
{
	/* print last 1024 bytes */
	if (size > 1024) {
		buf += (size - 1024);
	}
	printf("%s", buf);
}

/** for 'out of order' debug */
static void
_dhd_wlfc_print_log(athost_wl_status_info_t* wlfc)
{
	if (!wlfc || !wlfc->log_buf) {
		return;
	}

	printf("%s: log_buf_full(%d), log_buf_offset(%d)\n",
		__FUNCTION__, wlfc->log_buf_full, wlfc->log_buf_offset);
	if (wlfc->log_buf_full) {
		_dhd_wlfc_print_1k_buf(wlfc->log_buf + wlfc->log_buf_offset,
			WLFC_LOG_BUF_SIZE - wlfc->log_buf_offset);
	}
	wlfc->log_buf[wlfc->log_buf_offset] = 0;
	_dhd_wlfc_print_1k_buf(wlfc->log_buf, wlfc->log_buf_offset);
	printf("\n%s: done\n", __FUNCTION__);

	wlfc->log_buf_offset = 0;
	wlfc->log_buf_full = FALSE;
}

/** for 'out of order' debug */
static void
_dhd_wlfc_check_send_order(athost_wl_status_info_t* wlfc, wlfc_mac_descriptor_t* entry, void* p)
{
	uint8 seq = WL_TXSTATUS_GET_FREERUNCTR(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
	uint8 gen = WL_TXSTATUS_GET_GENERATION(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
	uint8 prec = DHD_PKTTAG_FIFO(PKTTAG(p));

	if ((entry->last_send_gen[prec] == gen) &&
		((uint8)(entry->last_send_seq[prec] + 1) > seq)) {
		printf("%s: prec(%d), last(%u), p(%u)\n",
			__FUNCTION__, prec, entry->last_send_seq[prec], seq);
		_dhd_wlfc_print_log(wlfc);
	}

	entry->last_send_seq[prec] = seq;
	entry->last_send_gen[prec] = gen;
}

/** for 'out of order' debug */
static void
_dhd_wlfc_check_complete_order(athost_wl_status_info_t* wlfc, wlfc_mac_descriptor_t* entry, void* p)
{
	uint8 seq = WL_TXSTATUS_GET_FREERUNCTR(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
	uint8 prec = DHD_PKTTAG_FIFO(PKTTAG(p));

	entry->last_complete_seq[prec] = seq;
}

#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */

/** reordering related */

#if defined(DHD_WLFC_THREAD)
static void
_dhd_wlfc_thread_wakeup(dhd_pub_t *dhdp)
{
#if defined(LINUX)
	dhdp->wlfc_thread_go = TRUE;
	wake_up_interruptible(&dhdp->wlfc_wqhead);
#endif /* LINUX */
}
#endif /* DHD_WLFC_THREAD */

static uint16
_dhd_wlfc_adjusted_seq(void* p, uint8 current_seq)
{
	uint16 seq;

	if (!p) {
		return 0xffff;
	}

	seq = WL_TXSTATUS_GET_FREERUNCTR(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
	if (seq < current_seq) {
		/* wrap around */
		seq += 256;
	}

	return seq;
}

/**
 * Enqueue a caller supplied packet on a caller supplied precedence queue, optionally reorder
 * suppressed packets.
 *    @param[in] pq       caller supplied packet queue to enqueue the packet on
 *    @param[in] prec     precedence of the to-be-queued packet
 *    @param[in] p        transmit packet to enqueue
 *    @param[in] qHead    if TRUE, enqueue to head instead of tail. Used to maintain d11 seq order.
 *    @param[in] current_seq
 *    @param[in] reOrder  reOrder on odd precedence (=suppress queue)
 */
static void
_dhd_wlfc_prec_enque(struct pktq *pq, int prec, void* p, bool qHead,
	uint8 current_seq, bool reOrder)
{
	struct pktq_prec *q;
	uint16 seq, seq2;
	void *p2, *p2_prev;

	if (!p)
		return;

	ASSERT(prec >= 0 && prec < pq->num_prec);
	ASSERT(PKTLINK(p) == NULL);		/* queueing chains not allowed */

	ASSERT(!pktq_full(pq));
	ASSERT(!pktqprec_full(pq, prec));

	q = &pq->q[prec];

	if (q->head == NULL) {
		/* empty queue */
		q->head = p;
		q->tail = p;
	} else {
		if (reOrder && (prec & 1)) {
			seq = _dhd_wlfc_adjusted_seq(p, current_seq);
			p2 = qHead ? q->head : q->tail;
			seq2 = _dhd_wlfc_adjusted_seq(p2, current_seq);

			if ((qHead &&((seq+1) > seq2)) || (!qHead && ((seq2+1) > seq))) {
				/* need reorder */
				p2 = q->head;
				p2_prev = NULL;
				seq2 = _dhd_wlfc_adjusted_seq(p2, current_seq);

				while (seq > seq2) {
					p2_prev = p2;
					p2 = PKTLINK(p2);
					if (!p2) {
						break;
					}
					seq2 = _dhd_wlfc_adjusted_seq(p2, current_seq);
				}

				if (p2_prev == NULL) {
					/* insert head */
					PKTSETLINK(p, q->head);
					q->head = p;
				} else if (p2 == NULL) {
					/* insert tail */
					PKTSETLINK(p2_prev, p);
					q->tail = p;
				} else {
					/* insert after p2_prev */
					PKTSETLINK(p, PKTLINK(p2_prev));
					PKTSETLINK(p2_prev, p);
				}
				goto exit;
			}
		}

		if (qHead) {
			PKTSETLINK(p, q->head);
			q->head = p;
		} else {
			PKTSETLINK(q->tail, p);
			q->tail = p;
		}
	}

exit:

	q->n_pkts++;
	pq->n_pkts_tot++;

	if (pq->hi_prec < prec)
		pq->hi_prec = (uint8)prec;
} /* _dhd_wlfc_prec_enque */

/**
 * Create a place to store all packet pointers submitted to the firmware until a status comes back,
 * suppress or otherwise.
 *
 * hang-er: noun, a contrivance on which things are hung, as a hook.
 */
/** @deprecated soon */
static void*
_dhd_wlfc_hanger_create(dhd_pub_t *dhd, int max_items)
{
	int i;
	wlfc_hanger_t* hanger;

	/* allow only up to a specific size for now */
	ASSERT(max_items == WLFC_HANGER_MAXITEMS);

	if ((hanger = (wlfc_hanger_t*)DHD_OS_PREALLOC(dhd, DHD_PREALLOC_DHD_WLFC_HANGER,
		WLFC_HANGER_SIZE(max_items))) == NULL) {
		return NULL;
	}
	memset(hanger, 0, WLFC_HANGER_SIZE(max_items));
	hanger->max_items = max_items;

	for (i = 0; i < hanger->max_items; i++) {
		hanger->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
	}
	return hanger;
}

/** @deprecated soon */
static int
_dhd_wlfc_hanger_delete(dhd_pub_t *dhd, void* hanger)
{
	wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;

	if (h) {
		DHD_OS_PREFREE(dhd, h, WLFC_HANGER_SIZE(h->max_items));
		return BCME_OK;
	}
	return BCME_BADARG;
}

/** @deprecated soon */
static uint16
_dhd_wlfc_hanger_get_free_slot(void* hanger)
{
	uint32 i;
	wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;

	if (h) {
		i = h->slot_pos + 1;
		if (i == h->max_items) {
			i = 0;
		}
		while (i != h->slot_pos) {
			if (h->items[i].state == WLFC_HANGER_ITEM_STATE_FREE) {
				h->slot_pos = i;
				return (uint16)i;
			}
			i++;
			if (i == h->max_items)
				i = 0;
		}
		h->failed_slotfind++;
	}
	return WLFC_HANGER_MAXITEMS;
}

/** @deprecated soon */
static int
_dhd_wlfc_hanger_get_genbit(void* hanger, void* pkt, uint32 slot_id, int* gen)
{
	int rc = BCME_OK;
	wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;

	*gen = 0xff;

	/* this packet was not pushed at the time it went to the firmware */
	if (slot_id == WLFC_HANGER_MAXITEMS)
		return BCME_NOTFOUND;

	if (h) {
		if (h->items[slot_id].state != WLFC_HANGER_ITEM_STATE_FREE) {
			*gen = h->items[slot_id].gen;
		}
		else {
			DHD_ERROR(("Error: %s():%d item not used\n",
				__FUNCTION__, __LINE__));
			rc = BCME_NOTFOUND;
		}

	} else {
		rc = BCME_BADARG;
	}

	return rc;
}

/** @deprecated soon */
static int
_dhd_wlfc_hanger_pushpkt(void* hanger, void* pkt, uint32 slot_id)
{
	int rc = BCME_OK;
	wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;

	if (h && (slot_id < WLFC_HANGER_MAXITEMS)) {
		if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_FREE) {
			h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE;
			h->items[slot_id].pkt = pkt;
			h->items[slot_id].pkt_state = 0;
			h->items[slot_id].pkt_txstatus = 0;
			h->pushed++;
		} else {
			h->failed_to_push++;
			rc = BCME_NOTFOUND;
		}
	} else {
		rc = BCME_BADARG;
	}

	return rc;
}

/** @deprecated soon */
static int
_dhd_wlfc_hanger_poppkt(void* hanger, uint32 slot_id, void** pktout, bool remove_from_hanger)
{
	int rc = BCME_OK;
	wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;

	*pktout = NULL;

	/* this packet was not pushed at the time it went to the firmware */
	if (slot_id == WLFC_HANGER_MAXITEMS)
		return BCME_NOTFOUND;

	if (h) {
		if (h->items[slot_id].state != WLFC_HANGER_ITEM_STATE_FREE) {
			*pktout = h->items[slot_id].pkt;
			if (remove_from_hanger) {
				h->items[slot_id].state =
					WLFC_HANGER_ITEM_STATE_FREE;
				h->items[slot_id].pkt = NULL;
				h->items[slot_id].gen = 0xff;
				h->items[slot_id].identifier = 0;
				h->popped++;
			}
		} else {
			h->failed_to_pop++;
			rc = BCME_NOTFOUND;
		}
	} else {
		rc = BCME_BADARG;
	}

	return rc;
}

/** @deprecated soon */
static int
_dhd_wlfc_hanger_mark_suppressed(void* hanger, uint32 slot_id, uint8 gen)
{
	int rc = BCME_OK;
	wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;

	/* this packet was not pushed at the time it went to the firmware */
	if (slot_id == WLFC_HANGER_MAXITEMS)
		return BCME_NOTFOUND;
	if (h) {
		h->items[slot_id].gen = gen;
		if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) {
			h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED;
		} else {
			rc = BCME_BADARG;
		}
	} else {
		rc = BCME_BADARG;
	}

	return rc;
}

/** remove reference of specific packet in hanger */
/** @deprecated soon */
static bool
_dhd_wlfc_hanger_remove_reference(wlfc_hanger_t* h, void* pkt)
{
	int i;

	if (!h || !pkt) {
		return FALSE;
	}

	i = WL_TXSTATUS_GET_HSLOT(DHD_PKTTAG_H2DTAG(PKTTAG(pkt)));

	if ((i < h->max_items) && (pkt == h->items[i].pkt)) {
		if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) {
			h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
			h->items[i].pkt = NULL;
			h->items[i].gen = 0xff;
			h->items[i].identifier = 0;
			return TRUE;
		} else {
			DHD_ERROR(("Error: %s():%d item not suppressed\n",
				__FUNCTION__, __LINE__));
		}
	}

	return FALSE;
}

/** afq = At Firmware Queue, queue containing packets pending in the dongle */
static int
_dhd_wlfc_enque_afq(athost_wl_status_info_t* ctx, void *p)
{
	wlfc_mac_descriptor_t* entry;
	uint16 entry_idx = WL_TXSTATUS_GET_HSLOT(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
	uint8 prec = DHD_PKTTAG_FIFO(PKTTAG(p));

	if (entry_idx < WLFC_MAC_DESC_TABLE_SIZE)
		entry  = &ctx->destination_entries.nodes[entry_idx];
	else if (entry_idx < (WLFC_MAC_DESC_TABLE_SIZE + WLFC_MAX_IFNUM))
		entry = &ctx->destination_entries.interfaces[entry_idx - WLFC_MAC_DESC_TABLE_SIZE];
	else
		entry = &ctx->destination_entries.other;

	pktq_penq(&entry->afq, prec, p);

	return BCME_OK;
}

/** afq = At Firmware Queue, queue containing packets pending in the dongle */
static int
_dhd_wlfc_deque_afq(athost_wl_status_info_t* ctx, uint16 hslot, uint8 hcnt, uint8 prec,
	void **pktout)
{
	wlfc_mac_descriptor_t *entry;
	struct pktq *pq;
	struct pktq_prec *q;
	void *p, *b;

	if (!ctx) {
		DHD_ERROR(("%s: ctx(%p), pktout(%p)\n", __FUNCTION__, ctx, pktout));
		return BCME_BADARG;
	}

	if (pktout) {
		*pktout = NULL;
	}

	ASSERT(hslot < (WLFC_MAC_DESC_TABLE_SIZE + WLFC_MAX_IFNUM + 1));

	if (hslot < WLFC_MAC_DESC_TABLE_SIZE)
		entry  = &ctx->destination_entries.nodes[hslot];
	else if (hslot < (WLFC_MAC_DESC_TABLE_SIZE + WLFC_MAX_IFNUM))
		entry = &ctx->destination_entries.interfaces[hslot - WLFC_MAC_DESC_TABLE_SIZE];
	else
		entry = &ctx->destination_entries.other;

	pq = &entry->afq;

	ASSERT(prec < pq->num_prec);

	q = &pq->q[prec];

	b = NULL;
	p = q->head;

	while (p && (hcnt != WL_TXSTATUS_GET_FREERUNCTR(DHD_PKTTAG_H2DTAG(PKTTAG(p)))))
	{
		b = p;
		p = PKTLINK(p);
	}

	if (p == NULL) {
		/* none is matched */
		if (b) {
			DHD_ERROR(("%s: can't find matching seq(%d)\n", __FUNCTION__, hcnt));
		} else {
			DHD_ERROR(("%s: queue is empty\n", __FUNCTION__));
		}

		return BCME_ERROR;
	}

	bcm_pkt_validate_chk(p, "_dhd_wlfc_deque_afq");

	if (!b) {
		/* head packet is matched */
		if ((q->head = PKTLINK(p)) == NULL) {
			q->tail = NULL;
		}
	} else {
		/* middle packet is matched */
		DHD_INFO(("%s: out of order, seq(%d), head_seq(%d)\n", __FUNCTION__, hcnt,
			WL_TXSTATUS_GET_FREERUNCTR(DHD_PKTTAG_H2DTAG(PKTTAG(q->head)))));
		ctx->stats.ooo_pkts[prec]++;
		PKTSETLINK(b, PKTLINK(p));
		if (PKTLINK(p) == NULL) {
			q->tail = b;
		}
	}

	q->n_pkts--;
	pq->n_pkts_tot--;

#ifdef WL_TXQ_STALL
	q->dequeue_count++;
#endif

	PKTSETLINK(p, NULL);

	if (pktout) {
		*pktout = p;
	}

	return BCME_OK;
} /* _dhd_wlfc_deque_afq */

/**
 * Flow control information piggy backs on packets, in the form of one or more TLVs. This function
 * pushes one or more TLVs onto a packet that is going to be sent towards the dongle.
 *
 *     @param[in]     ctx
 *     @param[in/out] packet
 *     @param[in]     tim_signal TRUE if parameter 'tim_bmp' is valid
 *     @param[in]     tim_bmp
 *     @param[in]     mac_handle
 *     @param[in]     htodtag
 *     @param[in]     htodseq d11 seqno for seqno reuse, only used if 'seq reuse' was agreed upon
 *                    earlier between host and firmware.
 *     @param[in]     skip_wlfc_hdr
 */
static int
_dhd_wlfc_pushheader(athost_wl_status_info_t* ctx, void** packet, bool tim_signal,
	uint8 tim_bmp, uint8 mac_handle, uint32 htodtag, uint16 htodseq, bool skip_wlfc_hdr)
{
	uint32 wl_pktinfo = 0;
	uint8* wlh;
	uint8 dataOffset = 0;
	uint8 fillers;
	uint8 tim_signal_len = 0;
	dhd_pub_t *dhdp = (dhd_pub_t *)ctx->dhdp;

	struct bdc_header *h;
	void *p = *packet;

	if (skip_wlfc_hdr)
		goto push_bdc_hdr;

	if (tim_signal) {
		tim_signal_len = TLV_HDR_LEN + WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP;
	}

	/* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
	dataOffset = WLFC_CTL_VALUE_LEN_PKTTAG + TLV_HDR_LEN + tim_signal_len;
	if (WLFC_GET_REUSESEQ(dhdp->wlfc_mode)) {
		dataOffset += WLFC_CTL_VALUE_LEN_SEQ;
	}

	fillers = ROUNDUP(dataOffset, 4) - dataOffset;
	dataOffset += fillers;

	PKTPUSH(ctx->osh, p, dataOffset);
	wlh = (uint8*) PKTDATA(ctx->osh, p);

	wl_pktinfo = htol32(htodtag);

	wlh[TLV_TAG_OFF] = WLFC_CTL_TYPE_PKTTAG;
	wlh[TLV_LEN_OFF] = WLFC_CTL_VALUE_LEN_PKTTAG;
	memcpy(&wlh[TLV_HDR_LEN] /* dst */, &wl_pktinfo, sizeof(uint32));

	if (WLFC_GET_REUSESEQ(dhdp->wlfc_mode)) {
		uint16 wl_seqinfo = htol16(htodseq);
		wlh[TLV_LEN_OFF] += WLFC_CTL_VALUE_LEN_SEQ;
		memcpy(&wlh[TLV_HDR_LEN + WLFC_CTL_VALUE_LEN_PKTTAG], &wl_seqinfo,
			WLFC_CTL_VALUE_LEN_SEQ);
	}

	if (tim_signal_len) {
		wlh[dataOffset - fillers - tim_signal_len ] =
			WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP;
		wlh[dataOffset - fillers - tim_signal_len + 1] =
			WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP;
		wlh[dataOffset - fillers - tim_signal_len + 2] = mac_handle;
		wlh[dataOffset - fillers - tim_signal_len + 3] = tim_bmp;
	}
	if (fillers)
		memset(&wlh[dataOffset - fillers], WLFC_CTL_TYPE_FILLER, fillers);

push_bdc_hdr:
	PKTPUSH(ctx->osh, p, BDC_HEADER_LEN);
	h = (struct bdc_header *)PKTDATA(ctx->osh, p);
	h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
	if (PKTSUMNEEDED(p))
		h->flags |= BDC_FLAG_SUM_NEEDED;

#ifdef EXT_STA
	/* save pkt encryption exemption info for dongle */
	h->flags &= ~BDC_FLAG_EXEMPT;
	h->flags |= (DHD_PKTTAG_EXEMPT(PKTTAG(p)) & BDC_FLAG_EXEMPT);
#endif /* EXT_STA */

	h->priority = (PKTPRIO(p) & BDC_PRIORITY_MASK);
	h->flags2 = 0;
	h->dataOffset = dataOffset >> 2;
	BDC_SET_IF_IDX(h, DHD_PKTTAG_IF(PKTTAG(p)));
	*packet = p;
	return BCME_OK;
} /* _dhd_wlfc_pushheader */

/**
 * Removes (PULLs) flow control related headers from the caller supplied packet, is invoked eg
 * when a packet is about to be freed.
 */
static int
_dhd_wlfc_pullheader(athost_wl_status_info_t* ctx, void* pktbuf)
{
	struct bdc_header *h;

	if (PKTLEN(ctx->osh, pktbuf) < BDC_HEADER_LEN) {
		DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__,
		           PKTLEN(ctx->osh, pktbuf), BDC_HEADER_LEN));
		return BCME_ERROR;
	}
	h = (struct bdc_header *)PKTDATA(ctx->osh, pktbuf);

	/* pull BDC header */
	PKTPULL(ctx->osh, pktbuf, BDC_HEADER_LEN);

	if (PKTLEN(ctx->osh, pktbuf) < (uint)(h->dataOffset << 2)) {
		DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__,
		           PKTLEN(ctx->osh, pktbuf), (h->dataOffset << 2)));
		return BCME_ERROR;
	}

	/* pull wl-header */
	PKTPULL(ctx->osh, pktbuf, (h->dataOffset << 2));
	return BCME_OK;
}

/**
 * @param[in/out] p packet
 */
static wlfc_mac_descriptor_t*
_dhd_wlfc_find_table_entry(athost_wl_status_info_t* ctx, void* p)
{
	int i;
	wlfc_mac_descriptor_t* table = ctx->destination_entries.nodes;
	uint8 ifid = DHD_PKTTAG_IF(PKTTAG(p));
	uint8* dstn = DHD_PKTTAG_DSTN(PKTTAG(p));
	wlfc_mac_descriptor_t* entry = DHD_PKTTAG_ENTRY(PKTTAG(p));
	int iftype = ctx->destination_entries.interfaces[ifid].iftype;

	/* saved one exists, return it */
	if (entry)
		return entry;

	/* Multicast destination, STA and P2P clients get the interface entry.
	 * STA/GC gets the Mac Entry for TDLS destinations, TDLS destinations
	 * have their own entry.
	 */
	if ((iftype == WLC_E_IF_ROLE_STA || ETHER_ISMULTI(dstn) ||
		iftype == WLC_E_IF_ROLE_P2P_CLIENT) &&
		(ctx->destination_entries.interfaces[ifid].occupied)) {
			entry = &ctx->destination_entries.interfaces[ifid];
	}

	if (entry && ETHER_ISMULTI(dstn)) {
		DHD_PKTTAG_SET_ENTRY(PKTTAG(p), entry);
		return entry;
	}

	for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
		if (table[i].occupied) {
			if (table[i].interface_id == ifid) {
				if (!memcmp(table[i].ea, dstn, ETHER_ADDR_LEN)) {
					entry = &table[i];
					break;
				}
			}
		}
	}

	if (entry == NULL)
		entry = &ctx->destination_entries.other;

	DHD_PKTTAG_SET_ENTRY(PKTTAG(p), entry);

	return entry;
} /* _dhd_wlfc_find_table_entry */

/**
 * In case a packet must be dropped (because eg the queues are full), various tallies have to be
 * be updated. Called from several other functions.
 *     @param[in] dhdp pointer to public DHD structure
 *     @param[in] prec precedence of the packet
 *     @param[in] p    the packet to be dropped
 *     @param[in] bPktInQ TRUE if packet is part of a queue
 */
static int
_dhd_wlfc_prec_drop(dhd_pub_t *dhdp, int prec, void* p, bool bPktInQ)
{
	athost_wl_status_info_t* ctx;
	void *pout = NULL;

	ASSERT(dhdp && p);
	if (prec < 0 || prec >= WLFC_PSQ_PREC_COUNT) {
		ASSERT(0);
		return BCME_BADARG;
	}

	ctx = (athost_wl_status_info_t*)dhdp->wlfc_state;

	if (!WLFC_GET_AFQ(dhdp->wlfc_mode) && (prec & 1)) {
		/* suppressed queue, need pop from hanger */
		_dhd_wlfc_hanger_poppkt(ctx->hanger, WL_TXSTATUS_GET_HSLOT(DHD_PKTTAG_H2DTAG
					(PKTTAG(p))), &pout, TRUE);
		ASSERT(p == pout);
	}

	if (!(prec & 1)) {
#ifdef DHDTCPACK_SUPPRESS
		/* pkt in delayed q, so fake push BDC header for
		 * dhd_tcpack_check_xmit() and dhd_txcomplete().
		 */
		_dhd_wlfc_pushheader(ctx, &p, FALSE, 0, 0, 0, 0, TRUE);

		/* This packet is about to be freed, so remove it from tcp_ack_info_tbl
		 * This must be one of...
		 * 1. A pkt already in delayQ is evicted by another pkt with higher precedence
		 * in _dhd_wlfc_prec_enq_with_drop()
		 * 2. A pkt could not be enqueued to delayQ because it is full,
		 * in _dhd_wlfc_enque_delayq().
		 * 3. A pkt could not be enqueued to delayQ because it is full,
		 * in _dhd_wlfc_rollback_packet_toq().
		 */
		if (dhd_tcpack_check_xmit(dhdp, p) == BCME_ERROR) {
			DHD_ERROR(("%s %d: tcpack_suppress ERROR!!!"
				" Stop using it\n",
				__FUNCTION__, __LINE__));
			dhd_tcpack_suppress_set(dhdp, TCPACK_SUP_OFF);
		}
#endif /* DHDTCPACK_SUPPRESS */
	}

	if (bPktInQ) {
		ctx->pkt_cnt_in_q[DHD_PKTTAG_IF(PKTTAG(p))][prec>>1]--;
		ctx->pkt_cnt_per_ac[prec>>1]--;
		ctx->pkt_cnt_in_psq--;
	}

	ctx->pkt_cnt_in_drv[DHD_PKTTAG_IF(PKTTAG(p))][DHD_PKTTAG_FIFO(PKTTAG(p))]--;
	ctx->stats.pktout++;
	ctx->stats.drop_pkts[prec]++;

	dhd_txcomplete(dhdp, p, FALSE);
	PKTFREE(ctx->osh, p, TRUE);

	return 0;
} /* _dhd_wlfc_prec_drop */

/**
 * Called when eg the host handed a new packet over to the driver, or when the dongle reported
 * that a packet could currently not be transmitted (=suppressed). This function enqueues a transmit
 * packet in the host driver to be (re)transmitted at a later opportunity.
 *     @param[in] dhdp pointer to public DHD structure
 *     @param[in] qHead When TRUE, queue packet at head instead of tail, to preserve d11 sequence
 */
static bool
_dhd_wlfc_prec_enq_with_drop(dhd_pub_t *dhdp, struct pktq *pq, void *pkt, int prec, bool qHead,
	uint8 current_seq)
{
	void *p = NULL;
	int eprec = -1;		/* precedence to evict from */
	athost_wl_status_info_t* ctx;

	ASSERT(dhdp && pq && pkt);
	ASSERT(prec >= 0 && prec < pq->num_prec);

	ctx = (athost_wl_status_info_t*)dhdp->wlfc_state;

	/* Fast case, precedence queue is not full and we are also not
	 * exceeding total queue length
	 */
	if (!pktqprec_full(pq, prec) && !pktq_full(pq)) {
		goto exit;
	}

	/* Determine precedence from which to evict packet, if any */
	if (pktqprec_full(pq, prec)) {
		eprec = prec;
	} else if (pktq_full(pq)) {
		p = pktq_peek_tail(pq, &eprec);
		if (!p) {
			DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
			return FALSE;
		}
		if ((eprec > prec) || (eprec < 0)) {
			if (!pktqprec_empty(pq, prec)) {
				eprec = prec;
			} else {
				return FALSE;
			}
		}
	}

	/* Evict if needed */
	if (eprec >= 0) {
		/* Detect queueing to unconfigured precedence */
		ASSERT(!pktqprec_empty(pq, eprec));
		/* Evict all fragmented frames */
		dhd_prec_drop_pkts(dhdp, pq, eprec, _dhd_wlfc_prec_drop);
	}

exit:
	/* Enqueue */
	_dhd_wlfc_prec_enque(pq, prec, pkt, qHead, current_seq,
		WLFC_GET_REORDERSUPP(dhdp->wlfc_mode));
	ctx->pkt_cnt_in_q[DHD_PKTTAG_IF(PKTTAG(pkt))][prec>>1]++;
	ctx->pkt_cnt_per_ac[prec>>1]++;
	ctx->pkt_cnt_in_psq++;

	return TRUE;
} /* _dhd_wlfc_prec_enq_with_drop */

/**
 * Called during eg the 'committing' of a transmit packet from the OS layer to a lower layer, in
 * the event that this 'commit' failed.
 */
static int
_dhd_wlfc_rollback_packet_toq(athost_wl_status_info_t* ctx,
	void* p, ewlfc_packet_state_t pkt_type, uint32 hslot)
{
	/*
	 * put the packet back to the head of queue
	 * - suppressed packet goes back to suppress sub-queue
	 * - pull out the header, if new or delayed packet
	 *
	 * Note: hslot is used only when header removal is done.
	 */
	wlfc_mac_descriptor_t* entry;
	int rc = BCME_OK;
	int prec, fifo_id;

	entry = _dhd_wlfc_find_table_entry(ctx, p);
	prec = DHD_PKTTAG_FIFO(PKTTAG(p));
	fifo_id = prec << 1;
	if (pkt_type == eWLFC_PKTTYPE_SUPPRESSED)
		fifo_id += 1;
	if (entry != NULL) {
		/*
		if this packet did not count against FIFO credit, it must have
		taken a requested_credit from the firmware (for pspoll etc.)
		*/
		if ((prec != AC_COUNT) && !DHD_PKTTAG_CREDITCHECK(PKTTAG(p)))
			entry->requested_credit++;

		if (pkt_type == eWLFC_PKTTYPE_DELAYED) {
			/* decrement sequence count */
			WLFC_DECR_SEQCOUNT(entry, prec);
			/* remove header first */
			rc = _dhd_wlfc_pullheader(ctx, p);
			if (rc != BCME_OK) {
				DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
				goto exit;
			}
		}

		if (_dhd_wlfc_prec_enq_with_drop(ctx->dhdp, &entry->psq, p, fifo_id, TRUE,
			WLFC_SEQCOUNT(entry, fifo_id>>1))
			== FALSE) {
			/* enque failed */
			DHD_ERROR(("Error: %s():%d, fifo_id(%d)\n",
				__FUNCTION__, __LINE__, fifo_id));
			rc = BCME_ERROR;
		}
	} else {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		rc = BCME_ERROR;
	}

exit:
	if (rc != BCME_OK) {
		ctx->stats.rollback_failed++;
		_dhd_wlfc_prec_drop(ctx->dhdp, fifo_id, p, FALSE);
	} else {
		ctx->stats.rollback++;
	}

	return rc;
} /* _dhd_wlfc_rollback_packet_toq */

/** Returns TRUE if host OS -> DHD flow control is allowed on the caller supplied interface */
static bool
_dhd_wlfc_allow_fc(athost_wl_status_info_t* ctx, uint8 ifid)
{
	int prec, ac_traffic = WLFC_NO_TRAFFIC;

	for (prec = 0; prec < AC_COUNT; prec++) {
		if (ctx->pkt_cnt_in_drv[ifid][prec] > 0) {
			if (ac_traffic == WLFC_NO_TRAFFIC)
				ac_traffic = prec + 1;
			else if (ac_traffic != (prec + 1))
				ac_traffic = WLFC_MULTI_TRAFFIC;
		}
	}

	if (ac_traffic >= 1 && ac_traffic <= AC_COUNT) {
		/* single AC (BE/BK/VI/VO) in queue */
		if (ctx->allow_fc) {
			return TRUE;
		} else {
			uint32 delta;
			uint32 curr_t = OSL_SYSUPTIME();

			if (ctx->fc_defer_timestamp == 0) {
				/* first single ac scenario */
				ctx->fc_defer_timestamp = curr_t;
				return FALSE;
			}

			/* single AC duration, this handles wrap around, e.g. 1 - ~0 = 2. */
			delta = curr_t - ctx->fc_defer_timestamp;
			if (delta >= WLFC_FC_DEFER_PERIOD_MS) {
				ctx->allow_fc = TRUE;
			}
		}
	} else {
		/* multiple ACs or BCMC in queue */
		ctx->allow_fc = FALSE;
		ctx->fc_defer_timestamp = 0;
	}

	return ctx->allow_fc;
} /* _dhd_wlfc_allow_fc */

/**
 * Starts or stops the flow of transmit packets from the host OS towards the DHD, depending on
 * low/high watermarks.
 */
static void
_dhd_wlfc_flow_control_check(athost_wl_status_info_t* ctx, struct pktq* pq, uint8 if_id)
{
	dhd_pub_t *dhdp;

	ASSERT(ctx);

	dhdp = (dhd_pub_t *)ctx->dhdp;
	ASSERT(dhdp);

	if (dhdp->skip_fc && dhdp->skip_fc((void *)dhdp, if_id))
		return;

	if ((ctx->hostif_flow_state[if_id] == OFF) && !_dhd_wlfc_allow_fc(ctx, if_id))
		return;

	if ((pq->n_pkts_tot <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) {
		/* start traffic */
		ctx->hostif_flow_state[if_id] = OFF;
		/*
		WLFC_DBGMESG(("qlen:%02d, if:%02d, ->OFF, start traffic %s()\n",
		pq->n_pkts_tot, if_id, __FUNCTION__));
		*/
		WLFC_DBGMESG(("F"));

		dhd_txflowcontrol(dhdp, if_id, OFF);

		ctx->toggle_host_if = 0;
	}

	if (pq->n_pkts_tot >= WLFC_FLOWCONTROL_HIWATER && ctx->hostif_flow_state[if_id] == OFF) {
		/* stop traffic */
		ctx->hostif_flow_state[if_id] = ON;
		/*
		WLFC_DBGMESG(("qlen:%02d, if:%02d, ->ON, stop traffic   %s()\n",
		pq->n_pkts_tot, if_id, __FUNCTION__));
		*/
		WLFC_DBGMESG(("N"));

		dhd_txflowcontrol(dhdp, if_id, ON);

		ctx->host_ifidx = if_id;
		ctx->toggle_host_if = 1;
	}

	return;
} /* _dhd_wlfc_flow_control_check */

/** XXX: Warning: this function directly accesses bus-transmit function */
static int
_dhd_wlfc_send_signalonly_packet(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry,
	uint8 ta_bmp)
{
	int rc = BCME_OK;
	void* p = NULL;
	int dummylen = ((dhd_pub_t *)ctx->dhdp)->hdrlen+ 16;
	dhd_pub_t *dhdp = (dhd_pub_t *)ctx->dhdp;

	if (dhdp->proptxstatus_txoff) {
		rc = BCME_NORESOURCE;
		return rc;
	}

	/* allocate a dummy packet */
	p = PKTGET(ctx->osh, dummylen, TRUE);
	if (p) {
		PKTPULL(ctx->osh, p, dummylen);
		DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), 0);
		_dhd_wlfc_pushheader(ctx, &p, TRUE, ta_bmp, entry->mac_handle, 0, 0, FALSE);
		DHD_PKTTAG_SETSIGNALONLY(PKTTAG(p), 1);
		DHD_PKTTAG_WLFCPKT_SET(PKTTAG(p), 1);
#ifdef PROP_TXSTATUS_DEBUG
		ctx->stats.signal_only_pkts_sent++;
#endif

#if defined(BCMPCIE)
		/* XXX : RAHUL : Verify the ifidx */
		rc = dhd_bus_txdata(dhdp->bus, p, ctx->host_ifidx);
#else
		rc = dhd_bus_txdata(dhdp->bus, p);
#endif
		if (rc != BCME_OK) {
			_dhd_wlfc_pullheader(ctx, p);
			PKTFREE(ctx->osh, p, TRUE);
		}
	} else {
		DHD_ERROR(("%s: couldn't allocate new %d-byte packet\n",
		           __FUNCTION__, dummylen));
		rc = BCME_NOMEM;
		dhdp->tx_pktgetfail++;
	}

	return rc;
} /* _dhd_wlfc_send_signalonly_packet */

/**
 * Called on eg receiving 'mac close' indication from dongle. Updates the per-MAC administration
 * maintained in caller supplied parameter 'entry'.
 *
 *    @param[in/out] entry  administration about a remote MAC entity
 *    @param[in]     prec   precedence queue for this remote MAC entitity
 *
 * Return value: TRUE if traffic availability changed
 */
static bool
_dhd_wlfc_traffic_pending_check(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry,
	int prec)
{
	bool rc = FALSE;

	if (entry->state == WLFC_STATE_CLOSE) {
		if ((pktqprec_n_pkts(&entry->psq, (prec << 1)) == 0) &&
			(pktqprec_n_pkts(&entry->psq, ((prec << 1) + 1)) == 0)) {
			/* no packets in both 'normal' and 'suspended' queues */
			if (entry->traffic_pending_bmp & NBITVAL(prec)) {
				rc = TRUE;
				entry->traffic_pending_bmp =
					entry->traffic_pending_bmp & ~ NBITVAL(prec);
			}
		} else {
			/* packets are queued in host for transmission to dongle */
			if (!(entry->traffic_pending_bmp & NBITVAL(prec))) {
				rc = TRUE;
				entry->traffic_pending_bmp =
					entry->traffic_pending_bmp | NBITVAL(prec);
			}
		}
	}

	if (rc) {
		/* request a TIM update to firmware at the next piggyback opportunity */
		if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp) {
			entry->send_tim_signal = 1;
			/*
			XXX: send a header only packet from the same context.
			--this should change to sending from a timeout or similar.
			*/
			_dhd_wlfc_send_signalonly_packet(ctx, entry, entry->traffic_pending_bmp);
			entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
			entry->send_tim_signal = 0;
		} else {
			rc = FALSE;
		}
	}

	return rc;
} /* _dhd_wlfc_traffic_pending_check */

/**
 * Called on receiving a 'd11 suppressed' or 'wl suppressed' tx status from the firmware. Enqueues
 * the packet to transmit to firmware again at a later opportunity.
 */
static int
_dhd_wlfc_enque_suppressed(athost_wl_status_info_t* ctx, int prec, void* p)
{
	wlfc_mac_descriptor_t* entry;

	entry = _dhd_wlfc_find_table_entry(ctx, p);
	if (entry == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_NOTFOUND;
	}
	/*
	- suppressed packets go to sub_queue[2*prec + 1] AND
	- delayed packets go to sub_queue[2*prec + 0] to ensure
	order of delivery.
	*/
	if (_dhd_wlfc_prec_enq_with_drop(ctx->dhdp, &entry->psq, p, ((prec << 1) + 1), FALSE,
		WLFC_SEQCOUNT(entry, prec))
		== FALSE) {
		ctx->stats.delayq_full_error++;
		/* WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); */
		WLFC_DBGMESG(("s"));
		return BCME_ERROR;
	}

	/* A packet has been pushed, update traffic availability bitmap, if applicable */
	_dhd_wlfc_traffic_pending_check(ctx, entry, prec);
	_dhd_wlfc_flow_control_check(ctx, &entry->psq, DHD_PKTTAG_IF(PKTTAG(p)));
	return BCME_OK;
}

/**
 * Called when a transmit packet is about to be 'committed' from the OS layer to a lower layer
 * towards the dongle (eg the DBUS layer). Updates wlfc administration. May modify packet.
 *
 *     @param[in/out] ctx    driver specific flow control administration
 *     @param[in/out] entry  The remote MAC entity for which the packet is destined.
 *     @param[in/out] packet Packet to send. This function optionally adds TLVs to the packet.
 *     @param[in] header_needed True if packet is 'new' to flow control
 *     @param[out] slot Handle to container in which the packet was 'parked'
 */
static int
_dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx,
	wlfc_mac_descriptor_t* entry, void** packet, int header_needed, uint32* slot)
{
	int rc = BCME_OK;
	int hslot = WLFC_HANGER_MAXITEMS;
	bool send_tim_update = FALSE;
	uint32 htod = 0;
	uint16 htodseq = 0;
	uint8 free_ctr;
	int gen = 0xff;
	dhd_pub_t *dhdp = (dhd_pub_t *)ctx->dhdp;
	void * p = *packet;

	*slot = hslot;

	if (entry == NULL) {
		entry = _dhd_wlfc_find_table_entry(ctx, p);
	}

	if (entry == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_ERROR;
	}

	if (entry->send_tim_signal) {
		/* sends a traffic indication bitmap to the dongle */
		send_tim_update = TRUE;
		entry->send_tim_signal = 0;
		entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
	}

	if (header_needed) {
		if (WLFC_GET_AFQ(dhdp->wlfc_mode)) {
			hslot = (uint)(entry - &ctx->destination_entries.nodes[0]);
		} else {
			hslot = _dhd_wlfc_hanger_get_free_slot(ctx->hanger);
		}
		gen = entry->generation;
		free_ctr = WLFC_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p)));
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
		_dhd_wlfc_bprint(ctx, "d%u.%u.%u-",
			(uint8)(entry - &ctx->destination_entries.nodes[0]), gen, free_ctr);
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
	} else {
		if (WLFC_GET_REUSESEQ(dhdp->wlfc_mode)) {
			htodseq = DHD_PKTTAG_H2DSEQ(PKTTAG(p));
		}

		hslot = WL_TXSTATUS_GET_HSLOT(DHD_PKTTAG_H2DTAG(PKTTAG(p)));

		if (WLFC_GET_REORDERSUPP(dhdp->wlfc_mode)) {
			gen = entry->generation;
		} else if (WLFC_GET_AFQ(dhdp->wlfc_mode)) {
			gen = WL_TXSTATUS_GET_GENERATION(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
		} else {
			_dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen);
		}

		free_ctr = WL_TXSTATUS_GET_FREERUNCTR(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
		_dhd_wlfc_bprint(ctx, "s%u.%u.%u-",
		(uint8)(entry - &ctx->destination_entries.nodes[0]), gen, free_ctr);
		if (WLFC_GET_REUSESEQ(dhdp->wlfc_mode)) {
			_dhd_wlfc_bprint(ctx, "%u.%u-",
				IS_WL_TO_REUSE_SEQ(DHD_PKTTAG_H2DSEQ(PKTTAG(p))),
				WL_SEQ_GET_NUM(DHD_PKTTAG_H2DSEQ(PKTTAG(p))));
		}
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
		/* remove old header */
		_dhd_wlfc_pullheader(ctx, p);
	}

	if (hslot >= WLFC_HANGER_MAXITEMS) {
		DHD_ERROR(("Error: %s():no hanger slot available\n", __FUNCTION__));
		return BCME_ERROR;
	}

	WL_TXSTATUS_SET_FREERUNCTR(htod, free_ctr);
	WL_TXSTATUS_SET_HSLOT(htod, hslot);
	WL_TXSTATUS_SET_FIFO(htod, DHD_PKTTAG_FIFO(PKTTAG(p)));
	WL_TXSTATUS_SET_FLAGS(htod, WLFC_PKTFLAG_PKTFROMHOST);
	WL_TXSTATUS_SET_GENERATION(htod, gen);
	DHD_PKTTAG_SETPKTDIR(PKTTAG(p), 1);

	if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) {
		/*
		Indicate that this packet is being sent in response to an
		explicit request from the firmware side.
		*/
		WLFC_PKTFLAG_SET_PKTREQUESTED(htod);
	} else {
		WLFC_PKTFLAG_CLR_PKTREQUESTED(htod);
	}

	rc = _dhd_wlfc_pushheader(ctx, &p, send_tim_update,
		entry->traffic_lastreported_bmp, entry->mac_handle, htod, htodseq, FALSE);
	if (rc == BCME_OK) {
		DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod);

		if (!WLFC_GET_AFQ(dhdp->wlfc_mode)) {
			wlfc_hanger_t *h = (wlfc_hanger_t*)(ctx->hanger);
			if (header_needed) {
				/*
				a new header was created for this packet.
				push to hanger slot and scrub q. Since bus
				send succeeded, increment seq number as well.
				*/
				rc = _dhd_wlfc_hanger_pushpkt(ctx->hanger, p, hslot);
				if (rc == BCME_OK) {
#ifdef PROP_TXSTATUS_DEBUG
					h->items[hslot].push_time =
						OSL_SYSUPTIME();
#endif
				} else {
					DHD_ERROR(("%s() hanger_pushpkt() failed, rc: %d\n",
						__FUNCTION__, rc));
				}
			} else {
				/* clear hanger state */
				if (((wlfc_hanger_t*)(ctx->hanger))->items[hslot].pkt != p)
					DHD_ERROR(("%s() pkt not match: cur %p, hanger pkt %p\n",
						__FUNCTION__, p, h->items[hslot].pkt));
				ASSERT(h->items[hslot].pkt == p);
				bcm_object_feature_set(h->items[hslot].pkt,
					BCM_OBJECT_FEATURE_PKT_STATE, 0);
				h->items[hslot].pkt_state = 0;
				h->items[hslot].pkt_txstatus = 0;
				h->items[hslot].state = WLFC_HANGER_ITEM_STATE_INUSE;
			}
		}

		if ((rc == BCME_OK) && header_needed) {
			/* increment free running sequence count */
			WLFC_INCR_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p)));
		}
	}
	*slot = hslot;
	*packet = p;
	return rc;
} /* _dhd_wlfc_pretx_pktprocess */

/**
 * A remote wireless mac may be temporarily 'closed' due to power management. Returns '1' if remote
 * mac is in the 'open' state, otherwise '0'.
 */
static int
_dhd_wlfc_is_destination_open(athost_wl_status_info_t* ctx,
	wlfc_mac_descriptor_t* entry, int prec)
{
	wlfc_mac_descriptor_t* interfaces = ctx->destination_entries.interfaces;

	if (entry->interface_id >= WLFC_MAX_IFNUM) {
		ASSERT(&ctx->destination_entries.other == entry);
		return 1;
	}

	if (interfaces[entry->interface_id].iftype ==
		WLC_E_IF_ROLE_P2P_GO) {
		/* - destination interface is of type p2p GO.
		For a p2pGO interface, if the destination is OPEN but the interface is
		CLOSEd, do not send traffic. But if the dstn is CLOSEd while there is
		destination-specific-credit left send packets. This is because the
		firmware storing the destination-specific-requested packet in queue.
		*/
		/* XXX: This behavior will change one PM1 protocol mod is complete */
		if ((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) &&
			(entry->requested_packet == 0)) {
			return 0;
		}
	}

	/* AP, p2p_go -> unicast desc entry, STA/p2p_cl -> interface desc. entry */
	if ((((entry->state == WLFC_STATE_CLOSE) ||
		(interfaces[entry->interface_id].state == WLFC_STATE_CLOSE)) &&
		(entry->requested_credit == 0) &&
		(entry->requested_packet == 0)) ||
		(!(entry->ac_bitmap & (1 << prec)))) {
		return 0;
	}

	return 1;
} /* _dhd_wlfc_is_destination_open */

/**
 * Dequeues a suppressed or delayed packet from a queue
 *    @param[in/out] ctx          Driver specific flow control administration
 *    @param[in]  prec            Precedence of queue to dequeue from
 *    @param[out] ac_credit_spent Boolean, returns 0 or 1
 *    @param[out] needs_hdr       Boolean, returns 0 or 1
 *    @param[out] entry_out       The remote MAC for which the packet is destined
 *    @param[in]  only_no_credit  If TRUE, searches all entries instead of just the active ones
 *
 * Return value: the dequeued packet
 */

static void*
_dhd_wlfc_deque_delayedq(athost_wl_status_info_t* ctx, int prec,
	uint8* ac_credit_spent, uint8* needs_hdr, wlfc_mac_descriptor_t** entry_out,
	bool only_no_credit)
{
	wlfc_mac_descriptor_t* entry;
	int total_entries;
	void* p = NULL;
	int i;
	uint8 credit_spent = ((prec == AC_COUNT) && !ctx->bcmc_credit_supported) ? 0 : 1;
	uint16 qlen;
	bool change_entry = FALSE;

	BCM_REFERENCE(qlen);
	BCM_REFERENCE(change_entry);

	*entry_out = NULL;
	/* most cases a packet will count against FIFO credit */
	*ac_credit_spent = credit_spent;

	/* search all entries, include nodes as well as interfaces */
	if (only_no_credit) {
		total_entries = ctx->requested_entry_count;
	} else {
		total_entries = ctx->active_entry_count;
	}

	for (i = 0; i < total_entries; i++) {
		if (only_no_credit) {
			entry = ctx->requested_entry[i];
		} else {
			entry = ctx->active_entry_head;
		}
		ASSERT(entry);

		if (entry->occupied && _dhd_wlfc_is_destination_open(ctx, entry, prec) &&
#ifdef PROPTX_MAXCOUNT
			(entry->transit_count < entry->transit_maxcount) &&
#endif /* PROPTX_MAXCOUNT */
			(entry->transit_count < WL_TXSTATUS_FREERUNCTR_MASK) &&
			(!entry->suppressed)) {
			*ac_credit_spent = credit_spent;
			if (entry->state == WLFC_STATE_CLOSE) {
				*ac_credit_spent = 0;
			}

			/* higher precedence will be picked up first,
			 * i.e. suppressed packets before delayed ones
			 */
			p = pktq_pdeq(&entry->psq, PSQ_SUP_IDX(prec));
			*needs_hdr = 0;
			if (p == NULL) {
				/* De-Q from delay Q */
				p = pktq_pdeq(&entry->psq, PSQ_DLY_IDX(prec));
				*needs_hdr = 1;
			}

			if (p != NULL) {
				bcm_pkt_validate_chk(p, "_dhd_wlfc_deque_afq");
				/* did the packet come from suppress sub-queue? */
				if (entry->requested_credit > 0) {
					entry->requested_credit--;
#ifdef PROP_TXSTATUS_DEBUG
					entry->dstncredit_sent_packets++;
#endif
				} else if (entry->requested_packet > 0) {
					entry->requested_packet--;
					DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p));
				}

				*entry_out = entry;
				ctx->pkt_cnt_in_q[DHD_PKTTAG_IF(PKTTAG(p))][prec]--;
				ctx->pkt_cnt_per_ac[prec]--;
				ctx->pkt_cnt_in_psq--;
#ifdef BULK_DEQUEUE
				/* Check pkts in delayq */
				if (entry->state == WLFC_STATE_OPEN) {
					entry->release_count[prec]++;
					qlen = pktq_mlen(&entry->psq,
						(1 << PSQ_SUP_IDX(prec) | 1 << PSQ_DLY_IDX(prec)));

					if (entry->release_count[prec] == ctx->max_release_count ||
						qlen == 0) {
						change_entry = TRUE;
						entry->release_count[prec] = 0;
					}

					if (change_entry) {
						/* move head */
						ctx->active_entry_head =
							ctx->active_entry_head->next;
					}
				}
#endif /* BULK_DEQUEUE */
				_dhd_wlfc_flow_control_check(ctx, &entry->psq,
					DHD_PKTTAG_IF(PKTTAG(p)));
				/*
				 * A packet has been picked up, update traffic availability bitmap,
				 * if applicable.
				 */
				_dhd_wlfc_traffic_pending_check(ctx, entry, prec);
				return p;
			}
		}
		if (!only_no_credit) {
			/* move head */
			ctx->active_entry_head = ctx->active_entry_head->next;
		}
	}
	return NULL;
} /* _dhd_wlfc_deque_delayedq */

/** Enqueues caller supplied packet on either a 'suppressed' or 'delayed' queue */
static int
_dhd_wlfc_enque_delayq(athost_wl_status_info_t* ctx, void* pktbuf, int prec)
{
	wlfc_mac_descriptor_t* entry;

	if (pktbuf != NULL) {
		entry = _dhd_wlfc_find_table_entry(ctx, pktbuf);
		if (entry == NULL) {
			DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
			return BCME_ERROR;
		}

		/*
		- suppressed packets go to sub_queue[2*prec + 1] AND
		- delayed packets go to sub_queue[2*prec + 0] to ensure
		order of delivery.
		*/
		if (_dhd_wlfc_prec_enq_with_drop(ctx->dhdp, &entry->psq, pktbuf, (prec << 1),
			FALSE, WLFC_SEQCOUNT(entry, prec))
			== FALSE) {
			WLFC_DBGMESG(("D"));
			ctx->stats.delayq_full_error++;
			return BCME_ERROR;
		}

#ifdef QMONITOR
		dhd_qmon_tx(&entry->qmon);
#endif

		/* A packet has been pushed, update traffic availability bitmap, if applicable */
		_dhd_wlfc_traffic_pending_check(ctx, entry, prec);
	}

	return BCME_OK;
} /* _dhd_wlfc_enque_delayq */

/** Returns TRUE if caller supplied packet is destined for caller supplied interface */
static bool _dhd_wlfc_ifpkt_fn(void* p, void *p_ifid)
{
	if (!p || !p_ifid)
		return FALSE;

	return (DHD_PKTTAG_WLFCPKT(PKTTAG(p))&& (*((uint8 *)p_ifid) == DHD_PKTTAG_IF(PKTTAG(p))));
}

/** Returns TRUE if caller supplied packet is destined for caller supplied remote MAC */
static bool _dhd_wlfc_entrypkt_fn(void* p, void *entry)
{
	if (!p || !entry)
		return FALSE;

	return (DHD_PKTTAG_WLFCPKT(PKTTAG(p))&& (entry == DHD_PKTTAG_ENTRY(PKTTAG(p))));
}

static void
_dhd_wlfc_return_implied_credit(athost_wl_status_info_t* wlfc, void* pkt)
{
	dhd_pub_t *dhdp;
	bool credit_return = FALSE;

	if (!wlfc || !pkt) {
		return;
	}

	dhdp = (dhd_pub_t *)(wlfc->dhdp);
	if (dhdp && (dhdp->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) &&
		DHD_PKTTAG_CREDITCHECK(PKTTAG(pkt))) {
		int lender, credit_returned = 0;
		uint8 fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pkt));

		credit_return = TRUE;

		/* Note that borrower is fifo_id */
		/* Return credits to highest priority lender first */
		for (lender = AC_COUNT; lender >= 0; lender--) {
			if (wlfc->credits_borrowed[fifo_id][lender] > 0) {
				wlfc->FIFO_credit[lender]++;
				wlfc->credits_borrowed[fifo_id][lender]--;
				credit_returned = 1;
				break;
			}
		}

		if (!credit_returned) {
			wlfc->FIFO_credit[fifo_id]++;
		}
	}

	BCM_REFERENCE(credit_return);
#if defined(DHD_WLFC_THREAD)
	if (credit_return) {
		_dhd_wlfc_thread_wakeup(dhdp);
	}
#endif /* defined(DHD_WLFC_THREAD) */
}

/** Removes and frees a packet from the hanger. Called during eg tx complete. */
static void
_dhd_wlfc_hanger_free_pkt(athost_wl_status_info_t* wlfc, uint32 slot_id, uint8 pkt_state,
	int pkt_txstatus)
{
	wlfc_hanger_t* hanger;
	wlfc_hanger_item_t* item;

	if (!wlfc)
		return;

	hanger = (wlfc_hanger_t*)wlfc->hanger;
	if (!hanger)
		return;

	if (slot_id == WLFC_HANGER_MAXITEMS)
		return;

	item = &hanger->items[slot_id];

	if (item->pkt) {
		item->pkt_state |= pkt_state;
		if (pkt_txstatus != -1)
			item->pkt_txstatus = (uint8)pkt_txstatus;
		bcm_object_feature_set(item->pkt, BCM_OBJECT_FEATURE_PKT_STATE, item->pkt_state);
		if (item->pkt_state == WLFC_HANGER_PKT_STATE_COMPLETE) {
			void *p = NULL;
			void *pkt = item->pkt;
			uint8 old_state = item->state;
			int ret = _dhd_wlfc_hanger_poppkt(wlfc->hanger, slot_id, &p, TRUE);
			BCM_REFERENCE(ret);
			BCM_REFERENCE(pkt);
			ASSERT((ret == BCME_OK) && p && (pkt == p));
			if (old_state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) {
				printf("ERROR: free a suppressed pkt %p state %d pkt_state %d\n",
					pkt, old_state, item->pkt_state);
			}
			ASSERT(old_state != WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED);

			/* free packet */
			wlfc->pkt_cnt_in_drv[DHD_PKTTAG_IF(PKTTAG(p))]
				[DHD_PKTTAG_FIFO(PKTTAG(p))]--;
			wlfc->stats.pktout++;
			dhd_txcomplete((dhd_pub_t *)wlfc->dhdp, p, item->pkt_txstatus);
			PKTFREE(wlfc->osh, p, TRUE);
		}
	} else {
		/* free slot */
		if (item->state == WLFC_HANGER_ITEM_STATE_FREE)
			DHD_ERROR(("Error: %s():%d Multiple TXSTATUS or BUSRETURNED: %d (%d)\n",
			    __FUNCTION__, __LINE__, item->pkt_state, pkt_state));
		item->state = WLFC_HANGER_ITEM_STATE_FREE;
	}
} /* _dhd_wlfc_hanger_free_pkt */

/** Called during eg detach() */
static void
_dhd_wlfc_pktq_flush(athost_wl_status_info_t* ctx, struct pktq *pq,
	bool dir, f_processpkt_t fn, void *arg, q_type_t q_type)
{
	int prec;
	dhd_pub_t *dhdp = (dhd_pub_t *)ctx->dhdp;

	ASSERT(dhdp);

	/* Optimize flush, if pktq len = 0, just return.
	 * pktq len of 0 means pktq's prec q's are all empty.
	 */
	if (pq->n_pkts_tot == 0) {
		return;
	}

	for (prec = 0; prec < pq->num_prec; prec++) {
		struct pktq_prec *q;
		void *p, *prev = NULL;

		q = &pq->q[prec];
		p = q->head;
		while (p) {
			bcm_pkt_validate_chk(p, "_dhd_wlfc_pktq_flush");
			if (fn == NULL || (*fn)(p, arg)) {
				bool head = (p == q->head);
				if (head)
					q->head = PKTLINK(p);
				else
					PKTSETLINK(prev, PKTLINK(p));
				if (q_type == Q_TYPE_PSQ) {
					if (!WLFC_GET_AFQ(dhdp->wlfc_mode) && (prec & 1)) {
						_dhd_wlfc_hanger_remove_reference(ctx->hanger, p);
					}
					ctx->pkt_cnt_in_q[DHD_PKTTAG_IF(PKTTAG(p))][prec>>1]--;
					ctx->pkt_cnt_per_ac[prec>>1]--;
					ctx->pkt_cnt_in_psq--;
					ctx->stats.cleanup_psq_cnt++;
					if (!(prec & 1)) {
						/* pkt in delayed q, so fake push BDC header for
						 * dhd_tcpack_check_xmit() and dhd_txcomplete().
						 */
						_dhd_wlfc_pushheader(ctx, &p, FALSE, 0, 0,
							0, 0, TRUE);
#ifdef DHDTCPACK_SUPPRESS
						if (dhd_tcpack_check_xmit(dhdp, p) == BCME_ERROR) {
							DHD_ERROR(("%s %d: tcpack_suppress ERROR!!!"
								" Stop using it\n",
								__FUNCTION__, __LINE__));
							dhd_tcpack_suppress_set(dhdp,
								TCPACK_SUP_OFF);
						}
#endif /* DHDTCPACK_SUPPRESS */
					}
				} else if (q_type == Q_TYPE_AFQ) {
					wlfc_mac_descriptor_t* entry =
						_dhd_wlfc_find_table_entry(ctx, p);
					if (entry->transit_count)
						entry->transit_count--;
					if (entry->suppr_transit_count) {
						entry->suppr_transit_count--;
						if (entry->suppressed &&
							(!entry->onbus_pkts_count) &&
							(!entry->suppr_transit_count))
							entry->suppressed = FALSE;
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
							_dhd_wlfc_bprint(ctx, "[sc]-");
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
					}
					_dhd_wlfc_return_implied_credit(ctx, p);
					ctx->stats.cleanup_fw_cnt++;
				}
				PKTSETLINK(p, NULL);
				if (dir) {
					ctx->pkt_cnt_in_drv[DHD_PKTTAG_IF(PKTTAG(p))][prec>>1]--;
					ctx->stats.pktout++;
					dhd_txcomplete(dhdp, p, FALSE);
				}
				PKTFREE(ctx->osh, p, dir);

				q->n_pkts--;
				pq->n_pkts_tot--;
#ifdef WL_TXQ_STALL
				q->dequeue_count++;
#endif

				p = (head ? q->head : PKTLINK(prev));
			} else {
				prev = p;
				p = PKTLINK(p);
			}
		}

		if (q->head == NULL) {
			ASSERT(q->n_pkts == 0);
			q->tail = NULL;
		}

	}

	if (fn == NULL)
		ASSERT(pq->n_pkts_tot == 0);
} /* _dhd_wlfc_pktq_flush */

#ifndef BCMDBUS
/** !BCMDBUS specific function. Dequeues a packet from the caller supplied queue. */
static void*
_dhd_wlfc_pktq_pdeq_with_fn(struct pktq *pq, int prec, f_processpkt_t fn, void *arg)
{
	struct pktq_prec *q;
	void *p, *prev = NULL;

	ASSERT(prec >= 0 && prec < pq->num_prec);

	q = &pq->q[prec];
	p = q->head;

	while (p) {
		if (fn == NULL || (*fn)(p, arg)) {
			break;
		} else {
			prev = p;
			p = PKTLINK(p);
		}
	}
	if (p == NULL)
		return NULL;

	bcm_pkt_validate_chk(p, "_dhd_wlfc_pktq_flush");

	if (prev == NULL) {
		if ((q->head = PKTLINK(p)) == NULL) {
			q->tail = NULL;
		}
	} else {
		PKTSETLINK(prev, PKTLINK(p));
		if (q->tail == p) {
			q->tail = prev;
		}
	}

	q->n_pkts--;

	pq->n_pkts_tot--;

#ifdef WL_TXQ_STALL
	q->dequeue_count++;
#endif

	PKTSETLINK(p, NULL);

	return p;
}

/** !BCMDBUS specific function */
static void
_dhd_wlfc_cleanup_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
{
	int prec;
	void *pkt = NULL, *head = NULL, *tail = NULL;
	struct pktq *txq = (struct pktq *)dhd_bus_txq(dhd->bus);
	athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger;
	wlfc_mac_descriptor_t* entry;

	dhd_os_sdlock_txq(dhd);
	for (prec = 0; prec < txq->num_prec; prec++) {
		while ((pkt = _dhd_wlfc_pktq_pdeq_with_fn(txq, prec, fn, arg))) {
#ifdef DHDTCPACK_SUPPRESS
			if (dhd_tcpack_check_xmit(dhd, pkt) == BCME_ERROR) {
				DHD_ERROR(("%s %d: tcpack_suppress ERROR!!! Stop using it\n",
					__FUNCTION__, __LINE__));
				dhd_tcpack_suppress_set(dhd, TCPACK_SUP_OFF);
			}
#endif /* DHDTCPACK_SUPPRESS */
			if (!head) {
				head = pkt;
			}
			if (tail) {
				PKTSETLINK(tail, pkt);
			}
			tail = pkt;
		}
	}
	dhd_os_sdunlock_txq(dhd);

	while ((pkt = head)) {
		head = PKTLINK(pkt);
		PKTSETLINK(pkt, NULL);
		entry = _dhd_wlfc_find_table_entry(wlfc, pkt);

		if (!WLFC_GET_AFQ(dhd->wlfc_mode) &&
			!_dhd_wlfc_hanger_remove_reference(h, pkt)) {
			DHD_ERROR(("%s: can't find pkt(%p) in hanger, free it anyway\n",
				__FUNCTION__, pkt));
		}
		if (entry->transit_count)
			entry->transit_count--;
		if (entry->suppr_transit_count) {
			entry->suppr_transit_count--;
			if (entry->suppressed &&
				(!entry->onbus_pkts_count) &&
				(!entry->suppr_transit_count))
				entry->suppressed = FALSE;
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
				_dhd_wlfc_bprint(wlfc, "[sc]-");
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
		}
		_dhd_wlfc_return_implied_credit(wlfc, pkt);
		wlfc->pkt_cnt_in_drv[DHD_PKTTAG_IF(PKTTAG(pkt))][DHD_PKTTAG_FIFO(PKTTAG(pkt))]--;
		wlfc->stats.pktout++;
		wlfc->stats.cleanup_txq_cnt++;
		dhd_txcomplete(dhd, pkt, FALSE);
		PKTFREE(wlfc->osh, pkt, TRUE);
	}
} /* _dhd_wlfc_cleanup_txq */

#endif /* !BCMDBUS */

/** called during eg detach */
void
_dhd_wlfc_cleanup(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
{
	int i;
	int total_entries;
	athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	wlfc_mac_descriptor_t* table;
	wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger;

	wlfc->stats.cleanup_txq_cnt = 0;
	wlfc->stats.cleanup_psq_cnt = 0;
	wlfc->stats.cleanup_fw_cnt = 0;

	/*
	*  flush sequence should be txq -> psq -> hanger/afq, hanger has to be last one
	*/
#ifndef BCMDBUS
	/* flush bus->txq */
	_dhd_wlfc_cleanup_txq(dhd, fn, arg);
#endif /* BCMDBUS */

	/* flush psq, search all entries, include nodes as well as interfaces */
	total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t);
	table = (wlfc_mac_descriptor_t*)&wlfc->destination_entries;

	for (i = 0; i < total_entries; i++) {
		if (table[i].occupied) {
			/* release packets held in PSQ (both delayed and suppressed) */
			if (table[i].psq.n_pkts_tot) {
				WLFC_DBGMESG(("%s(): PSQ[%d].len = %d\n",
					__FUNCTION__, i, table[i].psq.n_pkts_tot));
				_dhd_wlfc_pktq_flush(wlfc, &table[i].psq, TRUE,
					fn, arg, Q_TYPE_PSQ);
			}

			/* free packets held in AFQ */
			if (WLFC_GET_AFQ(dhd->wlfc_mode) && (table[i].afq.n_pkts_tot)) {
				_dhd_wlfc_pktq_flush(wlfc, &table[i].afq, TRUE,
					fn, arg, Q_TYPE_AFQ);
			}

			if ((fn == NULL) && (&table[i] != &wlfc->destination_entries.other)) {
				table[i].occupied = 0;
				if (table[i].transit_count || table[i].suppr_transit_count) {
					DHD_ERROR(("%s: table[%d] transit(%d), suppr_tansit(%d)\n",
						__FUNCTION__, i,
						table[i].transit_count,
						table[i].suppr_transit_count));
				}
			}
		}
	}

	/*
		. flush remained pkt in hanger queue, not in bus->txq nor psq.
		. the remained pkt was successfully downloaded to dongle already.
		. hanger slot state cannot be set to free until receive txstatus update.
	*/
	if (!WLFC_GET_AFQ(dhd->wlfc_mode)) {
		for (i = 0; i < h->max_items; i++) {
			if ((h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) ||
				(h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED)) {
				if (fn == NULL || (*fn)(h->items[i].pkt, arg)) {
					h->items[i].state = WLFC_HANGER_ITEM_STATE_FLUSHED;
				}
			}
		}
	}

	return;
} /* _dhd_wlfc_cleanup */

/** Called after eg the dongle signalled a new remote MAC that it connected with to the DHD */
static int
_dhd_wlfc_mac_entry_update(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry,
	uint8 action, uint8 ifid, uint8 iftype, uint8* ea,
	f_processpkt_t fn, void *arg)
{
	int rc = BCME_OK;
	uint8 i;

	BCM_REFERENCE(i);

#ifdef QMONITOR
	dhd_qmon_reset(&entry->qmon);
#endif

	if ((action == eWLFC_MAC_ENTRY_ACTION_ADD) || (action == eWLFC_MAC_ENTRY_ACTION_UPDATE)) {
		entry->occupied = 1;
		entry->state = WLFC_STATE_OPEN;
		entry->requested_credit = 0;
		entry->interface_id = ifid;
		entry->iftype = iftype;
		entry->ac_bitmap = 0xff; /* update this when handling APSD */
#ifdef BULK_DEQUEUE
		for (i = 0; i < AC_COUNT + 1; i++) {
			entry->release_count[i] = 0;
		}
#endif /* BULK_DEQUEUE */
		/* for an interface entry we may not care about the MAC address */
		if (ea != NULL)
			memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN);

		if (action == eWLFC_MAC_ENTRY_ACTION_ADD) {
			entry->suppressed = FALSE;
			entry->transit_count = 0;
#if defined(WL_EXT_IAPSTA) && defined(PROPTX_MAXCOUNT)
			entry->transit_maxcount = wl_ext_get_wlfc_maxcount(ctx->dhdp, ifid);
#endif /* PROPTX_MAXCOUNT */
			entry->suppr_transit_count = 0;
			entry->onbus_pkts_count = 0;
		}

		if (action == eWLFC_MAC_ENTRY_ACTION_ADD) {
			dhd_pub_t *dhdp = (dhd_pub_t *)(ctx->dhdp);

			pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN);
			_dhd_wlfc_flow_control_check(ctx, &entry->psq, ifid);

			if (WLFC_GET_AFQ(dhdp->wlfc_mode)) {
				pktq_init(&entry->afq, WLFC_AFQ_PREC_COUNT, WLFC_PSQ_LEN);
			}

			if (entry->next == NULL) {
				/* not linked to anywhere, add to tail */
				if (ctx->active_entry_head) {
					entry->prev = ctx->active_entry_head->prev;
					ctx->active_entry_head->prev->next = entry;
					ctx->active_entry_head->prev = entry;
					entry->next = ctx->active_entry_head;
				} else {
					ASSERT(ctx->active_entry_count == 0);
					entry->prev = entry->next = entry;
					ctx->active_entry_head = entry;
				}
				ctx->active_entry_count++;
			} else {
				DHD_ERROR(("%s():%d, entry(%d)\n", __FUNCTION__, __LINE__,
					(int)(entry - &ctx->destination_entries.nodes[0])));
			}
		}
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
		for (i = 0; i < (AC_COUNT + 1); i++) {
			entry->last_send_seq[i] = 255;
			entry->last_complete_seq[i] = 255;
		}
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
	} else if (action == eWLFC_MAC_ENTRY_ACTION_DEL) {
		/* When the entry is deleted, the packets that are queued in the entry must be
		   cleanup. The cleanup action should be before the occupied is set as 0.
		*/
		_dhd_wlfc_cleanup(ctx->dhdp, fn, arg);
		_dhd_wlfc_flow_control_check(ctx, &entry->psq, ifid);

		entry->occupied = 0;
		entry->state = WLFC_STATE_CLOSE;
		memset(&entry->ea[0], 0, ETHER_ADDR_LEN);

		if (entry->next) {
			/* not floating, remove from Q */
			if (ctx->active_entry_count <= 1) {
				/* last item */
				ctx->active_entry_head = NULL;
				ctx->active_entry_count = 0;
			} else {
				entry->prev->next = entry->next;
				entry->next->prev = entry->prev;
				if (entry == ctx->active_entry_head) {
					ctx->active_entry_head = entry->next;
				}
				ctx->active_entry_count--;
			}
			entry->next = entry->prev = NULL;
		} else {
			DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		}
	}
	return rc;
} /* _dhd_wlfc_mac_entry_update */

#ifdef LIMIT_BORROW

/** LIMIT_BORROW specific function */
static int
_dhd_wlfc_borrow_credit(athost_wl_status_info_t* ctx, int highest_lender_ac, int borrower_ac,
	bool bBorrowAll)
{
	int lender_ac, borrow_limit = 0;
	int rc = -1;

	if (ctx == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return -1;
	}

	/* Borrow from lowest priority available AC (including BC/MC credits) */
	for (lender_ac = 0; lender_ac <= highest_lender_ac; lender_ac++) {
		if (!bBorrowAll) {
			borrow_limit = ctx->Init_FIFO_credit[lender_ac]/WLFC_BORROW_LIMIT_RATIO;
		} else {
			borrow_limit = 0;
		}

		if (ctx->FIFO_credit[lender_ac] > borrow_limit) {
			ctx->credits_borrowed[borrower_ac][lender_ac]++;
			ctx->FIFO_credit[lender_ac]--;
			rc = lender_ac;
			break;
		}
	}

	return rc;
}

/** LIMIT_BORROW specific function */
static int _dhd_wlfc_return_credit(athost_wl_status_info_t* ctx, int lender_ac, int borrower_ac)
{
	if ((ctx == NULL) || (lender_ac < 0) || (lender_ac > AC_COUNT) ||
		(borrower_ac < 0) || (borrower_ac > AC_COUNT)) {
		DHD_ERROR(("Error: %s():%d, ctx(%p), lender_ac(%d), borrower_ac(%d)\n",
			__FUNCTION__, __LINE__, ctx, lender_ac, borrower_ac));

		return BCME_BADARG;
	}

	ctx->credits_borrowed[borrower_ac][lender_ac]--;
	ctx->FIFO_credit[lender_ac]++;

	return BCME_OK;
}

#endif /* LIMIT_BORROW */

/**
 * Called on an interface event (WLC_E_IF) indicated by firmware.
 *     @param action : eg eWLFC_MAC_ENTRY_ACTION_UPDATE or eWLFC_MAC_ENTRY_ACTION_ADD
 */
static int
_dhd_wlfc_interface_entry_update(void* state,
	uint8 action, uint8 ifid, uint8 iftype, uint8* ea)
{
	athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
	wlfc_mac_descriptor_t* entry;

	if (ifid >= WLFC_MAX_IFNUM)
		return BCME_BADARG;

	entry = &ctx->destination_entries.interfaces[ifid];

	return _dhd_wlfc_mac_entry_update(ctx, entry, action, ifid, iftype, ea,
		_dhd_wlfc_ifpkt_fn, &ifid);
}

/**
 * Called eg on receiving a WLC_E_BCMC_CREDIT_SUPPORT event from the dongle (broadcast/multicast
 * specific)
 */
static int
_dhd_wlfc_BCMCCredit_support_update(void* state)
{
	athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;

	ctx->bcmc_credit_supported = TRUE;
	return BCME_OK;
}

/** Called eg on receiving a WLC_E_FIFO_CREDIT_MAP event from the dongle */
static int
_dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits)
{
	athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
	int i;

	for (i = 0; i <= 4; i++) {
		if (ctx->Init_FIFO_credit[i] != ctx->FIFO_credit[i]) {
			DHD_ERROR(("%s: credit[i] is not returned, (%d %d)\n",
				__FUNCTION__, ctx->Init_FIFO_credit[i], ctx->FIFO_credit[i]));
		}
	}

	/* update the AC FIFO credit map */
	ctx->FIFO_credit[0] += (credits[0] - ctx->Init_FIFO_credit[0]);
	ctx->FIFO_credit[1] += (credits[1] - ctx->Init_FIFO_credit[1]);
	ctx->FIFO_credit[2] += (credits[2] - ctx->Init_FIFO_credit[2]);
	ctx->FIFO_credit[3] += (credits[3] - ctx->Init_FIFO_credit[3]);
	ctx->FIFO_credit[4] += (credits[4] - ctx->Init_FIFO_credit[4]);

	ctx->Init_FIFO_credit[0] = credits[0];
	ctx->Init_FIFO_credit[1] = credits[1];
	ctx->Init_FIFO_credit[2] = credits[2];
	ctx->Init_FIFO_credit[3] = credits[3];
	ctx->Init_FIFO_credit[4] = credits[4];

	/* credit for ATIM FIFO is not used yet. */
	ctx->Init_FIFO_credit[5] = ctx->FIFO_credit[5] = 0;

	return BCME_OK;
}

/**
 * Called during committing of a transmit packet from the OS DHD layer to the next layer towards
 * the dongle (eg the DBUS layer). All transmit packets flow via this function to the next layer.
 *
 *     @param[in/out] ctx      Driver specific flow control administration
 *     @param[in] ac           Access Category (QoS) of called supplied packet
 *     @param[in] commit_info  Contains eg the packet to send
 *     @param[in] fcommit      Function pointer to transmit function of next software layer
 *     @param[in] commit_ctx   Opaque context used when calling next layer
 */
static int
_dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac,
    dhd_wlfc_commit_info_t *commit_info, f_commitpkt_t fcommit, void* commit_ctx)
{
	uint32 hslot;
	int	rc;
	dhd_pub_t *dhdp = (dhd_pub_t *)(ctx->dhdp);

	/*
		if ac_fifo_credit_spent = 0

		This packet will not count against the FIFO credit.
		To ensure the txstatus corresponding to this packet
		does not provide an implied credit (default behavior)
		mark the packet accordingly.

		if ac_fifo_credit_spent = 1

		This is a normal packet and it counts against the FIFO
		credit count.
	*/
	DHD_PKTTAG_SETCREDITCHECK(PKTTAG(commit_info->p), commit_info->ac_fifo_credit_spent);
	rc = _dhd_wlfc_pretx_pktprocess(ctx, commit_info->mac_entry, &commit_info->p,
	     commit_info->needs_hdr, &hslot);

#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
	_dhd_wlfc_check_send_order(ctx, commit_info->mac_entry, commit_info->p);
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
	if (rc == BCME_OK) {
		rc = fcommit(commit_ctx, commit_info->p);
		if (rc == BCME_OK) {
			uint8 gen = WL_TXSTATUS_GET_GENERATION(
				DHD_PKTTAG_H2DTAG(PKTTAG(commit_info->p)));
			dhd_txpkt_log_and_dump(dhdp, commit_info->p, NULL);
			ctx->stats.pkt2bus++;
			if (commit_info->ac_fifo_credit_spent || (ac == AC_COUNT)) {
				ctx->stats.send_pkts[ac]++;
				WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac);
			}

			if (gen != commit_info->mac_entry->generation) {
				/* will be suppressed back by design */
				if (!commit_info->mac_entry->suppressed) {
					commit_info->mac_entry->suppressed = TRUE;
				}
				commit_info->mac_entry->suppr_transit_count++;
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
				_dhd_wlfc_bprint(ctx, "[si%u]-",
					commit_info->mac_entry->suppr_transit_count);
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
			}
			commit_info->mac_entry->transit_count++;
			commit_info->mac_entry->onbus_pkts_count++;
		} else if (commit_info->needs_hdr) {
			if (!WLFC_GET_AFQ(dhdp->wlfc_mode)) {
				void *pout = NULL;
				/* pop hanger for delayed packet */
				_dhd_wlfc_hanger_poppkt(ctx->hanger, WL_TXSTATUS_GET_HSLOT(
					DHD_PKTTAG_H2DTAG(PKTTAG(commit_info->p))), &pout, TRUE);
				ASSERT(commit_info->p == pout);
			}
		}
	} else {
		ctx->stats.generic_error++;
	}

	if (rc != BCME_OK) {
		/*
		   pretx pkt process or bus commit has failed, rollback.
		   - remove wl-header for a delayed packet
		   - save wl-header header for suppressed packets
		   - reset credit check flag
		*/
		_dhd_wlfc_rollback_packet_toq(ctx, commit_info->p, commit_info->pkt_type, hslot);
		DHD_PKTTAG_SETCREDITCHECK(PKTTAG(commit_info->p), 0);
	}

	return rc;
} /* _dhd_wlfc_handle_packet_commit */

/** Returns remote MAC descriptor for caller supplied MAC address */
static uint8
_dhd_wlfc_find_mac_desc_id_from_mac(dhd_pub_t *dhdp, uint8 *ea)
{
	wlfc_mac_descriptor_t* table =
		((athost_wl_status_info_t*)dhdp->wlfc_state)->destination_entries.nodes;
	uint8 table_index;

	if (ea != NULL) {
		for (table_index = 0; table_index < WLFC_MAC_DESC_TABLE_SIZE; table_index++) {
			if ((memcmp(ea, &table[table_index].ea[0], ETHER_ADDR_LEN) == 0) &&
				table[table_index].occupied)
				return table_index;
		}
	}
	return WLFC_MAC_DESC_ID_INVALID;
}

/**
 * Called when the host receives a WLFC_CTL_TYPE_TXSTATUS event from the dongle, indicating the
 * status of a frame that the dongle attempted to transmit over the wireless medium.
 */
static int
dhd_wlfc_suppressed_acked_update(dhd_pub_t *dhd, uint16 hslot, uint8 prec, uint8 hcnt)
{
	athost_wl_status_info_t* ctx;
	wlfc_mac_descriptor_t* entry = NULL;
	struct pktq *pq;
	struct pktq_prec *q;
	void *p, *b;

	if (!dhd) {
		DHD_ERROR(("%s: dhd(%p)\n", __FUNCTION__, dhd));
		return BCME_BADARG;
	}
	ctx = (athost_wl_status_info_t*)dhd->wlfc_state;
	if (!ctx) {
		DHD_ERROR(("%s: ctx(%p)\n", __FUNCTION__, ctx));
		return BCME_ERROR;
	}

	ASSERT(hslot < (WLFC_MAC_DESC_TABLE_SIZE + WLFC_MAX_IFNUM + 1));

	if (hslot < WLFC_MAC_DESC_TABLE_SIZE)
		entry  = &ctx->destination_entries.nodes[hslot];
	else if (hslot < (WLFC_MAC_DESC_TABLE_SIZE + WLFC_MAX_IFNUM))
		entry = &ctx->destination_entries.interfaces[hslot - WLFC_MAC_DESC_TABLE_SIZE];
	else
		entry = &ctx->destination_entries.other;

	pq = &entry->psq;

	ASSERT(((prec << 1) + 1) < pq->num_prec);

	q = &pq->q[((prec << 1) + 1)];

	b = NULL;
	p = q->head;

	while (p && (hcnt != WL_TXSTATUS_GET_FREERUNCTR(DHD_PKTTAG_H2DTAG(PKTTAG(p))))) {
		b = p;
		p = PKTLINK(p);
	}

	if (p == NULL) {
		/* none is matched */
		if (b) {
			DHD_ERROR(("%s: can't find matching seq(%d)\n", __FUNCTION__, hcnt));
		} else {
			DHD_ERROR(("%s: queue is empty\n", __FUNCTION__));
		}

		return BCME_ERROR;
	}

	if (!b) {
		/* head packet is matched */
		if ((q->head = PKTLINK(p)) == NULL) {
			q->tail = NULL;
		}
	} else {
		/* middle packet is matched */
		PKTSETLINK(b, PKTLINK(p));
		if (PKTLINK(p) == NULL) {
			q->tail = b;
		}
	}

	q->n_pkts--;
	pq->n_pkts_tot--;

#ifdef WL_TXQ_STALL
	q->dequeue_count++;
#endif

	ctx->pkt_cnt_in_q[DHD_PKTTAG_IF(PKTTAG(p))][prec]--;
	ctx->pkt_cnt_per_ac[prec]--;

	PKTSETLINK(p, NULL);

	if (WLFC_GET_AFQ(dhd->wlfc_mode)) {
		_dhd_wlfc_enque_afq(ctx, p);
	} else {
		_dhd_wlfc_hanger_pushpkt(ctx->hanger, p, hslot);
	}

	entry->transit_count++;

	return BCME_OK;
}

static int
_dhd_wlfc_compressed_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info, uint8 len, void** p_mac)
{
	uint8 status_flag_ori, status_flag;
	uint32 status;
	int ret = BCME_OK;
	int remove_from_hanger_ori, remove_from_hanger = 1;
	void* pktbuf = NULL;
	uint8 fifo_id = 0, gen = 0, count = 0, hcnt;
	uint16 hslot;
	wlfc_mac_descriptor_t* entry = NULL;
	athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	uint16 seq = 0, seq_fromfw = 0, seq_num = 0;
	uint16 pktfate_status;

	memcpy(&status, pkt_info, sizeof(uint32));
	status = ltoh32(status);
	status_flag = WL_TXSTATUS_GET_FLAGS(status);
	hcnt = WL_TXSTATUS_GET_FREERUNCTR(status);
	hslot = WL_TXSTATUS_GET_HSLOT(status);
	fifo_id = WL_TXSTATUS_GET_FIFO(status);
	gen = WL_TXSTATUS_GET_GENERATION(status);

	if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) {
		memcpy(&seq, pkt_info + WLFC_CTL_VALUE_LEN_TXSTATUS, WLFC_CTL_VALUE_LEN_SEQ);
		seq = ltoh16(seq);
		seq_fromfw = GET_WL_HAS_ASSIGNED_SEQ(seq);
		seq_num = WL_SEQ_GET_NUM(seq);
	}

	wlfc->stats.txstatus_in += len;

	if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) {
		wlfc->stats.pkt_freed += len;
	} else if (status_flag == WLFC_CTL_PKTFLAG_DISCARD_NOACK) {
		wlfc->stats.pkt_freed += len;
	} else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) {
		wlfc->stats.d11_suppress += len;
		remove_from_hanger = 0;
	} else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) {
		wlfc->stats.wl_suppress += len;
		remove_from_hanger = 0;
	} else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) {
		wlfc->stats.wlc_tossed_pkts += len;
	} else if (status_flag == WLFC_CTL_PKTFLAG_SUPPRESS_ACKED) {
		wlfc->stats.pkt_freed += len;
	} else if (status_flag == WLFC_CTL_PKTFLAG_EXPIRED) {
		wlfc->stats.pkt_exptime += len;
	} else if (status_flag == WLFC_CTL_PKTFLAG_DROPPED) {
		wlfc->stats.pkt_dropped += len;
	}

	if (dhd->proptxstatus_txstatus_ignore) {
		if (!remove_from_hanger) {
			DHD_ERROR(("suppress txstatus: %d\n", status_flag));
		}
		return BCME_OK;
	}

	status_flag_ori = status_flag;
	remove_from_hanger_ori = remove_from_hanger;

	while (count < len) {
		if (status_flag == WLFC_CTL_PKTFLAG_SUPPRESS_ACKED) {
			dhd_wlfc_suppressed_acked_update(dhd, hslot, fifo_id, hcnt);
		}
		if (WLFC_GET_AFQ(dhd->wlfc_mode)) {
			ret = _dhd_wlfc_deque_afq(wlfc, hslot, hcnt, fifo_id, &pktbuf);
		} else {
			status_flag = status_flag_ori;
			remove_from_hanger = remove_from_hanger_ori;
			ret = _dhd_wlfc_hanger_poppkt(wlfc->hanger, hslot, &pktbuf, FALSE);
			if (!pktbuf) {
				_dhd_wlfc_hanger_free_pkt(wlfc, hslot,
					WLFC_HANGER_PKT_STATE_TXSTATUS, -1);
				goto cont;
			} else {
				wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger;
				if (h->items[hslot].state == WLFC_HANGER_ITEM_STATE_FLUSHED) {
					status_flag = WLFC_CTL_PKTFLAG_DISCARD;
					remove_from_hanger = 1;
				}
			}
		}

		if ((ret != BCME_OK) || !pktbuf) {
			goto cont;
		}

		bcm_pkt_validate_chk(pktbuf, "_dhd_wlfc_compressed_txstatus_update");

		pktfate_status = ltoh16(status_flag_ori) & WLFC_CTL_PKTFLAG_MASK;
		dhd_txpkt_log_and_dump(dhd, pktbuf, &pktfate_status);

		/* set fifo_id to correct value because not all FW does that */
		fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf));

		entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf);

		if (!remove_from_hanger) {
			/* this packet was suppressed */
			if (!entry->suppressed || (entry->generation != gen)) {
				if (!entry->suppressed) {
					entry->suppr_transit_count = entry->transit_count;
					if (p_mac) {
						*p_mac = entry;
					}
				} else {
					DHD_ERROR(("gen(%d), entry->generation(%d)\n",
						gen, entry->generation));
				}
				entry->suppressed = TRUE;

#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
				_dhd_wlfc_bprint(wlfc, "[ss%u.%u.%u]-",
					(uint8)(entry - &wlfc->destination_entries.nodes[0]),
					entry->generation,
					entry->suppr_transit_count);
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
			}
			entry->generation = gen;
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
			if (gen == WL_TXSTATUS_GET_GENERATION(DHD_PKTTAG_H2DTAG(PKTTAG(pktbuf)))) {
				printf("==%d.%d==\n", gen, hcnt);
			}
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
		}

#ifdef PROP_TXSTATUS_DEBUG
		if (!WLFC_GET_AFQ(dhd->wlfc_mode))
		{
			uint32 new_t = OSL_SYSUPTIME();
			uint32 old_t;
			uint32 delta;
			old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[hslot].push_time;

			wlfc->stats.latency_sample_count++;
			if (new_t > old_t)
				delta = new_t - old_t;
			else
				delta = 0xffffffff + new_t - old_t;
			wlfc->stats.total_status_latency += delta;
			wlfc->stats.latency_most_recent = delta;

			wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta;
			if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32))
				wlfc->stats.idx_delta = 0;
		}
#endif /* PROP_TXSTATUS_DEBUG */

		/* pick up the implicit credit from this packet */
		if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) {
			_dhd_wlfc_return_implied_credit(wlfc, pktbuf);
		} else {
			/*
			if this packet did not count against FIFO credit, it must have
			taken a requested_credit from the destination entry (for pspoll etc.)
			*/
			if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf))) {
				entry->requested_credit++;
#if defined(DHD_WLFC_THREAD)
				_dhd_wlfc_thread_wakeup(dhd);
#endif /* DHD_WLFC_THREAD */
			}
#ifdef PROP_TXSTATUS_DEBUG
			entry->dstncredit_acks++;
#endif
		}

		if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) ||
			(status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) {
			/* save generation bit inside packet */
			WL_TXSTATUS_SET_GENERATION(DHD_PKTTAG_H2DTAG(PKTTAG(pktbuf)), gen);

			if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) {
				WL_SEQ_SET_REUSE(DHD_PKTTAG_H2DSEQ(PKTTAG(pktbuf)), seq_fromfw);
				WL_SEQ_SET_NUM(DHD_PKTTAG_H2DSEQ(PKTTAG(pktbuf)), seq_num);
			}

			ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf);
			if (ret != BCME_OK) {
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
				_dhd_wlfc_bprint(wlfc, "f%u.%u.%u-",
					(uint8)(entry - &wlfc->destination_entries.nodes[0]),
					gen,
					hcnt);
				_dhd_wlfc_check_complete_order(wlfc, entry, pktbuf);
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
				/* delay q is full, drop this packet */
				DHD_WLFC_QMON_COMPLETE(entry);
				_dhd_wlfc_prec_drop(dhd, (fifo_id << 1) + 1, pktbuf, FALSE);
			} else {
				if (!WLFC_GET_AFQ(dhd->wlfc_mode)) {
					/* Mark suppressed to avoid a double free
					during wlfc cleanup
					*/
					_dhd_wlfc_hanger_mark_suppressed(wlfc->hanger, hslot, gen);
				}
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
				_dhd_wlfc_bprint(wlfc, "r%u.%u.%u.%u-",
					status_flag,
					(uint8)(entry - &wlfc->destination_entries.nodes[0]),
					gen,
					hcnt);
				if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) {
					_dhd_wlfc_bprint(wlfc, "%u.%u-", seq_fromfw, seq_num);
				}

#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
			}
		} else {
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
			_dhd_wlfc_bprint(wlfc, "c%u.%u.%u.%u-",
				status_flag,
				(uint8)(entry - &wlfc->destination_entries.nodes[0]),
				gen,
				hcnt);
			_dhd_wlfc_check_complete_order(wlfc, entry, pktbuf);
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */

			DHD_WLFC_QMON_COMPLETE(entry);

			if (!WLFC_GET_AFQ(dhd->wlfc_mode)) {
				_dhd_wlfc_hanger_free_pkt(wlfc, hslot,
					WLFC_HANGER_PKT_STATE_TXSTATUS, TRUE);
			} else {
				dhd_txcomplete(dhd, pktbuf, TRUE);
				wlfc->pkt_cnt_in_drv[DHD_PKTTAG_IF(PKTTAG(pktbuf))]
					[DHD_PKTTAG_FIFO(PKTTAG(pktbuf))]--;
				wlfc->stats.pktout++;
				/* free the packet */
				PKTFREE(wlfc->osh, pktbuf, TRUE);
			}
		}
		/* pkt back from firmware side */
		if (entry->transit_count)
			entry->transit_count--;
		if (entry->suppr_transit_count) {
			entry->suppr_transit_count--;
			if (entry->suppressed &&
				(!entry->onbus_pkts_count) &&
				(!entry->suppr_transit_count))
				entry->suppressed = FALSE;
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
				_dhd_wlfc_bprint(wlfc, "[sc]-");
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
		}

cont:
		hcnt = (hcnt + 1) & WL_TXSTATUS_FREERUNCTR_MASK;
		if (!WLFC_GET_AFQ(dhd->wlfc_mode)) {
			hslot = (hslot + 1) & WL_TXSTATUS_HSLOT_MASK;
		}

		if (WLFC_GET_REUSESEQ(dhd->wlfc_mode) && seq_fromfw) {
			seq_num = (seq_num + 1) & WL_SEQ_NUM_MASK;
		}

		count++;
	}

	return BCME_OK;
} /* _dhd_wlfc_compressed_txstatus_update */

/**
 * Called when eg host receives a 'WLFC_CTL_TYPE_FIFO_CREDITBACK' event from the dongle.
 *    @param[in] credits caller supplied credit that will be added to the host credit.
 */
static int
_dhd_wlfc_fifocreditback_indicate(dhd_pub_t *dhd, uint8* credits)
{
	int i;
	athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	for (i = 0; i < WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK; i++) {
#ifdef PROP_TXSTATUS_DEBUG
		wlfc->stats.fifo_credits_back[i] += credits[i];
#endif

		/* update FIFO credits */
		if (dhd->proptxstatus_mode == WLFC_FCMODE_EXPLICIT_CREDIT)
		{
			int lender; /* Note that borrower is i */

			/* Return credits to highest priority lender first */
			for (lender = AC_COUNT; (lender >= 0) && (credits[i] > 0); lender--) {
				if (wlfc->credits_borrowed[i][lender] > 0) {
					if (credits[i] >= wlfc->credits_borrowed[i][lender]) {
						credits[i] -=
							(uint8)wlfc->credits_borrowed[i][lender];
						wlfc->FIFO_credit[lender] +=
						    wlfc->credits_borrowed[i][lender];
						wlfc->credits_borrowed[i][lender] = 0;
					} else {
						wlfc->credits_borrowed[i][lender] -= credits[i];
						wlfc->FIFO_credit[lender] += credits[i];
						credits[i] = 0;
					}
				}
			}

			/* If we have more credits left over, these must belong to the AC */
			if (credits[i] > 0) {
				wlfc->FIFO_credit[i] += credits[i];
			}

			if (wlfc->FIFO_credit[i] > wlfc->Init_FIFO_credit[i]) {
				wlfc->FIFO_credit[i] = wlfc->Init_FIFO_credit[i];
			}
		}
	}

#if defined(DHD_WLFC_THREAD)
	_dhd_wlfc_thread_wakeup(dhd);
#endif /* defined(DHD_WLFC_THREAD) */

	return BCME_OK;
} /* _dhd_wlfc_fifocreditback_indicate */

#ifndef BCMDBUS
/** !BCMDBUS specific function */
static void
_dhd_wlfc_suppress_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
{
	athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	wlfc_mac_descriptor_t* entry;
	int prec;
	void *pkt = NULL, *head = NULL, *tail = NULL;
	struct pktq *txq = (struct pktq *)dhd_bus_txq(dhd->bus);
	uint8	results[WLFC_CTL_VALUE_LEN_TXSTATUS+WLFC_CTL_VALUE_LEN_SEQ];
	uint8 credits[WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK] = {0};
	uint32 htod = 0;
	uint16 htodseq = 0;
	bool bCreditUpdate = FALSE;

	dhd_os_sdlock_txq(dhd);
	for (prec = 0; prec < txq->num_prec; prec++) {
		while ((pkt = _dhd_wlfc_pktq_pdeq_with_fn(txq, prec, fn, arg))) {
			if (!head) {
				head = pkt;
			}
			if (tail) {
				PKTSETLINK(tail, pkt);
			}
			tail = pkt;
		}
	}
	dhd_os_sdunlock_txq(dhd);

	while ((pkt = head)) {
		head = PKTLINK(pkt);
		PKTSETLINK(pkt, NULL);

		entry = _dhd_wlfc_find_table_entry(wlfc, pkt);
		if (!entry) {
			PKTFREE(dhd->osh, pkt, TRUE);
			continue;
		}
		if (entry->onbus_pkts_count > 0) {
			entry->onbus_pkts_count--;
		}
		if (entry->suppressed &&
				(!entry->onbus_pkts_count) &&
				(!entry->suppr_transit_count)) {
			entry->suppressed = FALSE;
		}
		/* fake a suppression txstatus */
		htod = DHD_PKTTAG_H2DTAG(PKTTAG(pkt));
		WL_TXSTATUS_SET_FLAGS(htod, WLFC_CTL_PKTFLAG_WLSUPPRESS);
		WL_TXSTATUS_SET_GENERATION(htod, entry->generation);
		htod = htol32(htod);
		memcpy(results, &htod, WLFC_CTL_VALUE_LEN_TXSTATUS);
		if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) {
			htodseq = DHD_PKTTAG_H2DSEQ(PKTTAG(pkt));
			if (IS_WL_TO_REUSE_SEQ(htodseq)) {
				SET_WL_HAS_ASSIGNED_SEQ(htodseq);
				RESET_WL_TO_REUSE_SEQ(htodseq);
			}
			htodseq = htol16(htodseq);
			memcpy(results + WLFC_CTL_VALUE_LEN_TXSTATUS, &htodseq,
				WLFC_CTL_VALUE_LEN_SEQ);
		}
		if (WLFC_GET_AFQ(dhd->wlfc_mode)) {
			_dhd_wlfc_enque_afq(wlfc, pkt);
		}
		_dhd_wlfc_compressed_txstatus_update(dhd, results, 1, NULL);

		/* fake a fifo credit back */
		if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pkt))) {
			credits[DHD_PKTTAG_FIFO(PKTTAG(pkt))]++;
			bCreditUpdate = TRUE;
		}
	}

	if (bCreditUpdate) {
		_dhd_wlfc_fifocreditback_indicate(dhd, credits);
	}
} /* _dhd_wlfc_suppress_txq */

#endif /* !BCMDBUS */

static int
_dhd_wlfc_dbg_senum_check(dhd_pub_t *dhd, uint8 *value)
{
	uint32 timestamp;

	(void)dhd;

	bcopy(&value[2], &timestamp, sizeof(uint32));
	timestamp = ltoh32(timestamp);
	DHD_INFO(("RXPKT: SEQ: %d, timestamp %d\n", value[1], timestamp));
	return BCME_OK;
}

static int
_dhd_wlfc_rssi_indicate(dhd_pub_t *dhd, uint8* rssi)
{
	(void)dhd;
	(void)rssi;
	return BCME_OK;
}

static void
_dhd_wlfc_add_requested_entry(athost_wl_status_info_t* wlfc, wlfc_mac_descriptor_t* entry)
{
	int i;

	if (!wlfc || !entry) {
		return;
	}

	for (i = 0; i < wlfc->requested_entry_count; i++) {
		if (entry == wlfc->requested_entry[i]) {
			break;
		}
	}

	if (i == wlfc->requested_entry_count) {
		/* no match entry found */
		ASSERT(wlfc->requested_entry_count <= (WLFC_MAC_DESC_TABLE_SIZE-1));
		wlfc->requested_entry[wlfc->requested_entry_count++] = entry;
	}
}

/** called on eg receiving 'mac open' event from the dongle. */
static void
_dhd_wlfc_remove_requested_entry(athost_wl_status_info_t* wlfc, wlfc_mac_descriptor_t* entry)
{
	int i;

	if (!wlfc || !entry) {
		return;
	}

	for (i = 0; i < wlfc->requested_entry_count; i++) {
		if (entry == wlfc->requested_entry[i]) {
			break;
		}
	}

	if (i < wlfc->requested_entry_count) {
		/* found */
		ASSERT(wlfc->requested_entry_count > 0);
		wlfc->requested_entry_count--;
		if (i != wlfc->requested_entry_count) {
			wlfc->requested_entry[i] =
				wlfc->requested_entry[wlfc->requested_entry_count];
		}
		wlfc->requested_entry[wlfc->requested_entry_count] = NULL;
	}
}

/** called on eg receiving a WLFC_CTL_TYPE_MACDESC_ADD TLV from the dongle */
static int
_dhd_wlfc_mac_table_update(dhd_pub_t *dhd, uint8* value, uint8 type)
{
	int rc;
	athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	wlfc_mac_descriptor_t* table;
	uint8 existing_index;
	uint8 table_index;
	uint8 ifid;
	uint8* ea;

	WLFC_DBGMESG(("%s(), mac ["MACDBG"],%s,idx:%d,id:0x%02x\n",
		__FUNCTION__, MAC2STRDBG(&value[2]),
		((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"),
		WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0]));

	table = wlfc->destination_entries.nodes;
	table_index = WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]);
	ifid = value[1];
	ea = &value[2];

	_dhd_wlfc_remove_requested_entry(wlfc, &table[table_index]);
	if (type == WLFC_CTL_TYPE_MACDESC_ADD) {
		existing_index = _dhd_wlfc_find_mac_desc_id_from_mac(dhd, &value[2]);
		if ((existing_index != WLFC_MAC_DESC_ID_INVALID) &&
			(existing_index != table_index) && table[existing_index].occupied) {
			/*
			there is an existing different entry, free the old one
			and move it to new index if necessary.
			*/
			rc = _dhd_wlfc_mac_entry_update(wlfc, &table[existing_index],
				eWLFC_MAC_ENTRY_ACTION_DEL, table[existing_index].interface_id,
				table[existing_index].iftype, NULL, _dhd_wlfc_entrypkt_fn,
				&table[existing_index]);
		}

		if (!table[table_index].occupied) {
			/* this new MAC entry does not exist, create one */
			table[table_index].mac_handle = value[0];
			rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index],
				eWLFC_MAC_ENTRY_ACTION_ADD, ifid,
				wlfc->destination_entries.interfaces[ifid].iftype,
				ea, NULL, NULL);
		} else {
			/* the space should have been empty, but it's not */
			wlfc->stats.mac_update_failed++;
		}
	}

	if (type == WLFC_CTL_TYPE_MACDESC_DEL) {
		if (table[table_index].occupied) {
				rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index],
					eWLFC_MAC_ENTRY_ACTION_DEL, ifid,
					wlfc->destination_entries.interfaces[ifid].iftype,
					ea, _dhd_wlfc_entrypkt_fn, &table[table_index]);
		} else {
			/* the space should have been occupied, but it's not */
			wlfc->stats.mac_update_failed++;
		}
	}
	BCM_REFERENCE(rc);
	return BCME_OK;
} /* _dhd_wlfc_mac_table_update */

/** Called on a 'mac open' or 'mac close' event indicated by the dongle */
static int
_dhd_wlfc_psmode_update(dhd_pub_t *dhd, uint8* value, uint8 type)
{
	/* Handle PS on/off indication */
	athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	wlfc_mac_descriptor_t* table;
	wlfc_mac_descriptor_t* desc; /* a table maps from mac handle to mac descriptor */
	uint8 mac_handle = value[0];
	int i;

	table = wlfc->destination_entries.nodes;
	desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)];
	if (desc->occupied) {
#ifdef BULK_DEQUEUE
		for (i = 0; i < AC_COUNT + 1; i++) {
			desc->release_count[i] = 0;
		}
#endif /* BULK_DEQUEUE */
		if (type == WLFC_CTL_TYPE_MAC_OPEN) {
			desc->state = WLFC_STATE_OPEN;
			desc->ac_bitmap = 0xff;
			DHD_WLFC_CTRINC_MAC_OPEN(desc);
			desc->requested_credit = 0;
			desc->requested_packet = 0;
			_dhd_wlfc_remove_requested_entry(wlfc, desc);
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
			_dhd_wlfc_bprint(wlfc, "[op%u.%u]-",
				(uint8)(table - &wlfc->destination_entries.nodes[0]),
				OSL_SYSUPTIME());
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
		} else {
			desc->state = WLFC_STATE_CLOSE;
			DHD_WLFC_CTRINC_MAC_CLOSE(desc);
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
			_dhd_wlfc_bprint(wlfc, "[cl%u.%u]-",
				(uint8)(table - &wlfc->destination_entries.nodes[0]),
				OSL_SYSUPTIME());
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
			/* Indicate to firmware if there is any traffic pending. */
			for (i = 0; i < AC_COUNT; i++) {
				_dhd_wlfc_traffic_pending_check(wlfc, desc, i);
			}
		}
	} else {
		wlfc->stats.psmode_update_failed++;
	}

	return BCME_OK;
} /* _dhd_wlfc_psmode_update */

/** called upon receiving 'interface open' or 'interface close' event from the dongle */
static int
_dhd_wlfc_interface_update(dhd_pub_t *dhd, uint8* value, uint8 type)
{
	/* Handle PS on/off indication */
	athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	wlfc_mac_descriptor_t* table;
	uint8 if_id = value[0];
	uint8 i;

	BCM_REFERENCE(i);

	if (if_id < WLFC_MAX_IFNUM) {
		table = wlfc->destination_entries.interfaces;
		if (table[if_id].occupied) {
#ifdef BULK_DEQUEUE
			for (i = 0; i < AC_COUNT + 1; i++) {
				table->release_count[i] = 0;
			}
#endif /* BULK_DEQUEUE */
			if (type == WLFC_CTL_TYPE_INTERFACE_OPEN) {
				table[if_id].state = WLFC_STATE_OPEN;
				/* WLFC_DBGMESG(("INTERFACE[%d] OPEN\n", if_id)); */
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
				_dhd_wlfc_bprint(wlfc, "[op%u.%u]-",
					(uint8)(table - &wlfc->destination_entries.nodes[0]),
					OSL_SYSUPTIME());
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
			} else {
				table[if_id].state = WLFC_STATE_CLOSE;
				/* WLFC_DBGMESG(("INTERFACE[%d] CLOSE\n", if_id)); */
#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
				_dhd_wlfc_bprint(wlfc, "[cl%u.%u]-",
					(uint8)(table - &wlfc->destination_entries.nodes[0]),
					OSL_SYSUPTIME());
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */
			}
			return BCME_OK;
		}
	}
	wlfc->stats.interface_update_failed++;

	/* XXX: what is an appropriate error? */
	return BCME_OK;
}

/** Called on receiving a WLFC_CTL_TYPE_MAC_REQUEST_CREDIT TLV from the dongle */
static int
_dhd_wlfc_credit_request(dhd_pub_t *dhd, uint8* value)
{
	athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	wlfc_mac_descriptor_t* table;
	wlfc_mac_descriptor_t* desc;
	uint8 mac_handle;
	uint8 credit;

	table = wlfc->destination_entries.nodes;
	mac_handle = value[1];
	credit = value[0];

	desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)];
	if (desc->occupied) {
		desc->requested_credit = credit;

		/* XXX: toggle AC prec bitmap based on received bmp, exclude ac/bc pkt */
		desc->ac_bitmap = value[2] & (~(1<<AC_COUNT));
		_dhd_wlfc_add_requested_entry(wlfc, desc);
#if defined(DHD_WLFC_THREAD)
		if (credit) {
			_dhd_wlfc_thread_wakeup(dhd);
		}
#endif /* DHD_WLFC_THREAD */
	} else {
		wlfc->stats.credit_request_failed++;
	}

	return BCME_OK;
}

/** Called on receiving a WLFC_CTL_TYPE_MAC_REQUEST_PACKET TLV from the dongle */
static int
_dhd_wlfc_packet_request(dhd_pub_t *dhd, uint8* value)
{
	athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	wlfc_mac_descriptor_t* table;
	wlfc_mac_descriptor_t* desc;
	uint8 mac_handle;
	uint8 packet_count;

	table = wlfc->destination_entries.nodes;
	mac_handle = value[1];
	packet_count = value[0];

	desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)];
	if (desc->occupied) {
		desc->requested_packet = packet_count;

		/* XXX: toggle AC prec bitmap based on received bmp, exclude ac/bc pkt */
		desc->ac_bitmap = value[2] & (~(1<<AC_COUNT));
		_dhd_wlfc_add_requested_entry(wlfc, desc);
#if defined(DHD_WLFC_THREAD)
		if (packet_count) {
			_dhd_wlfc_thread_wakeup(dhd);
		}
#endif /* DHD_WLFC_THREAD */
	} else {
		wlfc->stats.packet_request_failed++;
	}

	return BCME_OK;
}

/** Called when host receives a WLFC_CTL_TYPE_HOST_REORDER_RXPKTS TLV from the dongle */
static void
_dhd_wlfc_reorderinfo_indicate(uint8 *val, uint8 len, uchar *info_buf, uint *info_len)
{
	if (info_len) {
		/* Check copy length to avoid buffer overrun. In case of length exceeding
		*  WLHOST_REORDERDATA_TOTLEN, return failure instead sending incomplete result
		*  of length WLHOST_REORDERDATA_TOTLEN
		*/
		if ((info_buf) && (len <= WLHOST_REORDERDATA_TOTLEN)) {
			bcopy(val, info_buf, len);
			*info_len = len;
		} else {
			*info_len = 0;
		}
	}
}

/*
 * public functions
 */

bool dhd_wlfc_is_supported(dhd_pub_t *dhd)
{
	bool rc = TRUE;

	if (dhd == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return FALSE;
	}

	dhd_os_wlfc_block(dhd);

	if (!dhd->wlfc_state || (dhd->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		rc =  FALSE;
	}

	dhd_os_wlfc_unblock(dhd);

	return rc;
}

#ifdef BULK_DEQUEUE
#ifndef WLFC_MAX_RELEASE_CNT
#ifdef CUSTOM_AMPDU_MPDU
#define WLFC_MAX_RELEASE_CNT	CUSTOM_AMPDU_MPDU
#else
#define WLFC_MAX_RELEASE_CNT	16
#endif /* CUSTOM_AMPDU_MPDU */
#endif /* WLFC_MAX_RELEASE_CNT */
#endif /* BULK_DEQUEUE */

int dhd_wlfc_enable(dhd_pub_t *dhd)
{
	int i, rc = BCME_OK;
	athost_wl_status_info_t* wlfc;

	if (dhd == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	if (!dhd->wlfc_enabled || dhd->wlfc_state) {
		rc = BCME_OK;
		goto exit;
	}

	/* allocate space to track txstatus propagated from firmware */
	dhd->wlfc_state = DHD_OS_PREALLOC(dhd, DHD_PREALLOC_DHD_WLFC_INFO,
		sizeof(athost_wl_status_info_t));
	if (dhd->wlfc_state == NULL) {
		rc = BCME_NOMEM;
		goto exit;
	}

	/* initialize state space */
	wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	memset(wlfc, 0, sizeof(athost_wl_status_info_t));

	/* remember osh & dhdp */
	wlfc->osh = dhd->osh;
	wlfc->dhdp = dhd;
#ifdef BULK_DEQUEUE
	wlfc->max_release_count = WLFC_MAX_RELEASE_CNT;
#endif /* BULK_DEQUEUE */
	if (!WLFC_GET_AFQ(dhd->wlfc_mode)) {
		wlfc->hanger = _dhd_wlfc_hanger_create(dhd, WLFC_HANGER_MAXITEMS);
		if (wlfc->hanger == NULL) {
			DHD_OS_PREFREE(dhd, dhd->wlfc_state,
				sizeof(athost_wl_status_info_t));
			dhd->wlfc_state = NULL;
			rc = BCME_NOMEM;
			goto exit;
		}
	}

	dhd->proptxstatus_mode = WLFC_FCMODE_EXPLICIT_CREDIT;
	/* default to check rx pkt */
	dhd->wlfc_rxpkt_chk = TRUE;
#if defined (LINUX) || defined(linux)
	if (dhd->op_mode & DHD_FLAG_IBSS_MODE) {
		dhd->wlfc_rxpkt_chk = FALSE;
	}
#endif /* defined (LINUX) || defined(linux) */

	/* initialize all interfaces to accept traffic */
	for (i = 0; i < WLFC_MAX_IFNUM; i++) {
		wlfc->hostif_flow_state[i] = OFF;
	}

	_dhd_wlfc_mac_entry_update(wlfc, &wlfc->destination_entries.other,
		eWLFC_MAC_ENTRY_ACTION_ADD, 0xff, 0, NULL, NULL, NULL);

	wlfc->allow_credit_borrow = 0;
	wlfc->single_ac = 0;
	wlfc->single_ac_timestamp = 0;

#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
	wlfc->log_buf = MALLOC(dhd->osh, WLFC_LOG_BUF_SIZE);
	wlfc->log_buf[WLFC_LOG_BUF_SIZE - 1] = 0;
	wlfc->log_buf_offset = 0;
	wlfc->log_buf_full = FALSE;
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */

exit:
	DHD_ERROR(("%s: ret=%d\n", __FUNCTION__, rc));
	dhd_os_wlfc_unblock(dhd);

	return rc;
} /* dhd_wlfc_enable */

#ifdef SUPPORT_P2P_GO_PS

/**
 * Called when the host platform enters a lower power mode, eg right before a system hibernate.
 * SUPPORT_P2P_GO_PS specific function.
 */
int
dhd_wlfc_suspend(dhd_pub_t *dhd)
{
	uint32 tlv = 0;

	DHD_TRACE(("%s: masking wlfc events\n", __FUNCTION__));
	if (!dhd->wlfc_enabled)
		return -1;

	if (!dhd_wl_ioctl_get_intiovar(dhd, "tlv", &tlv, WLC_GET_VAR, FALSE, 0))
		return -1;
	if ((tlv & (WLFC_FLAGS_RSSI_SIGNALS | WLFC_FLAGS_XONXOFF_SIGNALS)) == 0)
		return 0;
	tlv &= ~(WLFC_FLAGS_RSSI_SIGNALS | WLFC_FLAGS_XONXOFF_SIGNALS);
	if (!dhd_wl_ioctl_set_intiovar(dhd, "tlv", tlv, WLC_SET_VAR, TRUE, 0))
		return -1;

	return 0;
}

/**
 * Called when the host platform resumes from a power management operation, eg resume after a
 * system hibernate. SUPPORT_P2P_GO_PS specific function.
 */
int
dhd_wlfc_resume(dhd_pub_t *dhd)
{
	uint32 tlv = 0;

	DHD_TRACE(("%s: unmasking wlfc events\n", __FUNCTION__));
	if (!dhd->wlfc_enabled)
		return -1;

	if (!dhd_wl_ioctl_get_intiovar(dhd, "tlv", &tlv, WLC_GET_VAR, FALSE, 0))
		return -1;
	if ((tlv & (WLFC_FLAGS_RSSI_SIGNALS | WLFC_FLAGS_XONXOFF_SIGNALS)) ==
		(WLFC_FLAGS_RSSI_SIGNALS | WLFC_FLAGS_XONXOFF_SIGNALS))
		return 0;
	tlv |= (WLFC_FLAGS_RSSI_SIGNALS | WLFC_FLAGS_XONXOFF_SIGNALS);
	if (!dhd_wl_ioctl_set_intiovar(dhd, "tlv", tlv, WLC_SET_VAR, TRUE, 0))
		return -1;

	return 0;
}

#endif /* SUPPORT_P2P_GO_PS */

/** A flow control header was received from firmware, containing one or more TLVs */
int
dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len, uchar *reorder_info_buf,
	uint *reorder_info_len)
{
	uint8 type, len;
	uint8* value;
	uint8* tmpbuf;
	uint16 remainder = (uint16)tlv_hdr_len;
	uint16 processed = 0;
	athost_wl_status_info_t* wlfc = NULL;
	void* entry;

	if ((dhd == NULL) || (pktbuf == NULL)) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	if (dhd->proptxstatus_mode != WLFC_ONLY_AMPDU_HOSTREORDER) {
		if (!dhd->wlfc_state || (dhd->proptxstatus_mode == WLFC_FCMODE_NONE)) {
			dhd_os_wlfc_unblock(dhd);
			return WLFC_UNSUPPORTED;
		}
		wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	}

	tmpbuf = (uint8*)PKTDATA(dhd->osh, pktbuf);

	if (remainder) {
		while ((processed < (WLFC_MAX_PENDING_DATALEN * 2)) && (remainder > 0)) {
			type = tmpbuf[processed];
			if (type == WLFC_CTL_TYPE_FILLER) {
				remainder -= 1;
				processed += 1;
				continue;
			}

			len  = tmpbuf[processed + 1];
			value = &tmpbuf[processed + 2];

			if (remainder < (2 + len))
				break;

			remainder -= 2 + len;
			processed += 2 + len;
			entry = NULL;

			DHD_INFO(("%s():%d type %d remainder %d processed %d\n",
				__FUNCTION__, __LINE__, type, remainder, processed));

			if (type == WLFC_CTL_TYPE_HOST_REORDER_RXPKTS)
				_dhd_wlfc_reorderinfo_indicate(value, len, reorder_info_buf,
					reorder_info_len);

			if (wlfc == NULL) {
				ASSERT(dhd->proptxstatus_mode == WLFC_ONLY_AMPDU_HOSTREORDER);

				if (type != WLFC_CTL_TYPE_HOST_REORDER_RXPKTS &&
					type != WLFC_CTL_TYPE_TRANS_ID)
					DHD_INFO(("%s():%d dhd->wlfc_state is NULL yet!"
					" type %d remainder %d processed %d\n",
					__FUNCTION__, __LINE__, type, remainder, processed));
				continue;
			}

			if (type == WLFC_CTL_TYPE_TXSTATUS) {
				_dhd_wlfc_compressed_txstatus_update(dhd, value, 1, &entry);
			} else if (type == WLFC_CTL_TYPE_COMP_TXSTATUS) {
				uint8 compcnt_offset = WLFC_CTL_VALUE_LEN_TXSTATUS;

				if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) {
					compcnt_offset += WLFC_CTL_VALUE_LEN_SEQ;
				}
				_dhd_wlfc_compressed_txstatus_update(dhd, value,
					value[compcnt_offset], &entry);
			} else if (type == WLFC_CTL_TYPE_FIFO_CREDITBACK) {
				_dhd_wlfc_fifocreditback_indicate(dhd, value);
			} else if (type == WLFC_CTL_TYPE_RSSI) {
				_dhd_wlfc_rssi_indicate(dhd, value);
			} else if (type == WLFC_CTL_TYPE_MAC_REQUEST_CREDIT) {
				_dhd_wlfc_credit_request(dhd, value);
			} else if (type == WLFC_CTL_TYPE_MAC_REQUEST_PACKET) {
				_dhd_wlfc_packet_request(dhd, value);
			} else if ((type == WLFC_CTL_TYPE_MAC_OPEN) ||
				(type == WLFC_CTL_TYPE_MAC_CLOSE)) {
				_dhd_wlfc_psmode_update(dhd, value, type);
			} else if ((type == WLFC_CTL_TYPE_MACDESC_ADD) ||
				(type == WLFC_CTL_TYPE_MACDESC_DEL)) {
				_dhd_wlfc_mac_table_update(dhd, value, type);
			} else if (type == WLFC_CTL_TYPE_TRANS_ID) {
				_dhd_wlfc_dbg_senum_check(dhd, value);
			} else if ((type == WLFC_CTL_TYPE_INTERFACE_OPEN) ||
				(type == WLFC_CTL_TYPE_INTERFACE_CLOSE)) {
				_dhd_wlfc_interface_update(dhd, value, type);
			}

#ifndef BCMDBUS
			if (entry && WLFC_GET_REORDERSUPP(dhd->wlfc_mode)) {
				/* suppress all packets for this mac entry from bus->txq */
				_dhd_wlfc_suppress_txq(dhd, _dhd_wlfc_entrypkt_fn, entry);
			}
#endif /* !BCMDBUS */
		} /* while */

		if (remainder != 0 && wlfc) {
			/* trouble..., something is not right */
			wlfc->stats.tlv_parse_failed++;
		}
	} /* if */

	if (wlfc)
		wlfc->stats.dhd_hdrpulls++;

	dhd_os_wlfc_unblock(dhd);
	return BCME_OK;
}

KERNEL_THREAD_RETURN_TYPE
dhd_wlfc_transfer_packets(void *data)
{
	dhd_pub_t *dhdp = (dhd_pub_t *)data;
	int ac, single_ac = 0, rc = BCME_OK;
	dhd_wlfc_commit_info_t  commit_info;
	athost_wl_status_info_t* ctx;
	int bus_retry_count = 0;
	int pkt_send = 0;
	int pkt_send_per_ac = 0;

	uint8 tx_map = 0; /* packets (send + in queue), Bitmask for 4 ACs + BC/MC */
	uint8 rx_map = 0; /* received packets, Bitmask for 4 ACs + BC/MC */
	uint8 packets_map = 0; /* packets in queue, Bitmask for 4 ACs + BC/MC */
	bool no_credit = FALSE;

	int lender;
	int pkt_bound = WLFC_PACKET_BOUND;
	int highest_lender_ac;

	BCM_REFERENCE(highest_lender_ac);

#if defined(DHD_WLFC_THREAD)
	/* wait till someone wakeup me up, will change it at running time */
#if defined(LINUX)
	int wait_msec = msecs_to_jiffies(0xFFFFFFFF);
#endif /* LINUX */
#endif /* defined(DHD_WLFC_THREAD) */

#if defined(DHD_WLFC_THREAD)
	while (1) {
		bus_retry_count = 0;
		pkt_send = 0;
		tx_map = 0;
		rx_map = 0;
		packets_map = 0;
#if defined(LINUX)
		wait_msec = wait_event_interruptible_timeout(dhdp->wlfc_wqhead,
			dhdp->wlfc_thread_go, wait_msec);
		if (kthread_should_stop()) {
			break;
		}
		dhdp->wlfc_thread_go = FALSE;
#endif /* LINUX */

		dhd_os_wlfc_block(dhdp);
#endif /* defined(DHD_WLFC_THREAD) */
		ctx = (athost_wl_status_info_t*)dhdp->wlfc_state;
#if defined(DHD_WLFC_THREAD)
		if (!ctx)
			goto exit;
#endif /* defined(DHD_WLFC_THREAD) */

	memset(&commit_info, 0, sizeof(commit_info));

	/*
	Commit packets for regular AC traffic. Higher priority first.
	First, use up FIFO credits available to each AC. Based on distribution
	and credits left, borrow from other ACs as applicable

	-NOTE:
	If the bus between the host and firmware is overwhelmed by the
	traffic from host, it is possible that higher priority traffic
	starves the lower priority queue. If that occurs often, we may
	have to employ weighted round-robin or ucode scheme to avoid
	low priority packet starvation.
	*/

#ifdef BULK_DEQUEUE
	pkt_bound = ctx->max_release_count;
#endif

	for (ac = AC_COUNT; ac >= 0; ac--) {
		if (dhdp->wlfc_rxpkt_chk) {
			/* check rx packet */
			uint32 curr_t = OSL_SYSUPTIME(), delta;

			delta = curr_t - ctx->rx_timestamp[ac];
			if (delta < WLFC_RX_DETECTION_THRESHOLD_MS) {
				rx_map |= (1 << ac);
			}
		}

		if (ctx->pkt_cnt_per_ac[ac] == 0) {
			continue;
		}

		tx_map |= (1 << ac);
		single_ac = ac + 1;
		pkt_send_per_ac = 0;
		while ((FALSE == dhdp->proptxstatus_txoff) &&
				(pkt_send_per_ac < pkt_bound)) {
			/* packets from delayQ with less priority are fresh and
			 * they'd need header and have no MAC entry
			 */
			no_credit = (ctx->FIFO_credit[ac] < 1);
			if (dhdp->proptxstatus_credit_ignore ||
				((ac == AC_COUNT) && !ctx->bcmc_credit_supported)) {
				no_credit = FALSE;
			}

			lender = -1;
#ifdef LIMIT_BORROW
			if (no_credit && (ac < AC_COUNT) && (tx_map >= rx_map) &&
				dhdp->wlfc_borrow_allowed) {
				/* try borrow from lower priority */
#ifdef BULK_DEQUEUE
				/* Enable credit borrow from higher AC
				 * to make packet chain longer
				 */
				highest_lender_ac = AC_COUNT;
#else
				highest_lender_ac = ac - 1;
#endif /* BULK_DEQUEUE */
				lender = _dhd_wlfc_borrow_credit(ctx, highest_lender_ac, ac, FALSE);
				if (lender != -1) {
					no_credit = FALSE;
				}
			}
#endif /* LIMIT_BORROW */
			commit_info.needs_hdr = 1;
			commit_info.mac_entry = NULL;
			commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
				&(commit_info.ac_fifo_credit_spent),
				&(commit_info.needs_hdr),
				&(commit_info.mac_entry),
				no_credit);
			commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED :
				eWLFC_PKTTYPE_SUPPRESSED;

			if (commit_info.p == NULL) {
#ifdef LIMIT_BORROW
				if (lender != -1 && dhdp->wlfc_borrow_allowed) {
					_dhd_wlfc_return_credit(ctx, lender, ac);
				}
#endif
				break;
			}

			if (!dhdp->proptxstatus_credit_ignore && (lender == -1)) {
				ASSERT(ctx->FIFO_credit[ac] >= commit_info.ac_fifo_credit_spent);
			}
			/* here we can ensure have credit or no credit needed */
			rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
				ctx->fcommit, ctx->commit_ctx);

			/* Bus commits may fail (e.g. flow control); abort after retries */
			if (rc == BCME_OK) {
				pkt_send++;
				pkt_send_per_ac++;
				if (commit_info.ac_fifo_credit_spent && (lender == -1)) {
					ctx->FIFO_credit[ac]--;
				}
#ifdef LIMIT_BORROW
				else if (!commit_info.ac_fifo_credit_spent && (lender != -1) &&
					dhdp->wlfc_borrow_allowed) {
					_dhd_wlfc_return_credit(ctx, lender, ac);
				}
#endif
			} else {
#ifdef LIMIT_BORROW
				if (lender != -1 && dhdp->wlfc_borrow_allowed) {
					_dhd_wlfc_return_credit(ctx, lender, ac);
				}
#endif
				bus_retry_count++;
				if (bus_retry_count >= BUS_RETRIES) {
					DHD_ERROR(("%s: bus error %d\n", __FUNCTION__, rc));
					goto exit;
				}
			}
		}

		if (ctx->pkt_cnt_per_ac[ac]) {
			packets_map |= (1 << ac);
		}
	}

	if ((tx_map == 0) || dhdp->proptxstatus_credit_ignore) {
		/* nothing send out or remain in queue */
		rc = BCME_OK;
		goto exit;
	}

	if (((tx_map & (tx_map - 1)) == 0) && (tx_map >= rx_map)) {
		/* only one tx ac exist and no higher rx ac */
		if ((single_ac == ctx->single_ac) && ctx->allow_credit_borrow) {
			ac = single_ac - 1;
		} else {
			uint32 delta;
			uint32 curr_t = OSL_SYSUPTIME();

			if (single_ac != ctx->single_ac) {
				/* new single ac traffic (first single ac or different single ac) */
				ctx->allow_credit_borrow = 0;
				ctx->single_ac_timestamp = curr_t;
				ctx->single_ac = (uint8)single_ac;
				rc = BCME_OK;
				goto exit;
			}
			/* same ac traffic, check if it lasts enough time */
			delta = curr_t - ctx->single_ac_timestamp;

			if (delta >= WLFC_BORROW_DEFER_PERIOD_MS) {
				/* wait enough time, can borrow now */
				ctx->allow_credit_borrow = 1;
				ac = single_ac - 1;
			} else {
				rc = BCME_OK;
				goto exit;
			}
		}
	} else {
		/* If we have multiple AC traffic, turn off borrowing, mark time and bail out */
		ctx->allow_credit_borrow = 0;
		ctx->single_ac_timestamp = 0;
		ctx->single_ac = 0;
		rc = BCME_OK;
		goto exit;
	}

	if (packets_map == 0) {
		/* nothing to send, skip borrow */
		rc = BCME_OK;
		goto exit;
	}

	/* At this point, borrow all credits only for ac */
	while (FALSE == dhdp->proptxstatus_txoff) {
#ifdef LIMIT_BORROW
		if (dhdp->wlfc_borrow_allowed) {
			if ((lender = _dhd_wlfc_borrow_credit(ctx, AC_COUNT, ac, TRUE)) == -1) {
				break;
			}
		}
		else
			break;
#endif
		commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
			&(commit_info.ac_fifo_credit_spent),
			&(commit_info.needs_hdr),
			&(commit_info.mac_entry),
			FALSE);
		if (commit_info.p == NULL) {
			/* before borrow only one ac exists and now this only ac is empty */
#ifdef LIMIT_BORROW
			_dhd_wlfc_return_credit(ctx, lender, ac);
#endif
			break;
		}

		commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED :
			eWLFC_PKTTYPE_SUPPRESSED;

		rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
		     ctx->fcommit, ctx->commit_ctx);

		/* Bus commits may fail (e.g. flow control); abort after retries */
		if (rc == BCME_OK) {
			pkt_send++;
			if (commit_info.ac_fifo_credit_spent) {
#ifndef LIMIT_BORROW
				ctx->FIFO_credit[ac]--;
#endif
			} else {
#ifdef LIMIT_BORROW
				_dhd_wlfc_return_credit(ctx, lender, ac);
#endif
			}
		} else {
#ifdef LIMIT_BORROW
			_dhd_wlfc_return_credit(ctx, lender, ac);
#endif
			bus_retry_count++;
			if (bus_retry_count >= BUS_RETRIES) {
				DHD_ERROR(("%s: bus error %d\n", __FUNCTION__, rc));
				goto exit;
			}
		}
	}

	BCM_REFERENCE(pkt_send);

exit:
#if defined(DHD_WLFC_THREAD)
		dhd_os_wlfc_unblock(dhdp);
#if defined(LINUX)
		if (ctx && ctx->pkt_cnt_in_psq && pkt_send) {
			wait_msec = msecs_to_jiffies(WLFC_THREAD_QUICK_RETRY_WAIT_MS);
		} else {
			wait_msec = msecs_to_jiffies(WLFC_THREAD_RETRY_WAIT_MS);
		}
#endif /* LINUX */
	}
	return 0;
#else
	return rc;
#endif /* defined(DHD_WLFC_THREAD) */
}

/**
 * Enqueues a transmit packet in the next layer towards the dongle, eg the DBUS layer. Called by
 * eg dhd_sendpkt().
 *     @param[in] dhdp                  Pointer to public DHD structure
 *     @param[in] fcommit               Pointer to transmit function of next layer
 *     @param[in] commit_ctx            Opaque context used when calling next layer
 *     @param[in] pktbuf                Packet to send
 *     @param[in] need_toggle_host_if   If TRUE, resets flag ctx->toggle_host_if
 */
int
dhd_wlfc_commit_packets(dhd_pub_t *dhdp, f_commitpkt_t fcommit,
	struct dhd_bus *commit_ctx, void *pktbuf, bool need_toggle_host_if)
{
	int rc = BCME_OK;
	athost_wl_status_info_t* ctx;

#if defined(DHD_WLFC_THREAD)
	if (!pktbuf)
		return BCME_OK;
#endif /* defined(DHD_WLFC_THREAD) */

	if ((dhdp == NULL) || (fcommit == NULL)) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhdp);

	if (!dhdp->wlfc_state || (dhdp->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		if (pktbuf) {
			DHD_PKTTAG_WLFCPKT_SET(PKTTAG(pktbuf), 0);
		}
		rc =  WLFC_UNSUPPORTED;
		goto exit;
	}

	ctx = (athost_wl_status_info_t*)dhdp->wlfc_state;

#ifdef BCMDBUS
	if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN)) {
		if (pktbuf) {
			PKTFREE(ctx->osh, pktbuf, TRUE);
			rc = BCME_OK;
		}
		goto exit;
	}
#endif

	if (dhdp->proptxstatus_module_ignore) {
		if (pktbuf) {
			uint32 htod = 0;
			WL_TXSTATUS_SET_FLAGS(htod, WLFC_PKTFLAG_PKTFROMHOST);
			_dhd_wlfc_pushheader(ctx, &pktbuf, FALSE, 0, 0, htod, 0, FALSE);
			if (fcommit(commit_ctx, pktbuf)) {
				/* free it if failed, otherwise do it in tx complete cb */
				PKTFREE(ctx->osh, pktbuf, TRUE);
			}
			rc = BCME_OK;
		}
		goto exit;
	}

	if (pktbuf) {
		int ac = DHD_PKTTAG_FIFO(PKTTAG(pktbuf));
		ASSERT(ac <= AC_COUNT);
		DHD_PKTTAG_WLFCPKT_SET(PKTTAG(pktbuf), 1);
		/* en-queue the packets to respective queue. */
		rc = _dhd_wlfc_enque_delayq(ctx, pktbuf, ac);
		if (rc) {
			_dhd_wlfc_prec_drop(ctx->dhdp, (ac << 1), pktbuf, FALSE);
		} else {
			ctx->stats.pktin++;
			ctx->pkt_cnt_in_drv[DHD_PKTTAG_IF(PKTTAG(pktbuf))][ac]++;
		}
	}

	if (!ctx->fcommit) {
		ctx->fcommit = fcommit;
	} else {
		ASSERT(ctx->fcommit == fcommit);
	}
	if (!ctx->commit_ctx) {
		ctx->commit_ctx = commit_ctx;
	} else {
		ASSERT(ctx->commit_ctx == commit_ctx);
	}

#if defined(DHD_WLFC_THREAD)
	_dhd_wlfc_thread_wakeup(dhdp);
#else
	dhd_wlfc_transfer_packets(dhdp);
#endif /* defined(DHD_WLFC_THREAD) */

exit:
	dhd_os_wlfc_unblock(dhdp);
	return rc;
} /* dhd_wlfc_commit_packets */

/**
 * Called when the (lower) DBUS layer indicates completion (succesfull or not) of a transmit packet
 */
int
dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success)
{
	athost_wl_status_info_t* wlfc;
	wlfc_mac_descriptor_t *entry;
	void* pout = NULL;
	int rtn = BCME_OK;
	if ((dhd == NULL) || (txp == NULL)) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	bcm_pkt_validate_chk(txp, "_dhd_wlfc_compressed_txstatus_update");

	dhd_os_wlfc_block(dhd);

	if (!dhd->wlfc_state || (dhd->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		rtn = WLFC_UNSUPPORTED;
		goto EXIT;
	}

	wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
	if (DHD_PKTTAG_SIGNALONLY(PKTTAG(txp))) {
#ifdef PROP_TXSTATUS_DEBUG
		wlfc->stats.signal_only_pkts_freed++;
#endif
		/* is this a signal-only packet? */
		_dhd_wlfc_pullheader(wlfc, txp);
		PKTFREE(wlfc->osh, txp, TRUE);
		goto EXIT;
	}

	entry = _dhd_wlfc_find_table_entry(wlfc, txp);
	ASSERT(entry);

	if (!success || dhd->proptxstatus_txstatus_ignore) {
		WLFC_DBGMESG(("At: %s():%d, bus_complete() failure for %p, htod_tag:0x%08x\n",
			__FUNCTION__, __LINE__, txp, DHD_PKTTAG_H2DTAG(PKTTAG(txp))));
		if (!WLFC_GET_AFQ(dhd->wlfc_mode)) {
			_dhd_wlfc_hanger_poppkt(wlfc->hanger, WL_TXSTATUS_GET_HSLOT(
				DHD_PKTTAG_H2DTAG(PKTTAG(txp))), &pout, TRUE);
			ASSERT(txp == pout);
		}

		/* indicate failure and free the packet */
		dhd_txcomplete(dhd, txp, success);

		/* return the credit, if necessary */
		_dhd_wlfc_return_implied_credit(wlfc, txp);

		if (entry->transit_count)
			entry->transit_count--;
		if (entry->suppr_transit_count)
			entry->suppr_transit_count--;
		wlfc->pkt_cnt_in_drv[DHD_PKTTAG_IF(PKTTAG(txp))][DHD_PKTTAG_FIFO(PKTTAG(txp))]--;
		wlfc->stats.pktout++;
		PKTFREE(wlfc->osh, txp, TRUE);
	} else {
		/* bus confirmed pkt went to firmware side */
		if (WLFC_GET_AFQ(dhd->wlfc_mode)) {
			_dhd_wlfc_enque_afq(wlfc, txp);
		} else {
			int hslot = WL_TXSTATUS_GET_HSLOT(DHD_PKTTAG_H2DTAG(PKTTAG(txp)));
			_dhd_wlfc_hanger_free_pkt(wlfc, hslot,
				WLFC_HANGER_PKT_STATE_BUSRETURNED, -1);
		}
	}

	ASSERT(entry->onbus_pkts_count > 0);
	if (entry->onbus_pkts_count > 0)
		entry->onbus_pkts_count--;
	if (entry->suppressed &&
		(!entry->onbus_pkts_count) &&
		(!entry->suppr_transit_count))
		entry->suppressed = FALSE;
EXIT:
	dhd_os_wlfc_unblock(dhd);
	return rtn;
} /* dhd_wlfc_txcomplete */

int
dhd_wlfc_init(dhd_pub_t *dhd)
{
	/* enable all signals & indicate host proptxstatus logic is active */
	uint32 tlv, mode, fw_caps;
	int ret = 0;

	if (dhd == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);
	if (dhd->wlfc_enabled) {
		DHD_INFO(("%s():%d, Already enabled!\n", __FUNCTION__, __LINE__));
		dhd_os_wlfc_unblock(dhd);
		return BCME_OK;
	}
	dhd->wlfc_enabled = TRUE;
	dhd_os_wlfc_unblock(dhd);

	tlv = WLFC_FLAGS_RSSI_SIGNALS |
		WLFC_FLAGS_XONXOFF_SIGNALS |
		WLFC_FLAGS_CREDIT_STATUS_SIGNALS |
		WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE |
		WLFC_FLAGS_HOST_RXRERODER_ACTIVE;

	/* XXX dhd->wlfc_state = NULL; */
	/* XXX ANDREY:may erase pointer to already created wlfc_state, PR#97824  */

	/*
	try to enable/disable signaling by sending "tlv" iovar. if that fails,
	fallback to no flow control? Print a message for now.
	*/

	/* enable proptxtstatus signaling by default */
	if (!dhd_wl_ioctl_set_intiovar(dhd, "tlv", tlv, WLC_SET_VAR, TRUE, 0)) {
		/*
		Leaving the message for now, it should be removed after a while; once
		the tlv situation is stable.
		*/
		DHD_INFO(("dhd_wlfc_init(): successfully %s bdcv2 tlv signaling, %d\n",
			dhd->wlfc_enabled?"enabled":"disabled", tlv));
	}

	mode = 0;

	/* query caps */
	ret = dhd_wl_ioctl_get_intiovar(dhd, "wlfc_mode", &fw_caps, WLC_GET_VAR, FALSE, 0);

	if (!ret) {
		DHD_INFO(("%s: query wlfc_mode succeed, fw_caps=0x%x\n", __FUNCTION__, fw_caps));

		if (WLFC_IS_OLD_DEF(fw_caps)) {
#ifdef BCMDBUS
			mode = WLFC_MODE_HANGER;
#else
			/* enable proptxtstatus v2 by default */
			mode = WLFC_MODE_AFQ;
#endif /* BCMDBUS */
		} else {
			WLFC_SET_AFQ(mode, WLFC_GET_AFQ(fw_caps));
#ifdef BCMDBUS
			WLFC_SET_AFQ(mode, 0);
#endif /* BCMDBUS */
			WLFC_SET_REUSESEQ(mode, WLFC_GET_REUSESEQ(fw_caps));
			WLFC_SET_REORDERSUPP(mode, WLFC_GET_REORDERSUPP(fw_caps));
		}
		ret = dhd_wl_ioctl_set_intiovar(dhd, "wlfc_mode", mode, WLC_SET_VAR, TRUE, 0);
	}

	dhd_os_wlfc_block(dhd);

	dhd->wlfc_mode = 0;
	if (ret >= 0) {
		if (WLFC_IS_OLD_DEF(mode)) {
			WLFC_SET_AFQ(dhd->wlfc_mode, (mode == WLFC_MODE_AFQ));
		} else {
			dhd->wlfc_mode = mode;
		}
	}

	DHD_INFO(("dhd_wlfc_init(): wlfc_mode=0x%x, ret=%d\n", dhd->wlfc_mode, ret));
#ifdef LIMIT_BORROW
	dhd->wlfc_borrow_allowed = TRUE;
#endif
	dhd_os_wlfc_unblock(dhd);

	if (dhd->plat_init)
		dhd->plat_init((void *)dhd);

	return BCME_OK;
} /* dhd_wlfc_init */

/** AMPDU host reorder specific function */
int
dhd_wlfc_hostreorder_init(dhd_pub_t *dhd)
{
	/* enable only ampdu hostreorder here */
	uint32 tlv;

	if (dhd == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

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

	tlv = WLFC_FLAGS_HOST_RXRERODER_ACTIVE;

	/* enable proptxtstatus signaling by default */
	if (dhd_wl_ioctl_set_intiovar(dhd, "tlv", tlv, WLC_SET_VAR, TRUE, 0)) {
		DHD_ERROR(("%s(): failed to enable/disable bdcv2 tlv signaling\n",
			__FUNCTION__));
	} else {
		/*
		Leaving the message for now, it should be removed after a while; once
		the tlv situation is stable.
		*/
		DHD_ERROR(("%s(): successful bdcv2 tlv signaling, %d\n",
			__FUNCTION__, tlv));
	}

	dhd_os_wlfc_block(dhd);
	dhd->proptxstatus_mode = WLFC_ONLY_AMPDU_HOSTREORDER;
	dhd_os_wlfc_unblock(dhd);
	/* terence 20161229: enable ampdu_hostreorder if tlv enable hostreorder */
	dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "ampdu_hostreorder", 1, 0, TRUE);

	return BCME_OK;
}

int
dhd_wlfc_cleanup_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
{
	if (dhd == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	if (!dhd->wlfc_state || (dhd->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		dhd_os_wlfc_unblock(dhd);
		return WLFC_UNSUPPORTED;
	}

#ifndef BCMDBUS
	_dhd_wlfc_cleanup_txq(dhd, fn, arg);
#endif /* !BCMDBUS */

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** release all packet resources */
int
dhd_wlfc_cleanup(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
{
	if (dhd == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	if (!dhd->wlfc_state || (dhd->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		dhd_os_wlfc_unblock(dhd);
		return WLFC_UNSUPPORTED;
	}

	_dhd_wlfc_cleanup(dhd, fn, arg);

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

int
dhd_wlfc_deinit(dhd_pub_t *dhd)
{
	/* cleanup all psq related resources */
	athost_wl_status_info_t* wlfc;
	uint32 tlv = 0;
	uint32 hostreorder = 0;

	if (dhd == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);
	if (!dhd->wlfc_enabled) {
		DHD_ERROR(("%s():%d, Already disabled!\n", __FUNCTION__, __LINE__));
		dhd_os_wlfc_unblock(dhd);
		return BCME_OK;
	}

	dhd->wlfc_enabled = FALSE;
	dhd_os_wlfc_unblock(dhd);

	/* query ampdu hostreorder */
	(void) dhd_wl_ioctl_get_intiovar(dhd, "ampdu_hostreorder",
		&hostreorder, WLC_GET_VAR, FALSE, 0);

	if (hostreorder) {
		tlv = WLFC_FLAGS_HOST_RXRERODER_ACTIVE;
		DHD_ERROR(("%s():%d, maintain HOST RXRERODER flag in tvl\n",
			__FUNCTION__, __LINE__));
	}

	/* Disable proptxtstatus signaling for deinit */
	(void) dhd_wl_ioctl_set_intiovar(dhd, "tlv", tlv, WLC_SET_VAR, TRUE, 0);

	dhd_os_wlfc_block(dhd);

	if (!dhd->wlfc_state || (dhd->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		dhd_os_wlfc_unblock(dhd);
		return WLFC_UNSUPPORTED;
	}

	wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;

	_dhd_wlfc_cleanup(dhd, NULL, NULL);

	if (!WLFC_GET_AFQ(dhd->wlfc_mode)) {
		int i;
		wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger;
		for (i = 0; i < h->max_items; i++) {
			if (h->items[i].state != WLFC_HANGER_ITEM_STATE_FREE) {
				_dhd_wlfc_hanger_free_pkt(wlfc, i,
					WLFC_HANGER_PKT_STATE_COMPLETE, TRUE);
			}
		}

		/* delete hanger */
		_dhd_wlfc_hanger_delete(dhd, h);
	}

#if defined(BCMINTERNAL) && defined(OOO_DEBUG)
	if (wlfc->log_buf) {
		MFREE(dhd->osh, wlfc->log_buf, WLFC_LOG_BUF_SIZE);
		wlfc->log_buf_offset = 0;
		wlfc->log_buf_full = FALSE;
	}
#endif /* defined(BCMINTERNAL) && defined(OOO_DEBUG) */

	/* free top structure */
	DHD_OS_PREFREE(dhd, dhd->wlfc_state,
		sizeof(athost_wl_status_info_t));
	dhd->wlfc_state = NULL;
	dhd->proptxstatus_mode = hostreorder ?
		WLFC_ONLY_AMPDU_HOSTREORDER : WLFC_FCMODE_NONE;

	dhd_os_wlfc_unblock(dhd);

	if (dhd->plat_deinit)
		dhd->plat_deinit((void *)dhd);
	return BCME_OK;
} /* dhd_wlfc_init */

/**
 * Called on an interface event (WLC_E_IF) indicated by firmware
 *     @param[in] dhdp   Pointer to public DHD structure
 *     @param[in] action eg eWLFC_MAC_ENTRY_ACTION_UPDATE or eWLFC_MAC_ENTRY_ACTION_ADD
 */
int dhd_wlfc_interface_event(dhd_pub_t *dhdp, uint8 action, uint8 ifid, uint8 iftype, uint8* ea)
{
	int rc;

	if (dhdp == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhdp);

	if (!dhdp->wlfc_state || (dhdp->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		dhd_os_wlfc_unblock(dhdp);
		return WLFC_UNSUPPORTED;
	}

	rc = _dhd_wlfc_interface_entry_update(dhdp->wlfc_state, action, ifid, iftype, ea);

	dhd_os_wlfc_unblock(dhdp);
	return rc;
}

/** Called eg on receiving a WLC_E_FIFO_CREDIT_MAP event from the dongle */
int dhd_wlfc_FIFOcreditmap_event(dhd_pub_t *dhdp, uint8* event_data)
{
	int rc;

	if (dhdp == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhdp);

	if (!dhdp->wlfc_state || (dhdp->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		dhd_os_wlfc_unblock(dhdp);
		return WLFC_UNSUPPORTED;
	}

	rc = _dhd_wlfc_FIFOcreditmap_update(dhdp->wlfc_state, event_data);

	dhd_os_wlfc_unblock(dhdp);

	return rc;
}
#ifdef LIMIT_BORROW
int dhd_wlfc_disable_credit_borrow_event(dhd_pub_t *dhdp, uint8* event_data)
{
	if (dhdp == NULL || event_data == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}
	dhd_os_wlfc_block(dhdp);
	dhdp->wlfc_borrow_allowed = (bool)(*(uint32 *)event_data);
	dhd_os_wlfc_unblock(dhdp);

	return BCME_OK;
}
#endif /* LIMIT_BORROW */

/**
 * Called eg on receiving a WLC_E_BCMC_CREDIT_SUPPORT event from the dongle (broadcast/multicast
 * specific)
 */
int dhd_wlfc_BCMCCredit_support_event(dhd_pub_t *dhdp)
{
	int rc;

	if (dhdp == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhdp);

	if (!dhdp->wlfc_state || (dhdp->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		dhd_os_wlfc_unblock(dhdp);
		return WLFC_UNSUPPORTED;
	}

	rc = _dhd_wlfc_BCMCCredit_support_update(dhdp->wlfc_state);

	dhd_os_wlfc_unblock(dhdp);
	return rc;
}

/** debug specific function */
int
dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
{
	int i;
	uint8* ea;
	athost_wl_status_info_t* wlfc;
	wlfc_hanger_t* h;
	wlfc_mac_descriptor_t* mac_table;
	wlfc_mac_descriptor_t* interfaces;
	char* iftypes[] = {"STA", "AP", "WDS", "p2pGO", "p2pCL"};

	if (!dhdp || !strbuf) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhdp);

	if (!dhdp->wlfc_state || (dhdp->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		dhd_os_wlfc_unblock(dhdp);
		return WLFC_UNSUPPORTED;
	}

	wlfc = (athost_wl_status_info_t*)dhdp->wlfc_state;

	h = (wlfc_hanger_t*)wlfc->hanger;
	if (h == NULL) {
		bcm_bprintf(strbuf, "wlfc-hanger not initialized yet\n");
	}

	mac_table = wlfc->destination_entries.nodes;
	interfaces = wlfc->destination_entries.interfaces;
	bcm_bprintf(strbuf, "---- wlfc stats ----\n");

	if (!WLFC_GET_AFQ(dhdp->wlfc_mode)) {
		h = (wlfc_hanger_t*)wlfc->hanger;
		if (h == NULL) {
			bcm_bprintf(strbuf, "wlfc-hanger not initialized yet\n");
		} else {
			bcm_bprintf(strbuf, "wlfc hanger (pushed,popped,f_push,"
				"f_pop,f_slot, pending) = (%d,%d,%d,%d,%d,%d)\n",
				h->pushed,
				h->popped,
				h->failed_to_push,
				h->failed_to_pop,
				h->failed_slotfind,
				(h->pushed - h->popped));
		}
	}

	bcm_bprintf(strbuf, "wlfc fail(tlv,credit_rqst,mac_update,psmode_update), "
		"(dq_full,rollback_fail) = (%d,%d,%d,%d), (%d,%d)\n",
		wlfc->stats.tlv_parse_failed,
		wlfc->stats.credit_request_failed,
		wlfc->stats.mac_update_failed,
		wlfc->stats.psmode_update_failed,
		wlfc->stats.delayq_full_error,
		wlfc->stats.rollback_failed);

	bcm_bprintf(strbuf, "PKTS (init_credit,credit,sent,drop_d,drop_s,outoforder) "
		"(AC0[%d,%d,%d,%d,%d,%d],AC1[%d,%d,%d,%d,%d,%d],AC2[%d,%d,%d,%d,%d,%d],"
		"AC3[%d,%d,%d,%d,%d,%d],BC_MC[%d,%d,%d,%d,%d,%d])\n",
		wlfc->Init_FIFO_credit[0], wlfc->FIFO_credit[0], wlfc->stats.send_pkts[0],
		wlfc->stats.drop_pkts[0], wlfc->stats.drop_pkts[1], wlfc->stats.ooo_pkts[0],
		wlfc->Init_FIFO_credit[1], wlfc->FIFO_credit[1], wlfc->stats.send_pkts[1],
		wlfc->stats.drop_pkts[2], wlfc->stats.drop_pkts[3], wlfc->stats.ooo_pkts[1],
		wlfc->Init_FIFO_credit[2], wlfc->FIFO_credit[2], wlfc->stats.send_pkts[2],
		wlfc->stats.drop_pkts[4], wlfc->stats.drop_pkts[5], wlfc->stats.ooo_pkts[2],
		wlfc->Init_FIFO_credit[3], wlfc->FIFO_credit[3], wlfc->stats.send_pkts[3],
		wlfc->stats.drop_pkts[6], wlfc->stats.drop_pkts[7], wlfc->stats.ooo_pkts[3],
		wlfc->Init_FIFO_credit[4], wlfc->FIFO_credit[4], wlfc->stats.send_pkts[4],
		wlfc->stats.drop_pkts[8], wlfc->stats.drop_pkts[9], wlfc->stats.ooo_pkts[4]);

	bcm_bprintf(strbuf, "\n");
	for (i = 0; i < WLFC_MAX_IFNUM; i++) {
		if (interfaces[i].occupied) {
			char* iftype_desc;

			if (interfaces[i].iftype > WLC_E_IF_ROLE_P2P_CLIENT)
				iftype_desc = "<Unknown";
			else
				iftype_desc = iftypes[interfaces[i].iftype];

			ea = interfaces[i].ea;
			bcm_bprintf(strbuf, "INTERFACE[%d].ea = "
				"["MACDBG"], if:%d, type: %s "
				"netif_flow_control:%s\n", i,
				MAC2STRDBG(ea), interfaces[i].interface_id,
				iftype_desc, ((wlfc->hostif_flow_state[i] == OFF)
				? " OFF":" ON"));

			bcm_bprintf(strbuf, "INTERFACE[%d].PSQ(len,state,credit),"
				"(trans,supp_trans,onbus)"
				"= (%d,%s,%d),(%d,%d,%d)\n",
				i,
				interfaces[i].psq.n_pkts_tot,
				((interfaces[i].state ==
				WLFC_STATE_OPEN) ? "OPEN":"CLOSE"),
				interfaces[i].requested_credit,
				interfaces[i].transit_count,
				interfaces[i].suppr_transit_count,
				interfaces[i].onbus_pkts_count);

			bcm_bprintf(strbuf, "INTERFACE[%d].PSQ"
				"(delay0,sup0,afq0),(delay1,sup1,afq1),(delay2,sup2,afq2),"
				"(delay3,sup3,afq3),(delay4,sup4,afq4) = (%d,%d,%d),"
				"(%d,%d,%d),(%d,%d,%d),(%d,%d,%d),(%d,%d,%d)\n",
				i,
				interfaces[i].psq.q[0].n_pkts,
				interfaces[i].psq.q[1].n_pkts,
				interfaces[i].afq.q[0].n_pkts,
				interfaces[i].psq.q[2].n_pkts,
				interfaces[i].psq.q[3].n_pkts,
				interfaces[i].afq.q[1].n_pkts,
				interfaces[i].psq.q[4].n_pkts,
				interfaces[i].psq.q[5].n_pkts,
				interfaces[i].afq.q[2].n_pkts,
				interfaces[i].psq.q[6].n_pkts,
				interfaces[i].psq.q[7].n_pkts,
				interfaces[i].afq.q[3].n_pkts,
				interfaces[i].psq.q[8].n_pkts,
				interfaces[i].psq.q[9].n_pkts,
				interfaces[i].afq.q[4].n_pkts);
		}
	}

	bcm_bprintf(strbuf, "\n");
	for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
		if (mac_table[i].occupied) {
			ea = mac_table[i].ea;
			bcm_bprintf(strbuf, "MAC_table[%d].ea = "
				"["MACDBG"], if:%d \n", i,
				MAC2STRDBG(ea),	mac_table[i].interface_id);

			bcm_bprintf(strbuf, "MAC_table[%d].PSQ(len,state,credit),"
				"(trans,supp_trans,onbus)"
				"= (%d,%s,%d),(%d,%d,%d)\n",
				i,
				mac_table[i].psq.n_pkts_tot,
				((mac_table[i].state ==
				WLFC_STATE_OPEN) ? " OPEN":"CLOSE"),
				mac_table[i].requested_credit,
				mac_table[i].transit_count,
				mac_table[i].suppr_transit_count,
				mac_table[i].onbus_pkts_count);
#ifdef PROP_TXSTATUS_DEBUG
			bcm_bprintf(strbuf, "MAC_table[%d]: (opened, closed) = (%d, %d)\n",
				i, mac_table[i].opened_ct, mac_table[i].closed_ct);
#endif
			bcm_bprintf(strbuf, "MAC_table[%d].PSQ"
				"(delay0,sup0,afq0),(delay1,sup1,afq1),(delay2,sup2,afq2),"
				"(delay3,sup3,afq3),(delay4,sup4,afq4) =(%d,%d,%d),"
				"(%d,%d,%d),(%d,%d,%d),(%d,%d,%d),(%d,%d,%d)\n",
				i,
				mac_table[i].psq.q[0].n_pkts,
				mac_table[i].psq.q[1].n_pkts,
				mac_table[i].afq.q[0].n_pkts,
				mac_table[i].psq.q[2].n_pkts,
				mac_table[i].psq.q[3].n_pkts,
				mac_table[i].afq.q[1].n_pkts,
				mac_table[i].psq.q[4].n_pkts,
				mac_table[i].psq.q[5].n_pkts,
				mac_table[i].afq.q[2].n_pkts,
				mac_table[i].psq.q[6].n_pkts,
				mac_table[i].psq.q[7].n_pkts,
				mac_table[i].afq.q[3].n_pkts,
				mac_table[i].psq.q[8].n_pkts,
				mac_table[i].psq.q[9].n_pkts,
				mac_table[i].afq.q[4].n_pkts);

		}
	}

#ifdef PROP_TXSTATUS_DEBUG
	{
		int avg;
		int moving_avg = 0;
		int moving_samples;

		if (wlfc->stats.latency_sample_count) {
			moving_samples = sizeof(wlfc->stats.deltas)/sizeof(uint32);

			for (i = 0; i < moving_samples; i++)
				moving_avg += wlfc->stats.deltas[i];
			moving_avg /= moving_samples;

			avg = (100 * wlfc->stats.total_status_latency) /
				wlfc->stats.latency_sample_count;
			bcm_bprintf(strbuf, "txstatus latency (average, last, moving[%d]) = "
				"(%d.%d, %03d, %03d)\n",
				moving_samples, avg/100, (avg - (avg/100)*100),
				wlfc->stats.latency_most_recent,
				moving_avg);
		}
	}

	bcm_bprintf(strbuf, "wlfc- fifo[0-5] credit stats: sent = (%d,%d,%d,%d,%d,%d), "
		"back = (%d,%d,%d,%d,%d,%d)\n",
		wlfc->stats.fifo_credits_sent[0],
		wlfc->stats.fifo_credits_sent[1],
		wlfc->stats.fifo_credits_sent[2],
		wlfc->stats.fifo_credits_sent[3],
		wlfc->stats.fifo_credits_sent[4],
		wlfc->stats.fifo_credits_sent[5],

		wlfc->stats.fifo_credits_back[0],
		wlfc->stats.fifo_credits_back[1],
		wlfc->stats.fifo_credits_back[2],
		wlfc->stats.fifo_credits_back[3],
		wlfc->stats.fifo_credits_back[4],
		wlfc->stats.fifo_credits_back[5]);
	{
		uint32 fifo_cr_sent = 0;
		uint32 fifo_cr_acked = 0;
		uint32 request_cr_sent = 0;
		uint32 request_cr_ack = 0;
		uint32 bc_mc_cr_ack = 0;

		for (i = 0; i < sizeof(wlfc->stats.fifo_credits_sent)/sizeof(uint32); i++) {
			fifo_cr_sent += wlfc->stats.fifo_credits_sent[i];
		}

		for (i = 0; i < sizeof(wlfc->stats.fifo_credits_back)/sizeof(uint32); i++) {
			fifo_cr_acked += wlfc->stats.fifo_credits_back[i];
		}

		for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
			if (wlfc->destination_entries.nodes[i].occupied) {
				request_cr_sent +=
					wlfc->destination_entries.nodes[i].dstncredit_sent_packets;
			}
		}
		for (i = 0; i < WLFC_MAX_IFNUM; i++) {
			if (wlfc->destination_entries.interfaces[i].occupied) {
				request_cr_sent +=
				wlfc->destination_entries.interfaces[i].dstncredit_sent_packets;
			}
		}
		for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
			if (wlfc->destination_entries.nodes[i].occupied) {
				request_cr_ack +=
					wlfc->destination_entries.nodes[i].dstncredit_acks;
			}
		}
		for (i = 0; i < WLFC_MAX_IFNUM; i++) {
			if (wlfc->destination_entries.interfaces[i].occupied) {
				request_cr_ack +=
					wlfc->destination_entries.interfaces[i].dstncredit_acks;
			}
		}
		bcm_bprintf(strbuf, "wlfc- (sent, status) => pq(%d,%d), vq(%d,%d),"
			"other:%d, bc_mc:%d, signal-only, (sent,freed): (%d,%d)",
			fifo_cr_sent, fifo_cr_acked,
			request_cr_sent, request_cr_ack,
			wlfc->destination_entries.other.dstncredit_acks,
			bc_mc_cr_ack,
			wlfc->stats.signal_only_pkts_sent, wlfc->stats.signal_only_pkts_freed);
	}
#endif /* PROP_TXSTATUS_DEBUG */
	bcm_bprintf(strbuf, "\n");
	bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull,out),"
		"(dropped,hdr_only,wlc_tossed,wlc_dropped,wlc_exptime)"
		"(freed,free_err,rollback)) = "
		"((%d,%d,%d,%d,%d),(%d,%d,%d,%d,%d),(%d,%d,%d))\n",
		wlfc->stats.pktin,
		wlfc->stats.pkt2bus,
		wlfc->stats.txstatus_in,
		wlfc->stats.dhd_hdrpulls,
		wlfc->stats.pktout,

		wlfc->stats.pktdropped,
		wlfc->stats.wlfc_header_only_pkt,
		wlfc->stats.wlc_tossed_pkts,
		wlfc->stats.pkt_dropped,
		wlfc->stats.pkt_exptime,

		wlfc->stats.pkt_freed,
		wlfc->stats.pkt_free_err, wlfc->stats.rollback);

	bcm_bprintf(strbuf, "wlfc- suppress((d11,wlc,err),enq(d11,wl,hq,mac?),retx(d11,wlc,hq)) = "
		"((%d,%d,%d),(%d,%d,%d,%d),(%d,%d,%d))\n",
		wlfc->stats.d11_suppress,
		wlfc->stats.wl_suppress,
		wlfc->stats.bad_suppress,

		wlfc->stats.psq_d11sup_enq,
		wlfc->stats.psq_wlsup_enq,
		wlfc->stats.psq_hostq_enq,
		wlfc->stats.mac_handle_notfound,

		wlfc->stats.psq_d11sup_retx,
		wlfc->stats.psq_wlsup_retx,
		wlfc->stats.psq_hostq_retx);

	bcm_bprintf(strbuf, "wlfc- cleanup(txq,psq,fw) = (%d,%d,%d)\n",
		wlfc->stats.cleanup_txq_cnt,
		wlfc->stats.cleanup_psq_cnt,
		wlfc->stats.cleanup_fw_cnt);

	bcm_bprintf(strbuf, "wlfc- generic error: %d\n", wlfc->stats.generic_error);

	for (i = 0; i < WLFC_MAX_IFNUM; i++) {
		bcm_bprintf(strbuf, "wlfc- if[%d], pkt_cnt_in_q/AC[0-4] = (%d,%d,%d,%d,%d)\n", i,
			wlfc->pkt_cnt_in_q[i][0],
			wlfc->pkt_cnt_in_q[i][1],
			wlfc->pkt_cnt_in_q[i][2],
			wlfc->pkt_cnt_in_q[i][3],
			wlfc->pkt_cnt_in_q[i][4]);
	}
	bcm_bprintf(strbuf, "\n");

	dhd_os_wlfc_unblock(dhdp);
	return BCME_OK;
} /* dhd_wlfc_dump */

int dhd_wlfc_clear_counts(dhd_pub_t *dhd)
{
	athost_wl_status_info_t* wlfc;
	wlfc_hanger_t* hanger;

	if (dhd == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	if (!dhd->wlfc_state || (dhd->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		dhd_os_wlfc_unblock(dhd);
		return WLFC_UNSUPPORTED;
	}

	wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;

	memset(&wlfc->stats, 0, sizeof(athost_wl_stat_counters_t));

	if (!WLFC_GET_AFQ(dhd->wlfc_mode)) {
		hanger = (wlfc_hanger_t*)wlfc->hanger;

		hanger->pushed = 0;
		hanger->popped = 0;
		hanger->failed_slotfind = 0;
		hanger->failed_to_pop = 0;
		hanger->failed_to_push = 0;
	}

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** returns TRUE if flow control is enabled */
int dhd_wlfc_get_enable(dhd_pub_t *dhd, bool *val)
{
	if (!dhd || !val) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	*val = dhd->wlfc_enabled;

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** Called via an IOVAR */
int dhd_wlfc_get_mode(dhd_pub_t *dhd, int *val)
{
	if (!dhd || !val) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	*val = dhd->wlfc_state ? dhd->proptxstatus_mode : 0;

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** Called via an IOVAR */
int dhd_wlfc_set_mode(dhd_pub_t *dhd, int val)
{
	if (!dhd) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	if (dhd->wlfc_state) {
		dhd->proptxstatus_mode = val & 0xff;
	}

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** Called when rx frame is received from the dongle */
bool dhd_wlfc_is_header_only_pkt(dhd_pub_t * dhd, void *pktbuf)
{
	athost_wl_status_info_t* wlfc;
	bool rc = FALSE;

	if (dhd == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return FALSE;
	}

	dhd_os_wlfc_block(dhd);

	if (!dhd->wlfc_state || (dhd->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		dhd_os_wlfc_unblock(dhd);
		return FALSE;
	}

	wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;

	if (PKTLEN(wlfc->osh, pktbuf) == 0) {
		wlfc->stats.wlfc_header_only_pkt++;
		rc = TRUE;
	}

	dhd_os_wlfc_unblock(dhd);

	return rc;
}

int dhd_wlfc_flowcontrol(dhd_pub_t *dhdp, bool state, bool bAcquireLock)
{
	if (dhdp == NULL) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	if (bAcquireLock) {
		dhd_os_wlfc_block(dhdp);
	}

	if (!dhdp->wlfc_state || (dhdp->proptxstatus_mode == WLFC_FCMODE_NONE) ||
		dhdp->proptxstatus_module_ignore) {
		if (bAcquireLock) {
			dhd_os_wlfc_unblock(dhdp);
		}
		return WLFC_UNSUPPORTED;
	}

	if (state != dhdp->proptxstatus_txoff) {
		dhdp->proptxstatus_txoff = state;
	}

	if (bAcquireLock) {
		dhd_os_wlfc_unblock(dhdp);
	}

	return BCME_OK;
}

/** Called when eg an rx frame is received from the dongle */
int dhd_wlfc_save_rxpath_ac_time(dhd_pub_t * dhd, uint8 prio)
{
	athost_wl_status_info_t* wlfc;
	int rx_path_ac = -1;

	if ((dhd == NULL) || (prio >= NUMPRIO)) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	if (!dhd->wlfc_rxpkt_chk) {
		dhd_os_wlfc_unblock(dhd);
		return BCME_OK;
	}

	if (!dhd->wlfc_state || (dhd->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		dhd_os_wlfc_unblock(dhd);
		return WLFC_UNSUPPORTED;
	}

	wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;

	rx_path_ac = prio2fifo[prio];
	wlfc->rx_timestamp[rx_path_ac] = OSL_SYSUPTIME();

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** called via an IOVAR */
int dhd_wlfc_get_module_ignore(dhd_pub_t *dhd, int *val)
{
	if (!dhd || !val) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	*val = dhd->proptxstatus_module_ignore;

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** called via an IOVAR */
int dhd_wlfc_set_module_ignore(dhd_pub_t *dhd, int val)
{
	uint32 tlv = 0;
	bool bChanged = FALSE;

	if (!dhd) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	if ((bool)val != dhd->proptxstatus_module_ignore) {
		dhd->proptxstatus_module_ignore = (val != 0);
		/* force txstatus_ignore sync with proptxstatus_module_ignore */
		dhd->proptxstatus_txstatus_ignore = dhd->proptxstatus_module_ignore;
		if (FALSE == dhd->proptxstatus_module_ignore) {
			tlv = WLFC_FLAGS_RSSI_SIGNALS |
				WLFC_FLAGS_XONXOFF_SIGNALS |
				WLFC_FLAGS_CREDIT_STATUS_SIGNALS |
				WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE;
		}
		/* always enable host reorder */
		tlv |= WLFC_FLAGS_HOST_RXRERODER_ACTIVE;
		bChanged = TRUE;
	}

	dhd_os_wlfc_unblock(dhd);

	if (bChanged) {
		/* select enable proptxtstatus signaling */
		if (dhd_wl_ioctl_set_intiovar(dhd, "tlv", tlv, WLC_SET_VAR, TRUE, 0)) {
			DHD_ERROR(("%s: failed to set bdcv2 tlv signaling to 0x%x\n",
				__FUNCTION__, tlv));
		} else {
			DHD_ERROR(("%s: successfully set bdcv2 tlv signaling to 0x%x\n",
				__FUNCTION__, tlv));
		}
	}

#if defined(DHD_WLFC_THREAD)
	_dhd_wlfc_thread_wakeup(dhd);
#endif /* defined(DHD_WLFC_THREAD) */

	return BCME_OK;
}

/** called via an IOVAR */
int dhd_wlfc_get_credit_ignore(dhd_pub_t *dhd, int *val)
{
	if (!dhd || !val) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	*val = dhd->proptxstatus_credit_ignore;

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** called via an IOVAR */
int dhd_wlfc_set_credit_ignore(dhd_pub_t *dhd, int val)
{
	if (!dhd) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	dhd->proptxstatus_credit_ignore = (val != 0);

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** called via an IOVAR */
int dhd_wlfc_get_txstatus_ignore(dhd_pub_t *dhd, int *val)
{
	if (!dhd || !val) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	*val = dhd->proptxstatus_txstatus_ignore;

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** called via an IOVAR */
int dhd_wlfc_set_txstatus_ignore(dhd_pub_t *dhd, int val)
{
	if (!dhd) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	dhd->proptxstatus_txstatus_ignore = (val != 0);

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** called via an IOVAR */
int dhd_wlfc_get_rxpkt_chk(dhd_pub_t *dhd, int *val)
{
	if (!dhd || !val) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	*val = dhd->wlfc_rxpkt_chk;

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

/** called via an IOVAR */
int dhd_wlfc_set_rxpkt_chk(dhd_pub_t *dhd, int val)
{
	if (!dhd) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhd);

	dhd->wlfc_rxpkt_chk = (val != 0);

	dhd_os_wlfc_unblock(dhd);

	return BCME_OK;
}

int dhd_txpkt_log_and_dump(dhd_pub_t *dhdp, void* pkt, uint16 *pktfate_status)
{
	uint32 pktid;
	uint32 pktlen = PKTLEN(dhdp->osh, pkt);
	uint8 *pktdata = PKTDATA(dhdp->osh, pkt);
#ifdef BDC
	struct bdc_header *bdch;
	uint32 bdc_len;
#endif /* BDC */
	uint8 ifidx = DHD_PKTTAG_IF(PKTTAG(pkt));
	uint8 hcnt = WL_TXSTATUS_GET_FREERUNCTR(DHD_PKTTAG_H2DTAG(PKTTAG(pkt)));
	uint8 fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pkt));

	if (!pkt) {
		DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
		return BCME_BADARG;
	}
	pktid = (ifidx << DHD_PKTID_IF_SHIFT) | (fifo_id << DHD_PKTID_FIFO_SHIFT) | hcnt;
#ifdef BDC
	bdch = (struct bdc_header *)pktdata;
	bdc_len = BDC_HEADER_LEN + (bdch->dataOffset << DHD_WORD_TO_LEN_SHIFT);
	pktlen -= bdc_len;
	pktdata = pktdata + bdc_len;
#endif /* BDC */
	dhd_handle_pktdata(dhdp, ifidx, pkt, pktdata, pktid, pktlen,
		pktfate_status, NULL, TRUE, FALSE, TRUE);
	return BCME_OK;
}

#ifdef PROPTX_MAXCOUNT
int dhd_wlfc_update_maxcount(dhd_pub_t *dhdp, uint8 ifid, int maxcount)
{
	athost_wl_status_info_t* ctx;
	int rc = 0;

	if (dhdp == NULL) {
		DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
		return BCME_BADARG;
	}

	dhd_os_wlfc_block(dhdp);

	if (!dhdp->wlfc_state || (dhdp->proptxstatus_mode == WLFC_FCMODE_NONE)) {
		rc = WLFC_UNSUPPORTED;
		goto exit;
	}

	if (ifid >= WLFC_MAX_IFNUM) {
		DHD_ERROR(("%s: bad ifid\n", __FUNCTION__));
		rc = BCME_BADARG;
		goto exit;
	}

	ctx = (athost_wl_status_info_t*)dhdp->wlfc_state;
	ctx->destination_entries.interfaces[ifid].transit_maxcount = maxcount;
exit:
	dhd_os_wlfc_unblock(dhdp);
	return rc;
}
#endif /* PROPTX_MAXCOUNT */
#endif /* PROP_TXSTATUS */
