/*
 * Copyright (c) 2007-2011 Atheros Communications Inc.
 * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "core.h"
#include "hif.h"
#include "debug.h"
#include "hif-ops.h"
#include "trace.h"

#include <asm/unaligned.h>

#define CALC_TXRX_PADDED_LEN(dev, len)  (__ALIGN_MASK((len), (dev)->block_mask))

static void ath6kl_htc_mbox_cleanup(struct htc_target *target);
static void ath6kl_htc_mbox_stop(struct htc_target *target);
static int ath6kl_htc_mbox_add_rxbuf_multiple(struct htc_target *target,
					      struct list_head *pkt_queue);
static void ath6kl_htc_set_credit_dist(struct htc_target *target,
				       struct ath6kl_htc_credit_info *cred_info,
				       u16 svc_pri_order[], int len);

/* threshold to re-enable Tx bundling for an AC*/
#define TX_RESUME_BUNDLE_THRESHOLD	1500

/* Functions for Tx credit handling */
static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info,
				  struct htc_endpoint_credit_dist *ep_dist,
				  int credits)
{
	ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit deposit ep %d credits %d\n",
		   ep_dist->endpoint, credits);

	ep_dist->credits += credits;
	ep_dist->cred_assngd += credits;
	cred_info->cur_free_credits -= credits;
}

static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
			       struct list_head *ep_list,
			       int tot_credits)
{
	struct htc_endpoint_credit_dist *cur_ep_dist;
	int count;

	ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit init total %d\n", tot_credits);

	cred_info->cur_free_credits = tot_credits;
	cred_info->total_avail_credits = tot_credits;

	list_for_each_entry(cur_ep_dist, ep_list, list) {
		if (cur_ep_dist->endpoint == ENDPOINT_0)
			continue;

		cur_ep_dist->cred_min = cur_ep_dist->cred_per_msg;

		if (tot_credits > 4) {
			if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) ||
			    (cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) {
				ath6kl_credit_deposit(cred_info,
						      cur_ep_dist,
						      cur_ep_dist->cred_min);
				cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
			}
		}

		if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
			ath6kl_credit_deposit(cred_info, cur_ep_dist,
					      cur_ep_dist->cred_min);
			/*
			 * Control service is always marked active, it
			 * never goes inactive EVER.
			 */
			cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
		}

		/*
		 * Streams have to be created (explicit | implicit) for all
		 * kinds of traffic. BE endpoints are also inactive in the
		 * beginning. When BE traffic starts it creates implicit
		 * streams that redistributes credits.
		 *
		 * Note: all other endpoints have minimums set but are
		 * initially given NO credits. credits will be distributed
		 * as traffic activity demands
		 */
	}

	/*
	 * For ath6kl_credit_seek function,
	 * it use list_for_each_entry_reverse to walk around the whole ep list.
	 * Therefore assign this lowestpri_ep_dist after walk around the ep_list
	 */
	cred_info->lowestpri_ep_dist = cur_ep_dist->list;

	WARN_ON(cred_info->cur_free_credits <= 0);

	list_for_each_entry(cur_ep_dist, ep_list, list) {
		if (cur_ep_dist->endpoint == ENDPOINT_0)
			continue;

		if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
			cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg;
		} else {
			/*
			 * For the remaining data endpoints, we assume that
			 * each cred_per_msg are the same. We use a simple
			 * calculation here, we take the remaining credits
			 * and determine how many max messages this can
			 * cover and then set each endpoint's normal value
			 * equal to 3/4 this amount.
			 */
			count = (cred_info->cur_free_credits /
				 cur_ep_dist->cred_per_msg)
				* cur_ep_dist->cred_per_msg;
			count = (count * 3) >> 2;
			count = max(count, cur_ep_dist->cred_per_msg);
			cur_ep_dist->cred_norm = count;
		}

		ath6kl_dbg(ATH6KL_DBG_CREDIT,
			   "credit ep %d svc_id %d credits %d per_msg %d norm %d min %d\n",
			   cur_ep_dist->endpoint,
			   cur_ep_dist->svc_id,
			   cur_ep_dist->credits,
			   cur_ep_dist->cred_per_msg,
			   cur_ep_dist->cred_norm,
			   cur_ep_dist->cred_min);
	}
}

/* initialize and setup credit distribution */
static int ath6kl_htc_mbox_credit_setup(struct htc_target *htc_target,
			       struct ath6kl_htc_credit_info *cred_info)
{
	u16 servicepriority[5];

	memset(cred_info, 0, sizeof(struct ath6kl_htc_credit_info));

	servicepriority[0] = WMI_CONTROL_SVC;  /* highest */
	servicepriority[1] = WMI_DATA_VO_SVC;
	servicepriority[2] = WMI_DATA_VI_SVC;
	servicepriority[3] = WMI_DATA_BE_SVC;
	servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */

	/* set priority list */
	ath6kl_htc_set_credit_dist(htc_target, cred_info, servicepriority, 5);

	return 0;
}

/* reduce an ep's credits back to a set limit */
static void ath6kl_credit_reduce(struct ath6kl_htc_credit_info *cred_info,
				 struct htc_endpoint_credit_dist *ep_dist,
				 int limit)
{
	int credits;

	ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit reduce ep %d limit %d\n",
		   ep_dist->endpoint, limit);

	ep_dist->cred_assngd = limit;

	if (ep_dist->credits <= limit)
		return;

	credits = ep_dist->credits - limit;
	ep_dist->credits -= credits;
	cred_info->cur_free_credits += credits;
}

static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info,
				 struct list_head *epdist_list)
{
	struct htc_endpoint_credit_dist *cur_list;

	list_for_each_entry(cur_list, epdist_list, list) {
		if (cur_list->endpoint == ENDPOINT_0)
			continue;

		if (cur_list->cred_to_dist > 0) {
			cur_list->credits += cur_list->cred_to_dist;
			cur_list->cred_to_dist = 0;

			if (cur_list->credits > cur_list->cred_assngd)
				ath6kl_credit_reduce(cred_info,
						     cur_list,
						     cur_list->cred_assngd);

			if (cur_list->credits > cur_list->cred_norm)
				ath6kl_credit_reduce(cred_info, cur_list,
						     cur_list->cred_norm);

			if (!(cur_list->dist_flags & HTC_EP_ACTIVE)) {
				if (cur_list->txq_depth == 0)
					ath6kl_credit_reduce(cred_info,
							     cur_list, 0);
			}
		}
	}
}

/*
 * HTC has an endpoint that needs credits, ep_dist is the endpoint in
 * question.
 */
static void ath6kl_credit_seek(struct ath6kl_htc_credit_info *cred_info,
				struct htc_endpoint_credit_dist *ep_dist)
{
	struct htc_endpoint_credit_dist *curdist_list;
	int credits = 0;
	int need;

	if (ep_dist->svc_id == WMI_CONTROL_SVC)
		goto out;

	if ((ep_dist->svc_id == WMI_DATA_VI_SVC) ||
	    (ep_dist->svc_id == WMI_DATA_VO_SVC))
		if ((ep_dist->cred_assngd >= ep_dist->cred_norm))
			goto out;

	/*
	 * For all other services, we follow a simple algorithm of:
	 *
	 * 1. checking the free pool for credits
	 * 2. checking lower priority endpoints for credits to take
	 */

	credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);

	if (credits >= ep_dist->seek_cred)
		goto out;

	/*
	 * We don't have enough in the free pool, try taking away from
	 * lower priority services The rule for taking away credits:
	 *
	 *   1. Only take from lower priority endpoints
	 *   2. Only take what is allocated above the minimum (never
	 *      starve an endpoint completely)
	 *   3. Only take what you need.
	 */

	list_for_each_entry_reverse(curdist_list,
				    &cred_info->lowestpri_ep_dist,
				    list) {
		if (curdist_list == ep_dist)
			break;

		need = ep_dist->seek_cred - cred_info->cur_free_credits;

		if ((curdist_list->cred_assngd - need) >=
		     curdist_list->cred_min) {
			/*
			 * The current one has been allocated more than
			 * it's minimum and it has enough credits assigned
			 * above it's minimum to fulfill our need try to
			 * take away just enough to fulfill our need.
			 */
			ath6kl_credit_reduce(cred_info, curdist_list,
					     curdist_list->cred_assngd - need);

			if (cred_info->cur_free_credits >=
			    ep_dist->seek_cred)
				break;
		}

		if (curdist_list->endpoint == ENDPOINT_0)
			break;
	}

	credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);

out:
	/* did we find some credits? */
	if (credits)
		ath6kl_credit_deposit(cred_info, ep_dist, credits);

	ep_dist->seek_cred = 0;
}

/* redistribute credits based on activity change */
static void ath6kl_credit_redistribute(struct ath6kl_htc_credit_info *info,
				       struct list_head *ep_dist_list)
{
	struct htc_endpoint_credit_dist *curdist_list;

	list_for_each_entry(curdist_list, ep_dist_list, list) {
		if (curdist_list->endpoint == ENDPOINT_0)
			continue;

		if ((curdist_list->svc_id == WMI_DATA_BK_SVC)  ||
		    (curdist_list->svc_id == WMI_DATA_BE_SVC))
			curdist_list->dist_flags |= HTC_EP_ACTIVE;

		if ((curdist_list->svc_id != WMI_CONTROL_SVC) &&
		    !(curdist_list->dist_flags & HTC_EP_ACTIVE)) {
			if (curdist_list->txq_depth == 0)
				ath6kl_credit_reduce(info, curdist_list, 0);
			else
				ath6kl_credit_reduce(info,
						     curdist_list,
						     curdist_list->cred_min);
		}
	}
}

/*
 *
 * This function is invoked whenever endpoints require credit
 * distributions. A lock is held while this function is invoked, this
 * function shall NOT block. The ep_dist_list is a list of distribution
 * structures in prioritized order as defined by the call to the
 * htc_set_credit_dist() api.
 */
static void ath6kl_credit_distribute(struct ath6kl_htc_credit_info *cred_info,
				     struct list_head *ep_dist_list,
			      enum htc_credit_dist_reason reason)
{
	switch (reason) {
	case HTC_CREDIT_DIST_SEND_COMPLETE:
		ath6kl_credit_update(cred_info, ep_dist_list);
		break;
	case HTC_CREDIT_DIST_ACTIVITY_CHANGE:
		ath6kl_credit_redistribute(cred_info, ep_dist_list);
		break;
	default:
		break;
	}

	WARN_ON(cred_info->cur_free_credits > cred_info->total_avail_credits);
	WARN_ON(cred_info->cur_free_credits < 0);
}

static void ath6kl_htc_tx_buf_align(u8 **buf, unsigned long len)
{
	u8 *align_addr;

	if (!IS_ALIGNED((unsigned long) *buf, 4)) {
		align_addr = PTR_ALIGN(*buf - 4, 4);
		memmove(align_addr, *buf, len);
		*buf = align_addr;
	}
}

static void ath6kl_htc_tx_prep_pkt(struct htc_packet *packet, u8 flags,
				   int ctrl0, int ctrl1)
{
	struct htc_frame_hdr *hdr;

	packet->buf -= HTC_HDR_LENGTH;
	hdr =  (struct htc_frame_hdr *)packet->buf;

	/* Endianess? */
	put_unaligned((u16)packet->act_len, &hdr->payld_len);
	hdr->flags = flags;
	hdr->eid = packet->endpoint;
	hdr->ctrl[0] = ctrl0;
	hdr->ctrl[1] = ctrl1;
}

static void htc_reclaim_txctrl_buf(struct htc_target *target,
				   struct htc_packet *pkt)
{
	spin_lock_bh(&target->htc_lock);
	list_add_tail(&pkt->list, &target->free_ctrl_txbuf);
	spin_unlock_bh(&target->htc_lock);
}

static struct htc_packet *htc_get_control_buf(struct htc_target *target,
					      bool tx)
{
	struct htc_packet *packet = NULL;
	struct list_head *buf_list;

	buf_list = tx ? &target->free_ctrl_txbuf : &target->free_ctrl_rxbuf;

	spin_lock_bh(&target->htc_lock);

	if (list_empty(buf_list)) {
		spin_unlock_bh(&target->htc_lock);
		return NULL;
	}

	packet = list_first_entry(buf_list, struct htc_packet, list);
	list_del(&packet->list);
	spin_unlock_bh(&target->htc_lock);

	if (tx)
		packet->buf = packet->buf_start + HTC_HDR_LENGTH;

	return packet;
}

static void htc_tx_comp_update(struct htc_target *target,
			       struct htc_endpoint *endpoint,
			       struct htc_packet *packet)
{
	packet->completion = NULL;
	packet->buf += HTC_HDR_LENGTH;

	if (!packet->status)
		return;

	ath6kl_err("req failed (status:%d, ep:%d, len:%d creds:%d)\n",
		   packet->status, packet->endpoint, packet->act_len,
		   packet->info.tx.cred_used);

	/* on failure to submit, reclaim credits for this packet */
	spin_lock_bh(&target->tx_lock);
	endpoint->cred_dist.cred_to_dist +=
				packet->info.tx.cred_used;
	endpoint->cred_dist.txq_depth = get_queue_depth(&endpoint->txq);

	ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx ctxt 0x%p dist 0x%p\n",
		   target->credit_info, &target->cred_dist_list);

	ath6kl_credit_distribute(target->credit_info,
				 &target->cred_dist_list,
				 HTC_CREDIT_DIST_SEND_COMPLETE);

	spin_unlock_bh(&target->tx_lock);
}

static void htc_tx_complete(struct htc_endpoint *endpoint,
			    struct list_head *txq)
{
	if (list_empty(txq))
		return;

	ath6kl_dbg(ATH6KL_DBG_HTC,
		   "htc tx complete ep %d pkts %d\n",
		   endpoint->eid, get_queue_depth(txq));

	ath6kl_tx_complete(endpoint->target, txq);
}

static void htc_tx_comp_handler(struct htc_target *target,
				struct htc_packet *packet)
{
	struct htc_endpoint *endpoint = &target->endpoint[packet->endpoint];
	struct list_head container;

	ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx complete seqno %d\n",
		   packet->info.tx.seqno);

	htc_tx_comp_update(target, endpoint, packet);
	INIT_LIST_HEAD(&container);
	list_add_tail(&packet->list, &container);
	/* do completion */
	htc_tx_complete(endpoint, &container);
}

static void htc_async_tx_scat_complete(struct htc_target *target,
				       struct hif_scatter_req *scat_req)
{
	struct htc_endpoint *endpoint;
	struct htc_packet *packet;
	struct list_head tx_compq;
	int i;

	INIT_LIST_HEAD(&tx_compq);

	ath6kl_dbg(ATH6KL_DBG_HTC,
		   "htc tx scat complete len %d entries %d\n",
		   scat_req->len, scat_req->scat_entries);

	if (scat_req->status)
		ath6kl_err("send scatter req failed: %d\n", scat_req->status);

	packet = scat_req->scat_list[0].packet;
	endpoint = &target->endpoint[packet->endpoint];

	/* walk through the scatter list and process */
	for (i = 0; i < scat_req->scat_entries; i++) {
		packet = scat_req->scat_list[i].packet;
		if (!packet) {
			WARN_ON(1);
			return;
		}

		packet->status = scat_req->status;
		htc_tx_comp_update(target, endpoint, packet);
		list_add_tail(&packet->list, &tx_compq);
	}

	/* free scatter request */
	hif_scatter_req_add(target->dev->ar, scat_req);

	/* complete all packets */
	htc_tx_complete(endpoint, &tx_compq);
}

static int ath6kl_htc_tx_issue(struct htc_target *target,
			       struct htc_packet *packet)
{
	int status;
	bool sync = false;
	u32 padded_len, send_len;

	if (!packet->completion)
		sync = true;

	send_len = packet->act_len + HTC_HDR_LENGTH;

	padded_len = CALC_TXRX_PADDED_LEN(target, send_len);

	ath6kl_dbg(ATH6KL_DBG_HTC,
		   "htc tx issue len %d seqno %d padded_len %d mbox 0x%X %s\n",
		   send_len, packet->info.tx.seqno, padded_len,
		   target->dev->ar->mbox_info.htc_addr,
		   sync ? "sync" : "async");

	if (sync) {
		status = hif_read_write_sync(target->dev->ar,
				target->dev->ar->mbox_info.htc_addr,
				 packet->buf, padded_len,
				 HIF_WR_SYNC_BLOCK_INC);

		packet->status = status;
		packet->buf += HTC_HDR_LENGTH;
	} else
		status = hif_write_async(target->dev->ar,
				target->dev->ar->mbox_info.htc_addr,
				packet->buf, padded_len,
				HIF_WR_ASYNC_BLOCK_INC, packet);

	trace_ath6kl_htc_tx(status, packet->endpoint, packet->buf, send_len);

	return status;
}

static int htc_check_credits(struct htc_target *target,
			     struct htc_endpoint *ep, u8 *flags,
			     enum htc_endpoint_id eid, unsigned int len,
			     int *req_cred)
{
	*req_cred = (len > target->tgt_cred_sz) ?
		     DIV_ROUND_UP(len, target->tgt_cred_sz) : 1;

	ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit check need %d got %d\n",
		   *req_cred, ep->cred_dist.credits);

	if (ep->cred_dist.credits < *req_cred) {
		if (eid == ENDPOINT_0)
			return -EINVAL;

		/* Seek more credits */
		ep->cred_dist.seek_cred = *req_cred - ep->cred_dist.credits;

		ath6kl_credit_seek(target->credit_info, &ep->cred_dist);

		ep->cred_dist.seek_cred = 0;

		if (ep->cred_dist.credits < *req_cred) {
			ath6kl_dbg(ATH6KL_DBG_CREDIT,
				   "credit not found for ep %d\n",
				   eid);
			return -EINVAL;
		}
	}

	ep->cred_dist.credits -= *req_cred;
	ep->ep_st.cred_cosumd += *req_cred;

	 /* When we are getting low on credits, ask for more */
	if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
		ep->cred_dist.seek_cred =
		ep->cred_dist.cred_per_msg - ep->cred_dist.credits;

		ath6kl_credit_seek(target->credit_info, &ep->cred_dist);

		/* see if we were successful in getting more */
		if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
			/* tell the target we need credits ASAP! */
			*flags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
			ep->ep_st.cred_low_indicate += 1;
			ath6kl_dbg(ATH6KL_DBG_CREDIT,
				   "credit we need credits asap\n");
		}
	}

	return 0;
}

static void ath6kl_htc_tx_pkts_get(struct htc_target *target,
				   struct htc_endpoint *endpoint,
				   struct list_head *queue)
{
	int req_cred;
	u8 flags;
	struct htc_packet *packet;
	unsigned int len;

	while (true) {
		flags = 0;

		if (list_empty(&endpoint->txq))
			break;
		packet = list_first_entry(&endpoint->txq, struct htc_packet,
					  list);

		ath6kl_dbg(ATH6KL_DBG_HTC,
			   "htc tx got packet 0x%p queue depth %d\n",
			   packet, get_queue_depth(&endpoint->txq));

		len = CALC_TXRX_PADDED_LEN(target,
					   packet->act_len + HTC_HDR_LENGTH);

		if (htc_check_credits(target, endpoint, &flags,
				      packet->endpoint, len, &req_cred))
			break;

		/* now we can fully move onto caller's queue */
		packet = list_first_entry(&endpoint->txq, struct htc_packet,
					  list);
		list_move_tail(&packet->list, queue);

		/* save the number of credits this packet consumed */
		packet->info.tx.cred_used = req_cred;

		/* all TX packets are handled asynchronously */
		packet->completion = htc_tx_comp_handler;
		packet->context = target;
		endpoint->ep_st.tx_issued += 1;

		/* save send flags */
		packet->info.tx.flags = flags;
		packet->info.tx.seqno = endpoint->seqno;
		endpoint->seqno++;
	}
}

/* See if the padded tx length falls on a credit boundary */
static int htc_get_credit_padding(unsigned int cred_sz, int *len,
				  struct htc_endpoint *ep)
{
	int rem_cred, cred_pad;

	rem_cred = *len % cred_sz;

	/* No padding needed */
	if  (!rem_cred)
		return 0;

	if (!(ep->conn_flags & HTC_FLGS_TX_BNDL_PAD_EN))
		return -1;

	/*
	 * The transfer consumes a "partial" credit, this
	 * packet cannot be bundled unless we add
	 * additional "dummy" padding (max 255 bytes) to
	 * consume the entire credit.
	 */
	cred_pad = *len < cred_sz ? (cred_sz - *len) : rem_cred;

	if ((cred_pad > 0) && (cred_pad <= 255))
		*len += cred_pad;
	else
		/* The amount of padding is too large, send as non-bundled */
		return -1;

	return cred_pad;
}

static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target,
					 struct htc_endpoint *endpoint,
					 struct hif_scatter_req *scat_req,
					 int n_scat,
					 struct list_head *queue)
{
	struct htc_packet *packet;
	int i, len, rem_scat, cred_pad;
	int status = 0;
	u8 flags;

	rem_scat = target->max_tx_bndl_sz;

	for (i = 0; i < n_scat; i++) {
		scat_req->scat_list[i].packet = NULL;

		if (list_empty(queue))
			break;

		packet = list_first_entry(queue, struct htc_packet, list);
		len = CALC_TXRX_PADDED_LEN(target,
					   packet->act_len + HTC_HDR_LENGTH);

		cred_pad = htc_get_credit_padding(target->tgt_cred_sz,
						  &len, endpoint);
		if (cred_pad < 0 || rem_scat < len) {
			status = -ENOSPC;
			break;
		}

		rem_scat -= len;
		/* now remove it from the queue */
		list_del(&packet->list);

		scat_req->scat_list[i].packet = packet;
		/* prepare packet and flag message as part of a send bundle */
		flags = packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE;
		ath6kl_htc_tx_prep_pkt(packet, flags,
				       cred_pad, packet->info.tx.seqno);
		/* Make sure the buffer is 4-byte aligned */
		ath6kl_htc_tx_buf_align(&packet->buf,
					packet->act_len + HTC_HDR_LENGTH);
		scat_req->scat_list[i].buf = packet->buf;
		scat_req->scat_list[i].len = len;

		scat_req->len += len;
		scat_req->scat_entries++;
		ath6kl_dbg(ATH6KL_DBG_HTC,
			   "htc tx adding (%d) pkt 0x%p seqno %d len %d remaining %d\n",
			   i, packet, packet->info.tx.seqno, len, rem_scat);
	}

	/* Roll back scatter setup in case of any failure */
	if (scat_req->scat_entries < HTC_MIN_HTC_MSGS_TO_BUNDLE) {
		for (i = scat_req->scat_entries - 1; i >= 0; i--) {
			packet = scat_req->scat_list[i].packet;
			if (packet) {
				packet->buf += HTC_HDR_LENGTH;
				list_add(&packet->list, queue);
			}
		}
		return -EAGAIN;
	}

	return status;
}

/*
 * Drain a queue and send as bundles this function may return without fully
 * draining the queue when
 *
 *    1. scatter resources are exhausted
 *    2. a message that will consume a partial credit will stop the
 *    bundling process early
 *    3. we drop below the minimum number of messages for a bundle
 */
static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
				 struct list_head *queue,
				 int *sent_bundle, int *n_bundle_pkts)
{
	struct htc_target *target = endpoint->target;
	struct hif_scatter_req *scat_req = NULL;
	int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0, i;
	struct htc_packet *packet;
	int status;
	u32 txb_mask;
	u8 ac = WMM_NUM_AC;

	if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) &&
	    (WMI_CONTROL_SVC != endpoint->svc_id))
		ac = target->dev->ar->ep2ac_map[endpoint->eid];

	while (true) {
		status = 0;
		n_scat = get_queue_depth(queue);
		n_scat = min(n_scat, target->msg_per_bndl_max);

		if (n_scat < HTC_MIN_HTC_MSGS_TO_BUNDLE)
			/* not enough to bundle */
			break;

		scat_req = hif_scatter_req_get(target->dev->ar);

		if (!scat_req) {
			/* no scatter resources  */
			ath6kl_dbg(ATH6KL_DBG_HTC,
				   "htc tx no more scatter resources\n");
			break;
		}

		if ((ac < WMM_NUM_AC) && (ac != WMM_AC_BK)) {
			if (WMM_AC_BE == ac)
				/*
				 * BE, BK have priorities and bit
				 * positions reversed
				 */
				txb_mask = (1 << WMM_AC_BK);
			else
				/*
				 * any AC with priority lower than
				 * itself
				 */
				txb_mask = ((1 << ac) - 1);

			/*
			 * when the scatter request resources drop below a
			 * certain threshold, disable Tx bundling for all
			 * AC's with priority lower than the current requesting
			 * AC. Otherwise re-enable Tx bundling for them
			 */
			if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS)
				target->tx_bndl_mask &= ~txb_mask;
			else
				target->tx_bndl_mask |= txb_mask;
		}

		ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n",
			   n_scat);

		scat_req->len = 0;
		scat_req->scat_entries = 0;

		status = ath6kl_htc_tx_setup_scat_list(target, endpoint,
						       scat_req, n_scat,
						       queue);
		if (status == -EAGAIN) {
			hif_scatter_req_add(target->dev->ar, scat_req);
			break;
		}

		/* send path is always asynchronous */
		scat_req->complete = htc_async_tx_scat_complete;
		n_sent_bundle++;
		tot_pkts_bundle += scat_req->scat_entries;

		ath6kl_dbg(ATH6KL_DBG_HTC,
			   "htc tx scatter bytes %d entries %d\n",
			   scat_req->len, scat_req->scat_entries);

		for (i = 0; i < scat_req->scat_entries; i++) {
			packet = scat_req->scat_list[i].packet;
			trace_ath6kl_htc_tx(packet->status, packet->endpoint,
					    packet->buf, packet->act_len);
		}

		ath6kl_hif_submit_scat_req(target->dev, scat_req, false);

		if (status)
			break;
	}

	*sent_bundle = n_sent_bundle;
	*n_bundle_pkts = tot_pkts_bundle;
	ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx bundle sent %d pkts\n",
		   n_sent_bundle);

	return;
}

static void ath6kl_htc_tx_from_queue(struct htc_target *target,
				     struct htc_endpoint *endpoint)
{
	struct list_head txq;
	struct htc_packet *packet;
	int bundle_sent;
	int n_pkts_bundle;
	u8 ac = WMM_NUM_AC;
	int status;

	spin_lock_bh(&target->tx_lock);

	endpoint->tx_proc_cnt++;
	if (endpoint->tx_proc_cnt > 1) {
		endpoint->tx_proc_cnt--;
		spin_unlock_bh(&target->tx_lock);
		ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx busy\n");
		return;
	}

	/*
	 * drain the endpoint TX queue for transmission as long
	 * as we have enough credits.
	 */
	INIT_LIST_HEAD(&txq);

	if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) &&
	    (WMI_CONTROL_SVC != endpoint->svc_id))
		ac = target->dev->ar->ep2ac_map[endpoint->eid];

	while (true) {
		if (list_empty(&endpoint->txq))
			break;

		ath6kl_htc_tx_pkts_get(target, endpoint, &txq);

		if (list_empty(&txq))
			break;

		spin_unlock_bh(&target->tx_lock);

		bundle_sent = 0;
		n_pkts_bundle = 0;

		while (true) {
			/* try to send a bundle on each pass */
			if ((target->tx_bndl_mask) &&
			    (get_queue_depth(&txq) >=
			    HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
				int temp1 = 0, temp2 = 0;

				/* check if bundling is enabled for an AC */
				if (target->tx_bndl_mask & (1 << ac)) {
					ath6kl_htc_tx_bundle(endpoint, &txq,
							     &temp1, &temp2);
					bundle_sent += temp1;
					n_pkts_bundle += temp2;
				}
			}

			if (list_empty(&txq))
				break;

			packet = list_first_entry(&txq, struct htc_packet,
						  list);
			list_del(&packet->list);

			ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags,
					       0, packet->info.tx.seqno);
			status = ath6kl_htc_tx_issue(target, packet);

			if (status) {
				packet->status = status;
				packet->completion(packet->context, packet);
			}
		}

		spin_lock_bh(&target->tx_lock);

		endpoint->ep_st.tx_bundles += bundle_sent;
		endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle;

		/*
		 * if an AC has bundling disabled and no tx bundling
		 * has occured continously for a certain number of TX,
		 * enable tx bundling for this AC
		 */
		if (!bundle_sent) {
			if (!(target->tx_bndl_mask & (1 << ac)) &&
			    (ac < WMM_NUM_AC)) {
				if (++target->ac_tx_count[ac] >=
					TX_RESUME_BUNDLE_THRESHOLD) {
					target->ac_tx_count[ac] = 0;
					target->tx_bndl_mask |= (1 << ac);
				}
			}
		} else {
			/* tx bundling will reset the counter */
			if (ac < WMM_NUM_AC)
				target->ac_tx_count[ac] = 0;
		}
	}

	endpoint->tx_proc_cnt = 0;
	spin_unlock_bh(&target->tx_lock);
}

static bool ath6kl_htc_tx_try(struct htc_target *target,
			      struct htc_endpoint *endpoint,
			      struct htc_packet *tx_pkt)
{
	struct htc_ep_callbacks ep_cb;
	int txq_depth;
	bool overflow = false;

	ep_cb = endpoint->ep_cb;

	spin_lock_bh(&target->tx_lock);
	txq_depth = get_queue_depth(&endpoint->txq);
	spin_unlock_bh(&target->tx_lock);

	if (txq_depth >= endpoint->max_txq_depth)
		overflow = true;

	if (overflow)
		ath6kl_dbg(ATH6KL_DBG_HTC,
			   "htc tx overflow ep %d depth %d max %d\n",
			   endpoint->eid, txq_depth,
			   endpoint->max_txq_depth);

	if (overflow && ep_cb.tx_full) {
		if (ep_cb.tx_full(endpoint->target, tx_pkt) ==
		    HTC_SEND_FULL_DROP) {
			endpoint->ep_st.tx_dropped += 1;
			return false;
		}
	}

	spin_lock_bh(&target->tx_lock);
	list_add_tail(&tx_pkt->list, &endpoint->txq);
	spin_unlock_bh(&target->tx_lock);

	ath6kl_htc_tx_from_queue(target, endpoint);

	return true;
}

static void htc_chk_ep_txq(struct htc_target *target)
{
	struct htc_endpoint *endpoint;
	struct htc_endpoint_credit_dist *cred_dist;

	/*
	 * Run through the credit distribution list to see if there are
	 * packets queued. NOTE: no locks need to be taken since the
	 * distribution list is not dynamic (cannot be re-ordered) and we
	 * are not modifying any state.
	 */
	list_for_each_entry(cred_dist, &target->cred_dist_list, list) {
		endpoint = cred_dist->htc_ep;

		spin_lock_bh(&target->tx_lock);
		if (!list_empty(&endpoint->txq)) {
			ath6kl_dbg(ATH6KL_DBG_HTC,
				   "htc creds ep %d credits %d pkts %d\n",
				   cred_dist->endpoint,
				   endpoint->cred_dist.credits,
				   get_queue_depth(&endpoint->txq));
			spin_unlock_bh(&target->tx_lock);
			/*
			 * Try to start the stalled queue, this list is
			 * ordered by priority. If there are credits
			 * available the highest priority queue will get a
			 * chance to reclaim credits from lower priority
			 * ones.
			 */
			ath6kl_htc_tx_from_queue(target, endpoint);
			spin_lock_bh(&target->tx_lock);
		}
		spin_unlock_bh(&target->tx_lock);
	}
}

static int htc_setup_tx_complete(struct htc_target *target)
{
	struct htc_packet *send_pkt = NULL;
	int status;

	send_pkt = htc_get_control_buf(target, true);

	if (!send_pkt)
		return -ENOMEM;

	if (target->htc_tgt_ver >= HTC_VERSION_2P1) {
		struct htc_setup_comp_ext_msg *setup_comp_ext;
		u32 flags = 0;

		setup_comp_ext =
		    (struct htc_setup_comp_ext_msg *)send_pkt->buf;
		memset(setup_comp_ext, 0, sizeof(*setup_comp_ext));
		setup_comp_ext->msg_id =
			cpu_to_le16(HTC_MSG_SETUP_COMPLETE_EX_ID);

		if (target->msg_per_bndl_max > 0) {
			/* Indicate HTC bundling to the target */
			flags |= HTC_SETUP_COMP_FLG_RX_BNDL_EN;
			setup_comp_ext->msg_per_rxbndl =
						target->msg_per_bndl_max;
		}

		memcpy(&setup_comp_ext->flags, &flags,
		       sizeof(setup_comp_ext->flags));
		set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext,
				 sizeof(struct htc_setup_comp_ext_msg),
				 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);

	} else {
		struct htc_setup_comp_msg *setup_comp;
		setup_comp = (struct htc_setup_comp_msg *)send_pkt->buf;
		memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg));
		setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID);
		set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp,
				 sizeof(struct htc_setup_comp_msg),
				 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
	}

	/* we want synchronous operation */
	send_pkt->completion = NULL;
	ath6kl_htc_tx_prep_pkt(send_pkt, 0, 0, 0);
	status = ath6kl_htc_tx_issue(target, send_pkt);

	if (send_pkt != NULL)
		htc_reclaim_txctrl_buf(target, send_pkt);

	return status;
}

static void ath6kl_htc_set_credit_dist(struct htc_target *target,
				struct ath6kl_htc_credit_info *credit_info,
				u16 srvc_pri_order[], int list_len)
{
	struct htc_endpoint *endpoint;
	int i, ep;

	target->credit_info = credit_info;

	list_add_tail(&target->endpoint[ENDPOINT_0].cred_dist.list,
		      &target->cred_dist_list);

	for (i = 0; i < list_len; i++) {
		for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
			endpoint = &target->endpoint[ep];
			if (endpoint->svc_id == srvc_pri_order[i]) {
				list_add_tail(&endpoint->cred_dist.list,
					      &target->cred_dist_list);
				break;
			}
		}
		if (ep >= ENDPOINT_MAX) {
			WARN_ON(1);
			return;
		}
	}
}

static int ath6kl_htc_mbox_tx(struct htc_target *target,
			      struct htc_packet *packet)
{
	struct htc_endpoint *endpoint;
	struct list_head queue;

	ath6kl_dbg(ATH6KL_DBG_HTC,
		   "htc tx ep id %d buf 0x%p len %d\n",
		   packet->endpoint, packet->buf, packet->act_len);

	if (packet->endpoint >= ENDPOINT_MAX) {
		WARN_ON(1);
		return -EINVAL;
	}

	endpoint = &target->endpoint[packet->endpoint];

	if (!ath6kl_htc_tx_try(target, endpoint, packet)) {
		packet->status = (target->htc_flags & HTC_OP_STATE_STOPPING) ?
				 -ECANCELED : -ENOSPC;
		INIT_LIST_HEAD(&queue);
		list_add(&packet->list, &queue);
		htc_tx_complete(endpoint, &queue);
	}

	return 0;
}

/* flush endpoint TX queue */
static void ath6kl_htc_mbox_flush_txep(struct htc_target *target,
			   enum htc_endpoint_id eid, u16 tag)
{
	struct htc_packet *packet, *tmp_pkt;
	struct list_head discard_q, container;
	struct htc_endpoint *endpoint = &target->endpoint[eid];

	if (!endpoint->svc_id) {
		WARN_ON(1);
		return;
	}

	/* initialize the discard queue */
	INIT_LIST_HEAD(&discard_q);

	spin_lock_bh(&target->tx_lock);

	list_for_each_entry_safe(packet, tmp_pkt, &endpoint->txq, list) {
		if ((tag == HTC_TX_PACKET_TAG_ALL) ||
		    (tag == packet->info.tx.tag))
			list_move_tail(&packet->list, &discard_q);
	}

	spin_unlock_bh(&target->tx_lock);

	list_for_each_entry_safe(packet, tmp_pkt, &discard_q, list) {
		packet->status = -ECANCELED;
		list_del(&packet->list);
		ath6kl_dbg(ATH6KL_DBG_HTC,
			   "htc tx flushing pkt 0x%p len %d  ep %d tag 0x%x\n",
			   packet, packet->act_len,
			   packet->endpoint, packet->info.tx.tag);

		INIT_LIST_HEAD(&container);
		list_add_tail(&packet->list, &container);
		htc_tx_complete(endpoint, &container);
	}
}

static void ath6kl_htc_flush_txep_all(struct htc_target *target)
{
	struct htc_endpoint *endpoint;
	int i;

	dump_cred_dist_stats(target);

	for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
		endpoint = &target->endpoint[i];
		if (endpoint->svc_id == 0)
			/* not in use.. */
			continue;
		ath6kl_htc_mbox_flush_txep(target, i, HTC_TX_PACKET_TAG_ALL);
	}
}

static void ath6kl_htc_mbox_activity_changed(struct htc_target *target,
					     enum htc_endpoint_id eid,
					     bool active)
{
	struct htc_endpoint *endpoint = &target->endpoint[eid];
	bool dist = false;

	if (endpoint->svc_id == 0) {
		WARN_ON(1);
		return;
	}

	spin_lock_bh(&target->tx_lock);

	if (active) {
		if (!(endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE)) {
			endpoint->cred_dist.dist_flags |= HTC_EP_ACTIVE;
			dist = true;
		}
	} else {
		if (endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE) {
			endpoint->cred_dist.dist_flags &= ~HTC_EP_ACTIVE;
			dist = true;
		}
	}

	if (dist) {
		endpoint->cred_dist.txq_depth =
			get_queue_depth(&endpoint->txq);

		ath6kl_dbg(ATH6KL_DBG_HTC,
			   "htc tx activity ctxt 0x%p dist 0x%p\n",
			   target->credit_info, &target->cred_dist_list);

		ath6kl_credit_distribute(target->credit_info,
					 &target->cred_dist_list,
					 HTC_CREDIT_DIST_ACTIVITY_CHANGE);
	}

	spin_unlock_bh(&target->tx_lock);

	if (dist && !active)
		htc_chk_ep_txq(target);
}

/* HTC Rx */

static inline void ath6kl_htc_rx_update_stats(struct htc_endpoint *endpoint,
					      int n_look_ahds)
{
	endpoint->ep_st.rx_pkts++;
	if (n_look_ahds == 1)
		endpoint->ep_st.rx_lkahds++;
	else if (n_look_ahds > 1)
		endpoint->ep_st.rx_bundle_lkahd++;
}

static inline bool htc_valid_rx_frame_len(struct htc_target *target,
					  enum htc_endpoint_id eid, int len)
{
	return (eid == target->dev->ar->ctrl_ep) ?
		len <= ATH6KL_BUFFER_SIZE : len <= ATH6KL_AMSDU_BUFFER_SIZE;
}

static int htc_add_rxbuf(struct htc_target *target, struct htc_packet *packet)
{
	struct list_head queue;

	INIT_LIST_HEAD(&queue);
	list_add_tail(&packet->list, &queue);
	return ath6kl_htc_mbox_add_rxbuf_multiple(target, &queue);
}

static void htc_reclaim_rxbuf(struct htc_target *target,
			      struct htc_packet *packet,
			      struct htc_endpoint *ep)
{
	if (packet->info.rx.rx_flags & HTC_RX_PKT_NO_RECYCLE) {
		htc_rxpkt_reset(packet);
		packet->status = -ECANCELED;
		ep->ep_cb.rx(ep->target, packet);
	} else {
		htc_rxpkt_reset(packet);
		htc_add_rxbuf((void *)(target), packet);
	}
}

static void reclaim_rx_ctrl_buf(struct htc_target *target,
				struct htc_packet *packet)
{
	spin_lock_bh(&target->htc_lock);
	list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
	spin_unlock_bh(&target->htc_lock);
}

static int ath6kl_htc_rx_packet(struct htc_target *target,
				struct htc_packet *packet,
				u32 rx_len)
{
	struct ath6kl_device *dev = target->dev;
	u32 padded_len;
	int status;

	padded_len = CALC_TXRX_PADDED_LEN(target, rx_len);

	if (padded_len > packet->buf_len) {
		ath6kl_err("not enough receive space for packet - padlen %d recvlen %d bufferlen %d\n",
			   padded_len, rx_len, packet->buf_len);
		return -ENOMEM;
	}

	ath6kl_dbg(ATH6KL_DBG_HTC,
		   "htc rx 0x%p hdr 0x%x len %d mbox 0x%x\n",
		   packet, packet->info.rx.exp_hdr,
		   padded_len, dev->ar->mbox_info.htc_addr);

	status = hif_read_write_sync(dev->ar,
				     dev->ar->mbox_info.htc_addr,
				     packet->buf, padded_len,
				     HIF_RD_SYNC_BLOCK_FIX);

	packet->status = status;

	return status;
}

/*
 * optimization for recv packets, we can indicate a
 * "hint" that there are more  single-packets to fetch
 * on this endpoint.
 */
static void ath6kl_htc_rx_set_indicate(u32 lk_ahd,
				       struct htc_endpoint *endpoint,
				       struct htc_packet *packet)
{
	struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)&lk_ahd;

	if (htc_hdr->eid == packet->endpoint) {
		if (!list_empty(&endpoint->rx_bufq))
			packet->info.rx.indicat_flags |=
					HTC_RX_FLAGS_INDICATE_MORE_PKTS;
	}
}

static void ath6kl_htc_rx_chk_water_mark(struct htc_endpoint *endpoint)
{
	struct htc_ep_callbacks ep_cb = endpoint->ep_cb;

	if (ep_cb.rx_refill_thresh > 0) {
		spin_lock_bh(&endpoint->target->rx_lock);
		if (get_queue_depth(&endpoint->rx_bufq)
		    < ep_cb.rx_refill_thresh) {
			spin_unlock_bh(&endpoint->target->rx_lock);
			ep_cb.rx_refill(endpoint->target, endpoint->eid);
			return;
		}
		spin_unlock_bh(&endpoint->target->rx_lock);
	}
}

/* This function is called with rx_lock held */
static int ath6kl_htc_rx_setup(struct htc_target *target,
			       struct htc_endpoint *ep,
			       u32 *lk_ahds, struct list_head *queue, int n_msg)
{
	struct htc_packet *packet;
	/* FIXME: type of lk_ahds can't be right */
	struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)lk_ahds;
	struct htc_ep_callbacks ep_cb;
	int status = 0, j, full_len;
	bool no_recycle;

	full_len = CALC_TXRX_PADDED_LEN(target,
					le16_to_cpu(htc_hdr->payld_len) +
					sizeof(*htc_hdr));

	if (!htc_valid_rx_frame_len(target, ep->eid, full_len)) {
		ath6kl_warn("Rx buffer requested with invalid length htc_hdr:eid %d, flags 0x%x, len %d\n",
			    htc_hdr->eid, htc_hdr->flags,
			    le16_to_cpu(htc_hdr->payld_len));
		return -EINVAL;
	}

	ep_cb = ep->ep_cb;
	for (j = 0; j < n_msg; j++) {
		/*
		 * Reset flag, any packets allocated using the
		 * rx_alloc() API cannot be recycled on
		 * cleanup,they must be explicitly returned.
		 */
		no_recycle = false;

		if (ep_cb.rx_allocthresh &&
		    (full_len > ep_cb.rx_alloc_thresh)) {
			ep->ep_st.rx_alloc_thresh_hit += 1;
			ep->ep_st.rxalloc_thresh_byte +=
				le16_to_cpu(htc_hdr->payld_len);

			spin_unlock_bh(&target->rx_lock);
			no_recycle = true;

			packet = ep_cb.rx_allocthresh(ep->target, ep->eid,
						      full_len);
			spin_lock_bh(&target->rx_lock);
		} else {
			/* refill handler is being used */
			if (list_empty(&ep->rx_bufq)) {
				if (ep_cb.rx_refill) {
					spin_unlock_bh(&target->rx_lock);
					ep_cb.rx_refill(ep->target, ep->eid);
					spin_lock_bh(&target->rx_lock);
				}
			}

			if (list_empty(&ep->rx_bufq)) {
				packet = NULL;
			} else {
				packet = list_first_entry(&ep->rx_bufq,
						struct htc_packet, list);
				list_del(&packet->list);
			}
		}

		if (!packet) {
			target->rx_st_flags |= HTC_RECV_WAIT_BUFFERS;
			target->ep_waiting = ep->eid;
			return -ENOSPC;
		}

		/* clear flags */
		packet->info.rx.rx_flags = 0;
		packet->info.rx.indicat_flags = 0;
		packet->status = 0;

		if (no_recycle)
			/*
			 * flag that these packets cannot be
			 * recycled, they have to be returned to
			 * the user
			 */
			packet->info.rx.rx_flags |= HTC_RX_PKT_NO_RECYCLE;

		/* Caller needs to free this upon any failure */
		list_add_tail(&packet->list, queue);

		if (target->htc_flags & HTC_OP_STATE_STOPPING) {
			status = -ECANCELED;
			break;
		}

		if (j) {
			packet->info.rx.rx_flags |= HTC_RX_PKT_REFRESH_HDR;
			packet->info.rx.exp_hdr = 0xFFFFFFFF;
		} else
			/* set expected look ahead */
			packet->info.rx.exp_hdr = *lk_ahds;

		packet->act_len = le16_to_cpu(htc_hdr->payld_len) +
			HTC_HDR_LENGTH;
	}

	return status;
}

static int ath6kl_htc_rx_alloc(struct htc_target *target,
			       u32 lk_ahds[], int msg,
			       struct htc_endpoint *endpoint,
			       struct list_head *queue)
{
	int status = 0;
	struct htc_packet *packet, *tmp_pkt;
	struct htc_frame_hdr *htc_hdr;
	int i, n_msg;

	spin_lock_bh(&target->rx_lock);

	for (i = 0; i < msg; i++) {
		htc_hdr = (struct htc_frame_hdr *)&lk_ahds[i];

		if (htc_hdr->eid >= ENDPOINT_MAX) {
			ath6kl_err("invalid ep in look-ahead: %d\n",
				   htc_hdr->eid);
			status = -ENOMEM;
			break;
		}

		if (htc_hdr->eid != endpoint->eid) {
			ath6kl_err("invalid ep in look-ahead: %d should be : %d (index:%d)\n",
				   htc_hdr->eid, endpoint->eid, i);
			status = -ENOMEM;
			break;
		}

		if (le16_to_cpu(htc_hdr->payld_len) > HTC_MAX_PAYLOAD_LENGTH) {
			ath6kl_err("payload len %d exceeds max htc : %d !\n",
				   htc_hdr->payld_len,
				   (u32) HTC_MAX_PAYLOAD_LENGTH);
			status = -ENOMEM;
			break;
		}

		if (endpoint->svc_id == 0) {
			ath6kl_err("ep %d is not connected !\n", htc_hdr->eid);
			status = -ENOMEM;
			break;
		}

		if (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) {
			/*
			 * HTC header indicates that every packet to follow
			 * has the same padded length so that it can be
			 * optimally fetched as a full bundle.
			 */
			n_msg = (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) >>
				HTC_FLG_RX_BNDL_CNT_S;

			/* the count doesn't include the starter frame */
			n_msg++;
			if (n_msg > target->msg_per_bndl_max) {
				status = -ENOMEM;
				break;
			}

			endpoint->ep_st.rx_bundle_from_hdr += 1;
			ath6kl_dbg(ATH6KL_DBG_HTC,
				   "htc rx bundle pkts %d\n",
				   n_msg);
		} else
			/* HTC header only indicates 1 message to fetch */
			n_msg = 1;

		/* Setup packet buffers for each message */
		status = ath6kl_htc_rx_setup(target, endpoint, &lk_ahds[i],
					     queue, n_msg);

		/*
		 * This is due to unavailabilty of buffers to rx entire data.
		 * Return no error so that free buffers from queue can be used
		 * to receive partial data.
		 */
		if (status == -ENOSPC) {
			spin_unlock_bh(&target->rx_lock);
			return 0;
		}

		if (status)
			break;
	}

	spin_unlock_bh(&target->rx_lock);

	if (status) {
		list_for_each_entry_safe(packet, tmp_pkt, queue, list) {
			list_del(&packet->list);
			htc_reclaim_rxbuf(target, packet,
					  &target->endpoint[packet->endpoint]);
		}
	}

	return status;
}

static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets)
{
	if (packets->endpoint != ENDPOINT_0) {
		WARN_ON(1);
		return;
	}

	if (packets->status == -ECANCELED) {
		reclaim_rx_ctrl_buf(context, packets);
		return;
	}

	if (packets->act_len > 0) {
		ath6kl_err("htc_ctrl_rx, got message with len:%zu\n",
			   packets->act_len + HTC_HDR_LENGTH);

		ath6kl_dbg_dump(ATH6KL_DBG_HTC,
				"htc rx unexpected endpoint 0 message", "",
				packets->buf - HTC_HDR_LENGTH,
				packets->act_len + HTC_HDR_LENGTH);
	}

	htc_reclaim_rxbuf(context, packets, &context->endpoint[0]);
}

static void htc_proc_cred_rpt(struct htc_target *target,
			      struct htc_credit_report *rpt,
			      int n_entries,
			      enum htc_endpoint_id from_ep)
{
	struct htc_endpoint *endpoint;
	int tot_credits = 0, i;
	bool dist = false;

	spin_lock_bh(&target->tx_lock);

	for (i = 0; i < n_entries; i++, rpt++) {
		if (rpt->eid >= ENDPOINT_MAX) {
			WARN_ON(1);
			spin_unlock_bh(&target->tx_lock);
			return;
		}

		endpoint = &target->endpoint[rpt->eid];

		ath6kl_dbg(ATH6KL_DBG_CREDIT,
			   "credit report ep %d credits %d\n",
			   rpt->eid, rpt->credits);

		endpoint->ep_st.tx_cred_rpt += 1;
		endpoint->ep_st.cred_retnd += rpt->credits;

		if (from_ep == rpt->eid) {
			/*
			 * This credit report arrived on the same endpoint
			 * indicating it arrived in an RX packet.
			 */
			endpoint->ep_st.cred_from_rx += rpt->credits;
			endpoint->ep_st.cred_rpt_from_rx += 1;
		} else if (from_ep == ENDPOINT_0) {
			/* credit arrived on endpoint 0 as a NULL message */
			endpoint->ep_st.cred_from_ep0 += rpt->credits;
			endpoint->ep_st.cred_rpt_ep0 += 1;
		} else {
			endpoint->ep_st.cred_from_other += rpt->credits;
			endpoint->ep_st.cred_rpt_from_other += 1;
		}

		if (rpt->eid == ENDPOINT_0)
			/* always give endpoint 0 credits back */
			endpoint->cred_dist.credits += rpt->credits;
		else {
			endpoint->cred_dist.cred_to_dist += rpt->credits;
			dist = true;
		}

		/*
		 * Refresh tx depth for distribution function that will
		 * recover these credits NOTE: this is only valid when
		 * there are credits to recover!
		 */
		endpoint->cred_dist.txq_depth =
			get_queue_depth(&endpoint->txq);

		tot_credits += rpt->credits;
	}

	if (dist) {
		/*
		 * This was a credit return based on a completed send
		 * operations note, this is done with the lock held
		 */
		ath6kl_credit_distribute(target->credit_info,
					 &target->cred_dist_list,
					 HTC_CREDIT_DIST_SEND_COMPLETE);
	}

	spin_unlock_bh(&target->tx_lock);

	if (tot_credits)
		htc_chk_ep_txq(target);
}

static int htc_parse_trailer(struct htc_target *target,
			     struct htc_record_hdr *record,
			     u8 *record_buf, u32 *next_lk_ahds,
			     enum htc_endpoint_id endpoint,
			     int *n_lk_ahds)
{
	struct htc_bundle_lkahd_rpt *bundle_lkahd_rpt;
	struct htc_lookahead_report *lk_ahd;
	int len;

	switch (record->rec_id) {
	case HTC_RECORD_CREDITS:
		len = record->len / sizeof(struct htc_credit_report);
		if (!len) {
			WARN_ON(1);
			return -EINVAL;
		}

		htc_proc_cred_rpt(target,
				  (struct htc_credit_report *) record_buf,
				  len, endpoint);
		break;
	case HTC_RECORD_LOOKAHEAD:
		len = record->len / sizeof(*lk_ahd);
		if (!len) {
			WARN_ON(1);
			return -EINVAL;
		}

		lk_ahd = (struct htc_lookahead_report *) record_buf;
		if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) &&
		    next_lk_ahds) {
			ath6kl_dbg(ATH6KL_DBG_HTC,
				   "htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n",
				   lk_ahd->pre_valid, lk_ahd->post_valid);

			/* look ahead bytes are valid, copy them over */
			memcpy((u8 *)&next_lk_ahds[0], lk_ahd->lk_ahd, 4);

			ath6kl_dbg_dump(ATH6KL_DBG_HTC,
					"htc rx next look ahead",
					"", next_lk_ahds, 4);

			*n_lk_ahds = 1;
		}
		break;
	case HTC_RECORD_LOOKAHEAD_BUNDLE:
		len = record->len / sizeof(*bundle_lkahd_rpt);
		if (!len || (len > HTC_HOST_MAX_MSG_PER_BUNDLE)) {
			WARN_ON(1);
			return -EINVAL;
		}

		if (next_lk_ahds) {
			int i;

			bundle_lkahd_rpt =
				(struct htc_bundle_lkahd_rpt *) record_buf;

			ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx bundle lk_ahd",
					"", record_buf, record->len);

			for (i = 0; i < len; i++) {
				memcpy((u8 *)&next_lk_ahds[i],
				       bundle_lkahd_rpt->lk_ahd, 4);
				bundle_lkahd_rpt++;
			}

			*n_lk_ahds = i;
		}
		break;
	default:
		ath6kl_err("unhandled record: id:%d len:%d\n",
			   record->rec_id, record->len);
		break;
	}

	return 0;
}

static int htc_proc_trailer(struct htc_target *target,
			    u8 *buf, int len, u32 *next_lk_ahds,
			    int *n_lk_ahds, enum htc_endpoint_id endpoint)
{
	struct htc_record_hdr *record;
	int orig_len;
	int status;
	u8 *record_buf;
	u8 *orig_buf;

	ath6kl_dbg(ATH6KL_DBG_HTC, "htc rx trailer len %d\n", len);
	ath6kl_dbg_dump(ATH6KL_DBG_HTC, NULL, "", buf, len);

	orig_buf = buf;
	orig_len = len;
	status = 0;

	while (len > 0) {
		if (len < sizeof(struct htc_record_hdr)) {
			status = -ENOMEM;
			break;
		}
		/* these are byte aligned structs */
		record = (struct htc_record_hdr *) buf;
		len -= sizeof(struct htc_record_hdr);
		buf += sizeof(struct htc_record_hdr);

		if (record->len > len) {
			ath6kl_err("invalid record len: %d (id:%d) buf has: %d bytes left\n",
				   record->len, record->rec_id, len);
			status = -ENOMEM;
			break;
		}
		record_buf = buf;

		status = htc_parse_trailer(target, record, record_buf,
					   next_lk_ahds, endpoint, n_lk_ahds);

		if (status)
			break;

		/* advance buffer past this record for next time around */
		buf += record->len;
		len -= record->len;
	}

	if (status)
		ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx bad trailer",
				"", orig_buf, orig_len);

	return status;
}

static int ath6kl_htc_rx_process_hdr(struct htc_target *target,
				     struct htc_packet *packet,
				     u32 *next_lkahds, int *n_lkahds)
{
	int status = 0;
	u16 payload_len;
	u32 lk_ahd;
	struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)packet->buf;

	if (n_lkahds != NULL)
		*n_lkahds = 0;

	/*
	 * NOTE: we cannot assume the alignment of buf, so we use the safe
	 * macros to retrieve 16 bit fields.
	 */
	payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len));

	memcpy((u8 *)&lk_ahd, packet->buf, sizeof(lk_ahd));

	if (packet->info.rx.rx_flags & HTC_RX_PKT_REFRESH_HDR) {
		/*
		 * Refresh the expected header and the actual length as it
		 * was unknown when this packet was grabbed as part of the
		 * bundle.
		 */
		packet->info.rx.exp_hdr = lk_ahd;
		packet->act_len = payload_len + HTC_HDR_LENGTH;

		/* validate the actual header that was refreshed  */
		if (packet->act_len > packet->buf_len) {
			ath6kl_err("refreshed hdr payload len (%d) in bundled recv is invalid (hdr: 0x%X)\n",
				   payload_len, lk_ahd);
			/*
			 * Limit this to max buffer just to print out some
			 * of the buffer.
			 */
			packet->act_len = min(packet->act_len, packet->buf_len);
			status = -ENOMEM;
			goto fail_rx;
		}

		if (packet->endpoint != htc_hdr->eid) {
			ath6kl_err("refreshed hdr ep (%d) does not match expected ep (%d)\n",
				   htc_hdr->eid, packet->endpoint);
			status = -ENOMEM;
			goto fail_rx;
		}
	}

	if (lk_ahd != packet->info.rx.exp_hdr) {
		ath6kl_err("%s(): lk_ahd mismatch! (pPkt:0x%p flags:0x%X)\n",
			   __func__, packet, packet->info.rx.rx_flags);
		ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx expected lk_ahd",
				"", &packet->info.rx.exp_hdr, 4);
		ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx current header",
				"", (u8 *)&lk_ahd, sizeof(lk_ahd));
		status = -ENOMEM;
		goto fail_rx;
	}

	if (htc_hdr->flags & HTC_FLG_RX_TRAILER) {
		if (htc_hdr->ctrl[0] < sizeof(struct htc_record_hdr) ||
		    htc_hdr->ctrl[0] > payload_len) {
			ath6kl_err("%s(): invalid hdr (payload len should be :%d, CB[0] is:%d)\n",
				   __func__, payload_len, htc_hdr->ctrl[0]);
			status = -ENOMEM;
			goto fail_rx;
		}

		if (packet->info.rx.rx_flags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
			next_lkahds = NULL;
			n_lkahds = NULL;
		}

		status = htc_proc_trailer(target, packet->buf + HTC_HDR_LENGTH
					  + payload_len - htc_hdr->ctrl[0],
					  htc_hdr->ctrl[0], next_lkahds,
					   n_lkahds, packet->endpoint);

		if (status)
			goto fail_rx;

		packet->act_len -= htc_hdr->ctrl[0];
	}

	packet->buf += HTC_HDR_LENGTH;
	packet->act_len -= HTC_HDR_LENGTH;

fail_rx:
	if (status)
		ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx bad packet",
				"", packet->buf, packet->act_len);

	return status;
}

static void ath6kl_htc_rx_complete(struct htc_endpoint *endpoint,
				   struct htc_packet *packet)
{
		ath6kl_dbg(ATH6KL_DBG_HTC,
			   "htc rx complete ep %d packet 0x%p\n",
			   endpoint->eid, packet);

		endpoint->ep_cb.rx(endpoint->target, packet);
}

static int ath6kl_htc_rx_bundle(struct htc_target *target,
				struct list_head *rxq,
				struct list_head *sync_compq,
				int *n_pkt_fetched, bool part_bundle)
{
	struct hif_scatter_req *scat_req;
	struct htc_packet *packet;
	int rem_space = target->max_rx_bndl_sz;
	int n_scat_pkt, status = 0, i, len;

	n_scat_pkt = get_queue_depth(rxq);
	n_scat_pkt = min(n_scat_pkt, target->msg_per_bndl_max);

	if ((get_queue_depth(rxq) - n_scat_pkt) > 0) {
		/*
		 * We were forced to split this bundle receive operation
		 * all packets in this partial bundle must have their
		 * lookaheads ignored.
		 */
		part_bundle = true;

		/*
		 * This would only happen if the target ignored our max
		 * bundle limit.
		 */
		ath6kl_warn("%s(): partial bundle detected num:%d , %d\n",
			    __func__, get_queue_depth(rxq), n_scat_pkt);
	}

	len = 0;

	ath6kl_dbg(ATH6KL_DBG_HTC,
		   "htc rx bundle depth %d pkts %d\n",
		   get_queue_depth(rxq), n_scat_pkt);

	scat_req = hif_scatter_req_get(target->dev->ar);

	if (scat_req == NULL)
		goto fail_rx_pkt;

	for (i = 0; i < n_scat_pkt; i++) {
		int pad_len;

		packet = list_first_entry(rxq, struct htc_packet, list);
		list_del(&packet->list);

		pad_len = CALC_TXRX_PADDED_LEN(target,
						   packet->act_len);

		if ((rem_space - pad_len) < 0) {
			list_add(&packet->list, rxq);
			break;
		}

		rem_space -= pad_len;

		if (part_bundle || (i < (n_scat_pkt - 1)))
			/*
			 * Packet 0..n-1 cannot be checked for look-aheads
			 * since we are fetching a bundle the last packet
			 * however can have it's lookahead used
			 */
			packet->info.rx.rx_flags |=
			    HTC_RX_PKT_IGNORE_LOOKAHEAD;

		/* NOTE: 1 HTC packet per scatter entry */
		scat_req->scat_list[i].buf = packet->buf;
		scat_req->scat_list[i].len = pad_len;

		packet->info.rx.rx_flags |= HTC_RX_PKT_PART_OF_BUNDLE;

		list_add_tail(&packet->list, sync_compq);

		WARN_ON(!scat_req->scat_list[i].len);
		len += scat_req->scat_list[i].len;
	}

	scat_req->len = len;
	scat_req->scat_entries = i;

	status = ath6kl_hif_submit_scat_req(target->dev, scat_req, true);

	if (!status)
		*n_pkt_fetched = i;

	/* free scatter request */
	hif_scatter_req_add(target->dev->ar, scat_req);

fail_rx_pkt:

	return status;
}

static int ath6kl_htc_rx_process_packets(struct htc_target *target,
					 struct list_head *comp_pktq,
					 u32 lk_ahds[],
					 int *n_lk_ahd)
{
	struct htc_packet *packet, *tmp_pkt;
	struct htc_endpoint *ep;
	int status = 0;

	list_for_each_entry_safe(packet, tmp_pkt, comp_pktq, list) {
		ep = &target->endpoint[packet->endpoint];

		trace_ath6kl_htc_rx(packet->status, packet->endpoint,
				    packet->buf, packet->act_len);

		/* process header for each of the recv packet */
		status = ath6kl_htc_rx_process_hdr(target, packet, lk_ahds,
						   n_lk_ahd);
		if (status)
			return status;

		list_del(&packet->list);

		if (list_empty(comp_pktq)) {
			/*
			 * Last packet's more packet flag is set
			 * based on the lookahead.
			 */
			if (*n_lk_ahd > 0)
				ath6kl_htc_rx_set_indicate(lk_ahds[0],
							   ep, packet);
		} else
			/*
			 * Packets in a bundle automatically have
			 * this flag set.
			 */
			packet->info.rx.indicat_flags |=
				HTC_RX_FLAGS_INDICATE_MORE_PKTS;

		ath6kl_htc_rx_update_stats(ep, *n_lk_ahd);

		if (packet->info.rx.rx_flags & HTC_RX_PKT_PART_OF_BUNDLE)
			ep->ep_st.rx_bundl += 1;

		ath6kl_htc_rx_complete(ep, packet);
	}

	return status;
}

static int ath6kl_htc_rx_fetch(struct htc_target *target,
			       struct list_head *rx_pktq,
			       struct list_head *comp_pktq)
{
	int fetched_pkts;
	bool part_bundle = false;
	int status = 0;
	struct list_head tmp_rxq;
	struct htc_packet *packet, *tmp_pkt;

	/* now go fetch the list of HTC packets */
	while (!list_empty(rx_pktq)) {
		fetched_pkts = 0;

		INIT_LIST_HEAD(&tmp_rxq);

		if (target->rx_bndl_enable && (get_queue_depth(rx_pktq) > 1)) {
			/*
			 * There are enough packets to attempt a
			 * bundle transfer and recv bundling is
			 * allowed.
			 */
			status = ath6kl_htc_rx_bundle(target, rx_pktq,
						      &tmp_rxq,
						      &fetched_pkts,
						      part_bundle);
			if (status)
				goto fail_rx;

			if (!list_empty(rx_pktq))
				part_bundle = true;

			list_splice_tail_init(&tmp_rxq, comp_pktq);
		}

		if (!fetched_pkts) {
			packet = list_first_entry(rx_pktq, struct htc_packet,
						   list);

			/* fully synchronous */
			packet->completion = NULL;

			if (!list_is_singular(rx_pktq))
				/*
				 * look_aheads in all packet
				 * except the last one in the
				 * bundle must be ignored
				 */
				packet->info.rx.rx_flags |=
					HTC_RX_PKT_IGNORE_LOOKAHEAD;

			/* go fetch the packet */
			status = ath6kl_htc_rx_packet(target, packet,
						      packet->act_len);

			list_move_tail(&packet->list, &tmp_rxq);

			if (status)
				goto fail_rx;

			list_splice_tail_init(&tmp_rxq, comp_pktq);
		}
	}

	return 0;

fail_rx:

	/*
	 * Cleanup any packets we allocated but didn't use to
	 * actually fetch any packets.
	 */

	list_for_each_entry_safe(packet, tmp_pkt, rx_pktq, list) {
		list_del(&packet->list);
		htc_reclaim_rxbuf(target, packet,
				  &target->endpoint[packet->endpoint]);
	}

	list_for_each_entry_safe(packet, tmp_pkt, &tmp_rxq, list) {
		list_del(&packet->list);
		htc_reclaim_rxbuf(target, packet,
				  &target->endpoint[packet->endpoint]);
	}

	return status;
}

int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
				     u32 msg_look_ahead, int *num_pkts)
{
	struct htc_packet *packets, *tmp_pkt;
	struct htc_endpoint *endpoint;
	struct list_head rx_pktq, comp_pktq;
	int status = 0;
	u32 look_aheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
	int num_look_ahead = 1;
	enum htc_endpoint_id id;
	int n_fetched = 0;

	INIT_LIST_HEAD(&comp_pktq);
	*num_pkts = 0;

	/*
	 * On first entry copy the look_aheads into our temp array for
	 * processing
	 */
	look_aheads[0] = msg_look_ahead;

	while (true) {
		/*
		 * First lookahead sets the expected endpoint IDs for all
		 * packets in a bundle.
		 */
		id = ((struct htc_frame_hdr *)&look_aheads[0])->eid;
		endpoint = &target->endpoint[id];

		if (id >= ENDPOINT_MAX) {
			ath6kl_err("MsgPend, invalid endpoint in look-ahead: %d\n",
				   id);
			status = -ENOMEM;
			break;
		}

		INIT_LIST_HEAD(&rx_pktq);
		INIT_LIST_HEAD(&comp_pktq);

		/*
		 * Try to allocate as many HTC RX packets indicated by the
		 * look_aheads.
		 */
		status = ath6kl_htc_rx_alloc(target, look_aheads,
					     num_look_ahead, endpoint,
					     &rx_pktq);
		if (status)
			break;

		if (get_queue_depth(&rx_pktq) >= 2)
			/*
			 * A recv bundle was detected, force IRQ status
			 * re-check again
			 */
			target->chk_irq_status_cnt = 1;

		n_fetched += get_queue_depth(&rx_pktq);

		num_look_ahead = 0;

		status = ath6kl_htc_rx_fetch(target, &rx_pktq, &comp_pktq);

		if (!status)
			ath6kl_htc_rx_chk_water_mark(endpoint);

		/* Process fetched packets */
		status = ath6kl_htc_rx_process_packets(target, &comp_pktq,
						       look_aheads,
						       &num_look_ahead);

		if (!num_look_ahead || status)
			break;

		/*
		 * For SYNCH processing, if we get here, we are running
		 * through the loop again due to a detected lookahead. Set
		 * flag that we should re-check IRQ status registers again
		 * before leaving IRQ processing, this can net better
		 * performance in high throughput situations.
		 */
		target->chk_irq_status_cnt = 1;
	}

	if (status) {
		ath6kl_err("failed to get pending recv messages: %d\n",
			   status);

		/* cleanup any packets in sync completion queue */
		list_for_each_entry_safe(packets, tmp_pkt, &comp_pktq, list) {
			list_del(&packets->list);
			htc_reclaim_rxbuf(target, packets,
					  &target->endpoint[packets->endpoint]);
		}

		if (target->htc_flags & HTC_OP_STATE_STOPPING) {
			ath6kl_warn("host is going to stop blocking receiver for htc_stop\n");
			ath6kl_hif_rx_control(target->dev, false);
		}
	}

	/*
	 * Before leaving, check to see if host ran out of buffers and
	 * needs to stop the receiver.
	 */
	if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
		ath6kl_warn("host has no rx buffers blocking receiver to prevent overrun\n");
		ath6kl_hif_rx_control(target->dev, false);
	}
	*num_pkts = n_fetched;

	return status;
}

/*
 * Synchronously wait for a control message from the target,
 * This function is used at initialization time ONLY.  At init messages
 * on ENDPOINT 0 are expected.
 */
static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
{
	struct htc_packet *packet = NULL;
	struct htc_frame_hdr *htc_hdr;
	u32 look_ahead;

	if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead,
				       HTC_TARGET_RESPONSE_TIMEOUT))
		return NULL;

	ath6kl_dbg(ATH6KL_DBG_HTC,
		   "htc rx wait ctrl look_ahead 0x%X\n", look_ahead);

	htc_hdr = (struct htc_frame_hdr *)&look_ahead;

	if (htc_hdr->eid != ENDPOINT_0)
		return NULL;

	packet = htc_get_control_buf(target, false);

	if (!packet)
		return NULL;

	packet->info.rx.rx_flags = 0;
	packet->info.rx.exp_hdr = look_ahead;
	packet->act_len = le16_to_cpu(htc_hdr->payld_len) + HTC_HDR_LENGTH;

	if (packet->act_len > packet->buf_len)
		goto fail_ctrl_rx;

	/* we want synchronous operation */
	packet->completion = NULL;

	/* get the message from the device, this will block */
	if (ath6kl_htc_rx_packet(target, packet, packet->act_len))
		goto fail_ctrl_rx;

	trace_ath6kl_htc_rx(packet->status, packet->endpoint,
			    packet->buf, packet->act_len);

	/* process receive header */
	packet->status = ath6kl_htc_rx_process_hdr(target, packet, NULL, NULL);

	if (packet->status) {
		ath6kl_err("htc_wait_for_ctrl_msg, ath6kl_htc_rx_process_hdr failed (status = %d)\n",
			   packet->status);
		goto fail_ctrl_rx;
	}

	return packet;

fail_ctrl_rx:
	if (packet != NULL) {
		htc_rxpkt_reset(packet);
		reclaim_rx_ctrl_buf(target, packet);
	}

	return NULL;
}

static int ath6kl_htc_mbox_add_rxbuf_multiple(struct htc_target *target,
				  struct list_head *pkt_queue)
{
	struct htc_endpoint *endpoint;
	struct htc_packet *first_pkt;
	bool rx_unblock = false;
	int status = 0, depth;

	if (list_empty(pkt_queue))
		return -ENOMEM;

	first_pkt = list_first_entry(pkt_queue, struct htc_packet, list);

	if (first_pkt->endpoint >= ENDPOINT_MAX)
		return status;

	depth = get_queue_depth(pkt_queue);

	ath6kl_dbg(ATH6KL_DBG_HTC,
		   "htc rx add multiple ep id %d cnt %d len %d\n",
		first_pkt->endpoint, depth, first_pkt->buf_len);

	endpoint = &target->endpoint[first_pkt->endpoint];

	if (target->htc_flags & HTC_OP_STATE_STOPPING) {
		struct htc_packet *packet, *tmp_pkt;

		/* walk through queue and mark each one canceled */
		list_for_each_entry_safe(packet, tmp_pkt, pkt_queue, list) {
			packet->status = -ECANCELED;
			list_del(&packet->list);
			ath6kl_htc_rx_complete(endpoint, packet);
		}

		return status;
	}

	spin_lock_bh(&target->rx_lock);

	list_splice_tail_init(pkt_queue, &endpoint->rx_bufq);

	/* check if we are blocked waiting for a new buffer */
	if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
		if (target->ep_waiting == first_pkt->endpoint) {
			ath6kl_dbg(ATH6KL_DBG_HTC,
				   "htc rx blocked on ep %d, unblocking\n",
				   target->ep_waiting);
			target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS;
			target->ep_waiting = ENDPOINT_MAX;
			rx_unblock = true;
		}
	}

	spin_unlock_bh(&target->rx_lock);

	if (rx_unblock && !(target->htc_flags & HTC_OP_STATE_STOPPING))
		/* TODO : implement a buffer threshold count? */
		ath6kl_hif_rx_control(target->dev, true);

	return status;
}

static void ath6kl_htc_mbox_flush_rx_buf(struct htc_target *target)
{
	struct htc_endpoint *endpoint;
	struct htc_packet *packet, *tmp_pkt;
	int i;

	for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
		endpoint = &target->endpoint[i];
		if (!endpoint->svc_id)
			/* not in use.. */
			continue;

		spin_lock_bh(&target->rx_lock);
		list_for_each_entry_safe(packet, tmp_pkt,
					 &endpoint->rx_bufq, list) {
			list_del(&packet->list);
			spin_unlock_bh(&target->rx_lock);
			ath6kl_dbg(ATH6KL_DBG_HTC,
				   "htc rx flush pkt 0x%p  len %d  ep %d\n",
				   packet, packet->buf_len,
				   packet->endpoint);
			/*
			 * packets in rx_bufq of endpoint 0 have originally
			 * been queued from target->free_ctrl_rxbuf where
			 * packet and packet->buf_start are allocated
			 * separately using kmalloc(). For other endpoint
			 * rx_bufq, it is allocated as skb where packet is
			 * skb->head. Take care of this difference while freeing
			 * the memory.
			 */
			if (packet->endpoint == ENDPOINT_0) {
				kfree(packet->buf_start);
				kfree(packet);
			} else {
				dev_kfree_skb(packet->pkt_cntxt);
			}
			spin_lock_bh(&target->rx_lock);
		}
		spin_unlock_bh(&target->rx_lock);
	}
}

static int ath6kl_htc_mbox_conn_service(struct htc_target *target,
			    struct htc_service_connect_req *conn_req,
			    struct htc_service_connect_resp *conn_resp)
{
	struct htc_packet *rx_pkt = NULL;
	struct htc_packet *tx_pkt = NULL;
	struct htc_conn_service_resp *resp_msg;
	struct htc_conn_service_msg *conn_msg;
	struct htc_endpoint *endpoint;
	enum htc_endpoint_id assigned_ep = ENDPOINT_MAX;
	unsigned int max_msg_sz = 0;
	int status = 0;
	u16 msg_id;

	ath6kl_dbg(ATH6KL_DBG_HTC,
		   "htc connect service target 0x%p service id 0x%x\n",
		   target, conn_req->svc_id);

	if (conn_req->svc_id == HTC_CTRL_RSVD_SVC) {
		/* special case for pseudo control service */
		assigned_ep = ENDPOINT_0;
		max_msg_sz = HTC_MAX_CTRL_MSG_LEN;
	} else {
		/* allocate a packet to send to the target */
		tx_pkt = htc_get_control_buf(target, true);

		if (!tx_pkt)
			return -ENOMEM;

		conn_msg = (struct htc_conn_service_msg *)tx_pkt->buf;
		memset(conn_msg, 0, sizeof(*conn_msg));
		conn_msg->msg_id = cpu_to_le16(HTC_MSG_CONN_SVC_ID);
		conn_msg->svc_id = cpu_to_le16(conn_req->svc_id);
		conn_msg->conn_flags = cpu_to_le16(conn_req->conn_flags);

		set_htc_pkt_info(tx_pkt, NULL, (u8 *) conn_msg,
				 sizeof(*conn_msg) + conn_msg->svc_meta_len,
				 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);

		/* we want synchronous operation */
		tx_pkt->completion = NULL;
		ath6kl_htc_tx_prep_pkt(tx_pkt, 0, 0, 0);
		status = ath6kl_htc_tx_issue(target, tx_pkt);

		if (status)
			goto fail_tx;

		/* wait for response */
		rx_pkt = htc_wait_for_ctrl_msg(target);

		if (!rx_pkt) {
			status = -ENOMEM;
			goto fail_tx;
		}

		resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf;
		msg_id = le16_to_cpu(resp_msg->msg_id);

		if ((msg_id != HTC_MSG_CONN_SVC_RESP_ID) ||
		    (rx_pkt->act_len < sizeof(*resp_msg))) {
			status = -ENOMEM;
			goto fail_tx;
		}

		conn_resp->resp_code = resp_msg->status;
		/* check response status */
		if (resp_msg->status != HTC_SERVICE_SUCCESS) {
			ath6kl_err("target failed service 0x%X connect request (status:%d)\n",
				   resp_msg->svc_id, resp_msg->status);
			status = -ENOMEM;
			goto fail_tx;
		}

		assigned_ep = (enum htc_endpoint_id)resp_msg->eid;
		max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz);
	}

	if (WARN_ON_ONCE(assigned_ep == ENDPOINT_UNUSED ||
			 assigned_ep >= ENDPOINT_MAX || !max_msg_sz)) {
		status = -ENOMEM;
		goto fail_tx;
	}

	endpoint = &target->endpoint[assigned_ep];
	endpoint->eid = assigned_ep;
	if (endpoint->svc_id) {
		status = -ENOMEM;
		goto fail_tx;
	}

	/* return assigned endpoint to caller */
	conn_resp->endpoint = assigned_ep;
	conn_resp->len_max = max_msg_sz;

	/* setup the endpoint */

	/* this marks the endpoint in use */
	endpoint->svc_id = conn_req->svc_id;

	endpoint->max_txq_depth = conn_req->max_txq_depth;
	endpoint->len_max = max_msg_sz;
	endpoint->ep_cb = conn_req->ep_cb;
	endpoint->cred_dist.svc_id = conn_req->svc_id;
	endpoint->cred_dist.htc_ep = endpoint;
	endpoint->cred_dist.endpoint = assigned_ep;
	endpoint->cred_dist.cred_sz = target->tgt_cred_sz;

	switch (endpoint->svc_id) {
	case WMI_DATA_BK_SVC:
		endpoint->tx_drop_packet_threshold = MAX_DEF_COOKIE_NUM / 3;
		break;
	default:
		endpoint->tx_drop_packet_threshold = MAX_HI_COOKIE_NUM;
		break;
	}

	if (conn_req->max_rxmsg_sz) {
		/*
		 * Override cred_per_msg calculation, this optimizes
		 * the credit-low indications since the host will actually
		 * issue smaller messages in the Send path.
		 */
		if (conn_req->max_rxmsg_sz > max_msg_sz) {
			status = -ENOMEM;
			goto fail_tx;
		}
		endpoint->cred_dist.cred_per_msg =
		    conn_req->max_rxmsg_sz / target->tgt_cred_sz;
	} else
		endpoint->cred_dist.cred_per_msg =
		    max_msg_sz / target->tgt_cred_sz;

	if (!endpoint->cred_dist.cred_per_msg)
		endpoint->cred_dist.cred_per_msg = 1;

	/* save local connection flags */
	endpoint->conn_flags = conn_req->flags;

fail_tx:
	if (tx_pkt)
		htc_reclaim_txctrl_buf(target, tx_pkt);

	if (rx_pkt) {
		htc_rxpkt_reset(rx_pkt);
		reclaim_rx_ctrl_buf(target, rx_pkt);
	}

	return status;
}

static void reset_ep_state(struct htc_target *target)
{
	struct htc_endpoint *endpoint;
	int i;

	for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
		endpoint = &target->endpoint[i];
		memset(&endpoint->cred_dist, 0, sizeof(endpoint->cred_dist));
		endpoint->svc_id = 0;
		endpoint->len_max = 0;
		endpoint->max_txq_depth = 0;
		memset(&endpoint->ep_st, 0,
		       sizeof(endpoint->ep_st));
		INIT_LIST_HEAD(&endpoint->rx_bufq);
		INIT_LIST_HEAD(&endpoint->txq);
		endpoint->target = target;
	}

	/* reset distribution list */
	/* FIXME: free existing entries */
	INIT_LIST_HEAD(&target->cred_dist_list);
}

static int ath6kl_htc_mbox_get_rxbuf_num(struct htc_target *target,
			     enum htc_endpoint_id endpoint)
{
	int num;

	spin_lock_bh(&target->rx_lock);
	num = get_queue_depth(&(target->endpoint[endpoint].rx_bufq));
	spin_unlock_bh(&target->rx_lock);
	return num;
}

static void htc_setup_msg_bndl(struct htc_target *target)
{
	/* limit what HTC can handle */
	target->msg_per_bndl_max = min(HTC_HOST_MAX_MSG_PER_BUNDLE,
				       target->msg_per_bndl_max);

	if (ath6kl_hif_enable_scatter(target->dev->ar)) {
		target->msg_per_bndl_max = 0;
		return;
	}

	/* limit bundle what the device layer can handle */
	target->msg_per_bndl_max = min(target->max_scat_entries,
				       target->msg_per_bndl_max);

	ath6kl_dbg(ATH6KL_DBG_BOOT,
		   "htc bundling allowed msg_per_bndl_max %d\n",
		   target->msg_per_bndl_max);

	/* Max rx bundle size is limited by the max tx bundle size */
	target->max_rx_bndl_sz = target->max_xfer_szper_scatreq;
	/* Max tx bundle size if limited by the extended mbox address range */
	target->max_tx_bndl_sz = min(HIF_MBOX0_EXT_WIDTH,
				     target->max_xfer_szper_scatreq);

	ath6kl_dbg(ATH6KL_DBG_BOOT, "htc max_rx_bndl_sz %d max_tx_bndl_sz %d\n",
		   target->max_rx_bndl_sz, target->max_tx_bndl_sz);

	if (target->max_tx_bndl_sz)
		/* tx_bndl_mask is enabled per AC, each has 1 bit */
		target->tx_bndl_mask = (1 << WMM_NUM_AC) - 1;

	if (target->max_rx_bndl_sz)
		target->rx_bndl_enable = true;

	if ((target->tgt_cred_sz % target->block_sz) != 0) {
		ath6kl_warn("credit size: %d is not block aligned! Disabling send bundling\n",
			    target->tgt_cred_sz);

		/*
		 * Disallow send bundling since the credit size is
		 * not aligned to a block size the I/O block
		 * padding will spill into the next credit buffer
		 * which is fatal.
		 */
		target->tx_bndl_mask = 0;
	}
}

static int ath6kl_htc_mbox_wait_target(struct htc_target *target)
{
	struct htc_packet *packet = NULL;
	struct htc_ready_ext_msg *rdy_msg;
	struct htc_service_connect_req connect;
	struct htc_service_connect_resp resp;
	int status;

	/* we should be getting 1 control message that the target is ready */
	packet = htc_wait_for_ctrl_msg(target);

	if (!packet)
		return -ENOMEM;

	/* we controlled the buffer creation so it's properly aligned */
	rdy_msg = (struct htc_ready_ext_msg *)packet->buf;

	if ((le16_to_cpu(rdy_msg->ver2_0_info.msg_id) != HTC_MSG_READY_ID) ||
	    (packet->act_len < sizeof(struct htc_ready_msg))) {
		status = -ENOMEM;
		goto fail_wait_target;
	}

	if (!rdy_msg->ver2_0_info.cred_cnt || !rdy_msg->ver2_0_info.cred_sz) {
		status = -ENOMEM;
		goto fail_wait_target;
	}

	target->tgt_creds = le16_to_cpu(rdy_msg->ver2_0_info.cred_cnt);
	target->tgt_cred_sz = le16_to_cpu(rdy_msg->ver2_0_info.cred_sz);

	ath6kl_dbg(ATH6KL_DBG_BOOT,
		   "htc target ready credits %d size %d\n",
		   target->tgt_creds, target->tgt_cred_sz);

	/* check if this is an extended ready message */
	if (packet->act_len >= sizeof(struct htc_ready_ext_msg)) {
		/* this is an extended message */
		target->htc_tgt_ver = rdy_msg->htc_ver;
		target->msg_per_bndl_max = rdy_msg->msg_per_htc_bndl;
	} else {
		/* legacy */
		target->htc_tgt_ver = HTC_VERSION_2P0;
		target->msg_per_bndl_max = 0;
	}

	ath6kl_dbg(ATH6KL_DBG_BOOT, "htc using protocol %s (%d)\n",
		   (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
		   target->htc_tgt_ver);

	if (target->msg_per_bndl_max > 0)
		htc_setup_msg_bndl(target);

	/* setup our pseudo HTC control endpoint connection */
	memset(&connect, 0, sizeof(connect));
	memset(&resp, 0, sizeof(resp));
	connect.ep_cb.rx = htc_ctrl_rx;
	connect.ep_cb.rx_refill = NULL;
	connect.ep_cb.tx_full = NULL;
	connect.max_txq_depth = NUM_CONTROL_BUFFERS;
	connect.svc_id = HTC_CTRL_RSVD_SVC;

	/* connect fake service */
	status = ath6kl_htc_mbox_conn_service((void *)target, &connect, &resp);

	if (status)
		/*
		 * FIXME: this call doesn't make sense, the caller should
		 * call ath6kl_htc_mbox_cleanup() when it wants remove htc
		 */
		ath6kl_hif_cleanup_scatter(target->dev->ar);

fail_wait_target:
	if (packet) {
		htc_rxpkt_reset(packet);
		reclaim_rx_ctrl_buf(target, packet);
	}

	return status;
}

/*
 * Start HTC, enable interrupts and let the target know
 * host has finished setup.
 */
static int ath6kl_htc_mbox_start(struct htc_target *target)
{
	struct htc_packet *packet;
	int status;

	memset(&target->dev->irq_proc_reg, 0,
	       sizeof(target->dev->irq_proc_reg));

	/* Disable interrupts at the chip level */
	ath6kl_hif_disable_intrs(target->dev);

	target->htc_flags = 0;
	target->rx_st_flags = 0;

	/* Push control receive buffers into htc control endpoint */
	while ((packet = htc_get_control_buf(target, false)) != NULL) {
		status = htc_add_rxbuf(target, packet);
		if (status)
			return status;
	}

	/* NOTE: the first entry in the distribution list is ENDPOINT_0 */
	ath6kl_credit_init(target->credit_info, &target->cred_dist_list,
			   target->tgt_creds);

	dump_cred_dist_stats(target);

	/* Indicate to the target of the setup completion */
	status = htc_setup_tx_complete(target);

	if (status)
		return status;

	/* unmask interrupts */
	status = ath6kl_hif_unmask_intrs(target->dev);

	if (status)
		ath6kl_htc_mbox_stop(target);

	return status;
}

static int ath6kl_htc_reset(struct htc_target *target)
{
	u32 block_size, ctrl_bufsz;
	struct htc_packet *packet;
	int i;

	reset_ep_state(target);

	block_size = target->dev->ar->mbox_info.block_size;

	ctrl_bufsz = (block_size > HTC_MAX_CTRL_MSG_LEN) ?
		      (block_size + HTC_HDR_LENGTH) :
		      (HTC_MAX_CTRL_MSG_LEN + HTC_HDR_LENGTH);

	for (i = 0; i < NUM_CONTROL_BUFFERS; i++) {
		packet = kzalloc(sizeof(*packet), GFP_KERNEL);
		if (!packet)
			return -ENOMEM;

		packet->buf_start = kzalloc(ctrl_bufsz, GFP_KERNEL);
		if (!packet->buf_start) {
			kfree(packet);
			return -ENOMEM;
		}

		packet->buf_len = ctrl_bufsz;
		if (i < NUM_CONTROL_RX_BUFFERS) {
			packet->act_len = 0;
			packet->buf = packet->buf_start;
			packet->endpoint = ENDPOINT_0;
			list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
		} else {
			list_add_tail(&packet->list, &target->free_ctrl_txbuf);
		}
	}

	return 0;
}

/* htc_stop: stop interrupt reception, and flush all queued buffers */
static void ath6kl_htc_mbox_stop(struct htc_target *target)
{
	spin_lock_bh(&target->htc_lock);
	target->htc_flags |= HTC_OP_STATE_STOPPING;
	spin_unlock_bh(&target->htc_lock);

	/*
	 * Masking interrupts is a synchronous operation, when this
	 * function returns all pending HIF I/O has completed, we can
	 * safely flush the queues.
	 */
	ath6kl_hif_mask_intrs(target->dev);

	ath6kl_htc_flush_txep_all(target);

	ath6kl_htc_mbox_flush_rx_buf(target);

	ath6kl_htc_reset(target);
}

static void *ath6kl_htc_mbox_create(struct ath6kl *ar)
{
	struct htc_target *target = NULL;
	int status = 0;

	target = kzalloc(sizeof(*target), GFP_KERNEL);
	if (!target) {
		ath6kl_err("unable to allocate memory\n");
		return NULL;
	}

	target->dev = kzalloc(sizeof(*target->dev), GFP_KERNEL);
	if (!target->dev) {
		ath6kl_err("unable to allocate memory\n");
		status = -ENOMEM;
		goto err_htc_cleanup;
	}

	spin_lock_init(&target->htc_lock);
	spin_lock_init(&target->rx_lock);
	spin_lock_init(&target->tx_lock);

	INIT_LIST_HEAD(&target->free_ctrl_txbuf);
	INIT_LIST_HEAD(&target->free_ctrl_rxbuf);
	INIT_LIST_HEAD(&target->cred_dist_list);

	target->dev->ar = ar;
	target->dev->htc_cnxt = target;
	target->ep_waiting = ENDPOINT_MAX;

	status = ath6kl_hif_setup(target->dev);
	if (status)
		goto err_htc_cleanup;

	status = ath6kl_htc_reset(target);
	if (status)
		goto err_htc_cleanup;

	return target;

err_htc_cleanup:
	ath6kl_htc_mbox_cleanup(target);

	return NULL;
}

/* cleanup the HTC instance */
static void ath6kl_htc_mbox_cleanup(struct htc_target *target)
{
	struct htc_packet *packet, *tmp_packet;

	ath6kl_hif_cleanup_scatter(target->dev->ar);

	list_for_each_entry_safe(packet, tmp_packet,
				 &target->free_ctrl_txbuf, list) {
		list_del(&packet->list);
		kfree(packet->buf_start);
		kfree(packet);
	}

	list_for_each_entry_safe(packet, tmp_packet,
				 &target->free_ctrl_rxbuf, list) {
		list_del(&packet->list);
		kfree(packet->buf_start);
		kfree(packet);
	}

	kfree(target->dev);
	kfree(target);
}

static const struct ath6kl_htc_ops ath6kl_htc_mbox_ops = {
	.create = ath6kl_htc_mbox_create,
	.wait_target = ath6kl_htc_mbox_wait_target,
	.start = ath6kl_htc_mbox_start,
	.conn_service = ath6kl_htc_mbox_conn_service,
	.tx = ath6kl_htc_mbox_tx,
	.stop = ath6kl_htc_mbox_stop,
	.cleanup = ath6kl_htc_mbox_cleanup,
	.flush_txep = ath6kl_htc_mbox_flush_txep,
	.flush_rx_buf = ath6kl_htc_mbox_flush_rx_buf,
	.activity_changed = ath6kl_htc_mbox_activity_changed,
	.get_rxbuf_num = ath6kl_htc_mbox_get_rxbuf_num,
	.add_rxbuf_multiple = ath6kl_htc_mbox_add_rxbuf_multiple,
	.credit_setup = ath6kl_htc_mbox_credit_setup,
};

void ath6kl_htc_mbox_attach(struct ath6kl *ar)
{
	ar->htc_ops = &ath6kl_htc_mbox_ops;
}
