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

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

#include "htc_debug.h"
#include "htc_internal.h"
#include <qdf_nbuf.h>           /* qdf_nbuf_t */

/* HTC Control message receive timeout msec */
#define HTC_CONTROL_RX_TIMEOUT     6000

#if defined(WLAN_DEBUG) || defined(DEBUG)
void debug_dump_bytes(uint8_t *buffer, uint16_t length, char *pDescription)
{
	int8_t stream[60];
	int8_t byteOffsetStr[10];
	uint32_t i;
	uint16_t offset, count, byteOffset;

	A_PRINTF("<---------Dumping %d Bytes : %s ------>\n", length,
		 pDescription);

	count = 0;
	offset = 0;
	byteOffset = 0;
	for (i = 0; i < length; i++) {
		A_SNPRINTF(stream + offset, (sizeof(stream) - offset),
			   "%02X ", buffer[i]);
		count++;
		offset += 3;

		if (count == 16) {
			count = 0;
			offset = 0;
			A_SNPRINTF(byteOffsetStr, sizeof(byteOffset), "%4.4X",
				   byteOffset);
			A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
			qdf_mem_zero(stream, 60);
			byteOffset += 16;
		}
	}

	if (offset != 0) {
		A_SNPRINTF(byteOffsetStr, sizeof(byteOffset), "%4.4X",
			   byteOffset);
		A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
	}

	A_PRINTF("<------------------------------------------------->\n");
}
#else
void debug_dump_bytes(uint8_t *buffer, uint16_t length, char *pDescription)
{
}
#endif

static A_STATUS htc_process_trailer(HTC_TARGET *target,
				    uint8_t *pBuffer,
				    int Length, HTC_ENDPOINT_ID FromEndpoint);

static void do_recv_completion_pkt(HTC_ENDPOINT *pEndpoint,
				   HTC_PACKET *pPacket)
{
	if (pEndpoint->EpCallBacks.EpRecv == NULL) {
		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
				("HTC ep %d has NULL recv callback on packet %pK\n",
				 pEndpoint->Id,
				 pPacket));
		if (pPacket)
			qdf_nbuf_free(pPacket->pPktContext);
	} else {
		AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
				("HTC calling ep %d recv callback on packet %pK\n",
				 pEndpoint->Id, pPacket));
		pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext,
					      pPacket);
	}
}

static void do_recv_completion(HTC_ENDPOINT *pEndpoint,
			       HTC_PACKET_QUEUE *pQueueToIndicate)
{
	HTC_PACKET *pPacket;

	if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
		/* nothing to indicate */
		return;
	}

	while (!HTC_QUEUE_EMPTY(pQueueToIndicate)) {
		pPacket = htc_packet_dequeue(pQueueToIndicate);
		do_recv_completion_pkt(pEndpoint, pPacket);
	}
}

static void recv_packet_completion(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint,
				   HTC_PACKET *pPacket)
{
	do_recv_completion_pkt(pEndpoint, pPacket);

	/* recover the packet container */
	free_htc_packet_container(target, pPacket);
}

void htc_control_rx_complete(void *Context, HTC_PACKET *pPacket)
{
	/* TODO, can't really receive HTC control messages yet.... */
	AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
			("Invalid call to  htc_control_rx_complete\n"));
}

void htc_unblock_recv(HTC_HANDLE HTCHandle)
{
	/* TODO  find the Need in new model */
}

void htc_enable_recv(HTC_HANDLE HTCHandle)
{

	/* TODO  find the Need in new model */
}

void htc_disable_recv(HTC_HANDLE HTCHandle)
{

	/* TODO  find the Need in new model */
}

int htc_get_num_recv_buffers(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);

	HTC_ENDPOINT *pEndpoint = &target->endpoint[Endpoint];
	return HTC_PACKET_QUEUE_DEPTH(&pEndpoint->RxBufferHoldQueue);
}

HTC_PACKET *allocate_htc_packet_container(HTC_TARGET *target)
{
	HTC_PACKET *pPacket;

	LOCK_HTC_RX(target);

	if (NULL == target->pHTCPacketStructPool) {
		UNLOCK_HTC_RX(target);
		return NULL;
	}

	pPacket = target->pHTCPacketStructPool;
	target->pHTCPacketStructPool = (HTC_PACKET *) pPacket->ListLink.pNext;

	UNLOCK_HTC_RX(target);

	pPacket->ListLink.pNext = NULL;
	return pPacket;
}

void free_htc_packet_container(HTC_TARGET *target, HTC_PACKET *pPacket)
{
	pPacket->ListLink.pPrev = NULL;

	LOCK_HTC_RX(target);
	if (NULL == target->pHTCPacketStructPool) {
		target->pHTCPacketStructPool = pPacket;
		pPacket->ListLink.pNext = NULL;
	} else {
		pPacket->ListLink.pNext =
			(DL_LIST *) target->pHTCPacketStructPool;
		target->pHTCPacketStructPool = pPacket;
	}

	UNLOCK_HTC_RX(target);
}

#ifdef RX_SG_SUPPORT
qdf_nbuf_t rx_sg_to_single_netbuf(HTC_TARGET *target)
{
	qdf_nbuf_t skb;
	uint8_t *anbdata;
	uint8_t *anbdata_new;
	uint32_t anblen;
	qdf_nbuf_t new_skb = NULL;
	uint32_t sg_queue_len;
	qdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;

	sg_queue_len = qdf_nbuf_queue_len(rx_sg_queue);

	if (sg_queue_len <= 1) {
		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
				("rx_sg_to_single_netbuf: invalid sg queue len %u\n"));
		goto _failed;
	}

	new_skb = qdf_nbuf_alloc(target->ExpRxSgTotalLen, 0, 4, false);
	if (new_skb == NULL) {
		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
				("rx_sg_to_single_netbuf: can't allocate %u size netbuf\n",
				 target->ExpRxSgTotalLen));
		goto _failed;
	}

	qdf_nbuf_peek_header(new_skb, &anbdata_new, &anblen);

	skb = qdf_nbuf_queue_remove(rx_sg_queue);
	do {
		qdf_nbuf_peek_header(skb, &anbdata, &anblen);
		qdf_mem_copy(anbdata_new, anbdata, qdf_nbuf_len(skb));
		qdf_nbuf_put_tail(new_skb, qdf_nbuf_len(skb));
		anbdata_new += qdf_nbuf_len(skb);
		qdf_nbuf_free(skb);
		skb = qdf_nbuf_queue_remove(rx_sg_queue);
	} while (skb != NULL);

	RESET_RX_SG_CONFIG(target);
	return new_skb;

_failed:

	while ((skb = qdf_nbuf_queue_remove(rx_sg_queue)) != NULL)
		qdf_nbuf_free(skb);

	RESET_RX_SG_CONFIG(target);
	return NULL;
}
#endif

#ifdef CONFIG_WIN
#define HTC_MSG_NACK_SUSPEND 7
#endif

QDF_STATUS htc_rx_completion_handler(void *Context, qdf_nbuf_t netbuf,
				   uint8_t pipeID)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	HTC_FRAME_HDR *HtcHdr;
	HTC_TARGET *target = (HTC_TARGET *) Context;
	uint8_t *netdata;
	uint32_t netlen;
	HTC_ENDPOINT *pEndpoint;
	HTC_PACKET *pPacket;
	uint16_t payloadLen;
	uint32_t trailerlen = 0;
	uint8_t htc_ep_id;

#ifdef RX_SG_SUPPORT
	LOCK_HTC_RX(target);
	if (target->IsRxSgInprogress) {
		target->CurRxSgTotalLen += qdf_nbuf_len(netbuf);
		qdf_nbuf_queue_add(&target->RxSgQueue, netbuf);
		if (target->CurRxSgTotalLen == target->ExpRxSgTotalLen) {
			netbuf = rx_sg_to_single_netbuf(target);
			if (netbuf == NULL) {
				UNLOCK_HTC_RX(target);
				goto _out;
			}
		} else {
			netbuf = NULL;
			UNLOCK_HTC_RX(target);
			goto _out;
		}
	}
	UNLOCK_HTC_RX(target);
#endif

	netdata = qdf_nbuf_data(netbuf);
	netlen = qdf_nbuf_len(netbuf);

	HtcHdr = (HTC_FRAME_HDR *) netdata;

	do {

		htc_ep_id = HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR, ENDPOINTID);

		if (htc_ep_id >= ENDPOINT_MAX) {
			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
					("HTC Rx: invalid EndpointID=%d\n",
					 htc_ep_id));
			debug_dump_bytes((uint8_t *) HtcHdr,
					sizeof(HTC_FRAME_HDR),
					"BAD HTC Header");
			status = QDF_STATUS_E_FAILURE;
			QDF_BUG(0);
			break;
		}

		pEndpoint = &target->endpoint[htc_ep_id];

		/*
		 * If this endpoint that received a message from the target has
		 * a to-target HIF pipe whose send completions are polled rather
		 * than interrupt driven, this is a good point to ask HIF to
		 * check whether it has any completed sends to handle.
		 */
		if (pEndpoint->ul_is_polled)
			htc_send_complete_check(pEndpoint, 1);

		payloadLen = HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR, PAYLOADLEN);

		if (netlen < (payloadLen + HTC_HDR_LENGTH)) {
#ifdef RX_SG_SUPPORT
			LOCK_HTC_RX(target);
			target->IsRxSgInprogress = true;
			qdf_nbuf_queue_init(&target->RxSgQueue);
			qdf_nbuf_queue_add(&target->RxSgQueue, netbuf);
			target->ExpRxSgTotalLen = (payloadLen + HTC_HDR_LENGTH);
			target->CurRxSgTotalLen += netlen;
			UNLOCK_HTC_RX(target);
			netbuf = NULL;
			break;
#else
			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
					("HTC Rx: insufficient length, got:%d expected =%zu\n",
					 netlen, payloadLen + HTC_HDR_LENGTH));
			debug_dump_bytes((uint8_t *) HtcHdr,
					 sizeof(HTC_FRAME_HDR),
					 "BAD RX packet length");
			status = QDF_STATUS_E_FAILURE;
			QDF_BUG(0);
			break;
#endif
		}
#ifdef HTC_EP_STAT_PROFILING
		LOCK_HTC_RX(target);
		INC_HTC_EP_STAT(pEndpoint, RxReceived, 1);
		UNLOCK_HTC_RX(target);
#endif

		/* if (IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) { */
		{
			uint8_t temp;
			A_STATUS temp_status;
			/* get flags to check for trailer */
			temp = HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR, FLAGS);
			if (temp & HTC_FLAGS_RECV_TRAILER) {
				/* extract the trailer length */
				temp =
					HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR,
						      CONTROLBYTES0);
				if ((temp < sizeof(HTC_RECORD_HDR))
				    || (temp > payloadLen)) {
					AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
						("htc_rx_completion_handler, invalid header (payloadlength should be :%d, CB[0] is:%d)\n",
						payloadLen, temp));
					status = QDF_STATUS_E_INVAL;
					break;
				}

				trailerlen = temp;
				/* process trailer data that follows HDR +
				 * application payload
				 */
				temp_status = htc_process_trailer(target,
						((uint8_t *) HtcHdr +
							HTC_HDR_LENGTH +
							payloadLen - temp),
						temp, htc_ep_id);
				if (A_FAILED(temp_status)) {
					status = QDF_STATUS_E_FAILURE;
					break;
				}

			}
		}

		if (((int)payloadLen - (int)trailerlen) <= 0) {
			/* 0 length packet with trailer data, just drop these */
			break;
		}

		if (htc_ep_id == ENDPOINT_0) {
			uint16_t message_id;
			HTC_UNKNOWN_MSG *htc_msg;
			bool wow_nack;

			/* remove HTC header */
			qdf_nbuf_pull_head(netbuf, HTC_HDR_LENGTH);
			netdata = qdf_nbuf_data(netbuf);
			netlen = qdf_nbuf_len(netbuf);

			htc_msg = (HTC_UNKNOWN_MSG *) netdata;
			message_id = HTC_GET_FIELD(htc_msg, HTC_UNKNOWN_MSG,
						   MESSAGEID);

			switch (message_id) {
			default:
				/* handle HTC control message */
				if (target->CtrlResponseProcessing) {
					/* this is a fatal error, target should
					 * not be sending unsolicited messages
					 * on the endpoint 0
					 */
					AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
							("HTC Rx Ctrl still processing\n"));
					status = QDF_STATUS_E_FAILURE;
					QDF_BUG(false);
					break;
				}

				LOCK_HTC_RX(target);
				target->CtrlResponseLength =
					min((int)netlen,
					    HTC_MAX_CONTROL_MESSAGE_LENGTH);
				qdf_mem_copy(target->CtrlResponseBuffer,
					     netdata,
					     target->CtrlResponseLength);

				/* Requester will clear this flag */
				target->CtrlResponseProcessing = true;
				UNLOCK_HTC_RX(target);

				qdf_event_set(&target->ctrl_response_valid);
				break;
#ifdef HTC_MSG_WAKEUP_FROM_SUSPEND_ID
			case HTC_MSG_WAKEUP_FROM_SUSPEND_ID:
				AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
					("Received initial wake up"));
				LOCK_HTC_CREDIT(target);
				htc_credit_record(HTC_INITIAL_WAKE_UP,
					pEndpoint->TxCredits,
					HTC_PACKET_QUEUE_DEPTH(
						&pEndpoint->TxQueue));
				UNLOCK_HTC_CREDIT(target);
				if (target->HTCInitInfo.
						target_initial_wakeup_cb)
					target->HTCInitInfo.
						target_initial_wakeup_cb();
				else
					AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
						("No initial wake up cb"));
				break;
#endif
			case HTC_MSG_SEND_SUSPEND_COMPLETE:
				wow_nack = false;
				LOCK_HTC_CREDIT(target);
				htc_credit_record(HTC_SUSPEND_ACK,
					pEndpoint->TxCredits,
					HTC_PACKET_QUEUE_DEPTH(
						&pEndpoint->TxQueue));
				UNLOCK_HTC_CREDIT(target);
				target->HTCInitInfo.TargetSendSuspendComplete(
					target->HTCInitInfo.pContext,
					wow_nack);

				break;
			case HTC_MSG_NACK_SUSPEND:
				wow_nack = true;
				LOCK_HTC_CREDIT(target);
				htc_credit_record(HTC_SUSPEND_ACK,
					pEndpoint->TxCredits,
					HTC_PACKET_QUEUE_DEPTH(
						&pEndpoint->TxQueue));
				UNLOCK_HTC_CREDIT(target);

				target->HTCInitInfo.TargetSendSuspendComplete(
					target->HTCInitInfo.pContext,
					wow_nack);
				break;
			}

			qdf_nbuf_free(netbuf);
			netbuf = NULL;
			break;
		}

		/* the current message based HIF architecture allocates net bufs
		 * for recv packets since this layer bridges that HIF to upper
		 * layers , which expects HTC packets, we form the packets here
		 * TODO_FIXME
		 */
		pPacket = allocate_htc_packet_container(target);
		if (NULL == pPacket) {
			status = QDF_STATUS_E_RESOURCES;
			break;
		}
		pPacket->Status = QDF_STATUS_SUCCESS;
		pPacket->Endpoint = htc_ep_id;
		pPacket->pPktContext = netbuf;
		pPacket->pBuffer = qdf_nbuf_data(netbuf) + HTC_HDR_LENGTH;
		pPacket->ActualLength = netlen - HTC_HEADER_LEN - trailerlen;

		qdf_nbuf_pull_head(netbuf, HTC_HEADER_LEN);
		qdf_nbuf_set_pktlen(netbuf, pPacket->ActualLength);

		recv_packet_completion(target, pEndpoint, pPacket);
		netbuf = NULL;

	} while (false);

#ifdef RX_SG_SUPPORT
_out:
#endif

	if (netbuf != NULL)
		qdf_nbuf_free(netbuf);

	return status;

}

A_STATUS htc_add_receive_pkt_multiple(HTC_HANDLE HTCHandle,
				      HTC_PACKET_QUEUE *pPktQueue)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	HTC_ENDPOINT *pEndpoint;
	HTC_PACKET *pFirstPacket;
	A_STATUS status = A_OK;
	HTC_PACKET *pPacket;

	pFirstPacket = htc_get_pkt_at_head(pPktQueue);

	if (NULL == pFirstPacket) {
		A_ASSERT(false);
		return A_EINVAL;
	}

	AR_DEBUG_ASSERT(pFirstPacket->Endpoint < ENDPOINT_MAX);

	AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
			("+- htc_add_receive_pkt_multiple : endPointId: %d, cnt:%d, length: %d\n",
			 pFirstPacket->Endpoint,
			 HTC_PACKET_QUEUE_DEPTH(pPktQueue),
			 pFirstPacket->BufferLength));

	pEndpoint = &target->endpoint[pFirstPacket->Endpoint];

	LOCK_HTC_RX(target);

	do {

		if (HTC_STOPPING(target)) {
			status = A_ERROR;
			break;
		}

		/* store receive packets */
		HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RxBufferHoldQueue,
						  pPktQueue);

	} while (false);

	UNLOCK_HTC_RX(target);

	if (A_FAILED(status)) {
		/* walk through queue and mark each one canceled */
		HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue, pPacket) {
			pPacket->Status = QDF_STATUS_E_CANCELED;
		}
		HTC_PACKET_QUEUE_ITERATE_END;

		do_recv_completion(pEndpoint, pPktQueue);
	}

	return status;
}

A_STATUS htc_add_receive_pkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket)
{
	HTC_PACKET_QUEUE queue;

	INIT_HTC_PACKET_QUEUE_AND_ADD(&queue, pPacket);
	return htc_add_receive_pkt_multiple(HTCHandle, &queue);
}

void htc_flush_rx_hold_queue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint)
{
	HTC_PACKET *pPacket;

	LOCK_HTC_RX(target);

	while (1) {
		pPacket = htc_packet_dequeue(&pEndpoint->RxBufferHoldQueue);
		if (pPacket == NULL)
			break;
		UNLOCK_HTC_RX(target);
		pPacket->Status = QDF_STATUS_E_CANCELED;
		pPacket->ActualLength = 0;
		AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
				("Flushing RX packet:%pK, length:%d, ep:%d\n",
				 pPacket, pPacket->BufferLength,
				 pPacket->Endpoint));
		/* give the packet back */
		do_recv_completion_pkt(pEndpoint, pPacket);
		LOCK_HTC_RX(target);
	}

	UNLOCK_HTC_RX(target);
}

void htc_recv_init(HTC_TARGET *target)
{
	/* Initialize ctrl_response_valid to block */
	qdf_event_create(&target->ctrl_response_valid);
}

/* polling routine to wait for a control packet to be received */
QDF_STATUS htc_wait_recv_ctrl_message(HTC_TARGET *target)
{
/*    int count = HTC_TARGET_MAX_RESPONSE_POLL; */

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCWaitCtrlMessageRecv\n"));

	/* Wait for BMI request/response transaction to complete */
	if (qdf_wait_single_event(&target->ctrl_response_valid,
				  HTC_CONTROL_RX_TIMEOUT)) {
		return QDF_STATUS_E_FAILURE;
	}

	LOCK_HTC_RX(target);
	/* caller will clear this flag */
	target->CtrlResponseProcessing = true;

	UNLOCK_HTC_RX(target);

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCWaitCtrlMessageRecv success\n"));
	return QDF_STATUS_SUCCESS;
}

static A_STATUS htc_process_trailer(HTC_TARGET *target,
				    uint8_t *pBuffer,
				    int Length, HTC_ENDPOINT_ID FromEndpoint)
{
	HTC_RECORD_HDR *pRecord;
	uint8_t htc_rec_id;
	uint8_t htc_rec_len;
	uint8_t *pRecordBuf;
	uint8_t *pOrigBuffer;
	int origLength;
	A_STATUS status;

	AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
			("+htc_process_trailer (length:%d)\n", Length));

	if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV))
		AR_DEBUG_PRINTBUF(pBuffer, Length, "Recv Trailer");

	pOrigBuffer = pBuffer;
	origLength = Length;
	status = A_OK;

	while (Length > 0) {

		if (Length < sizeof(HTC_RECORD_HDR)) {
			status = A_EPROTO;
			break;
		}
		/* these are byte aligned structs */
		pRecord = (HTC_RECORD_HDR *) pBuffer;
		Length -= sizeof(HTC_RECORD_HDR);
		pBuffer += sizeof(HTC_RECORD_HDR);

		htc_rec_len = HTC_GET_FIELD(pRecord, HTC_RECORD_HDR, LENGTH);
		htc_rec_id = HTC_GET_FIELD(pRecord, HTC_RECORD_HDR, RECORDID);

		if (htc_rec_len > Length) {
			/* no room left in buffer for record */
			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
					("invalid record length: %d (id:%d) buffer has: %d bytes left\n",
					 htc_rec_len, htc_rec_id, Length));
			status = A_EPROTO;
			break;
		}
		/* start of record follows the header */
		pRecordBuf = pBuffer;

		switch (htc_rec_id) {
		case HTC_RECORD_CREDITS:
			AR_DEBUG_ASSERT(htc_rec_len >=
					sizeof(HTC_CREDIT_REPORT));
			htc_process_credit_rpt(target,
					       (HTC_CREDIT_REPORT *) pRecordBuf,
					       htc_rec_len /
					       (sizeof(HTC_CREDIT_REPORT)),
					       FromEndpoint);
			break;

#ifdef HIF_SDIO
		case HTC_RECORD_LOOKAHEAD:
			/* Process in HIF layer */
			break;

		case HTC_RECORD_LOOKAHEAD_BUNDLE:
			/* Process in HIF layer */
			break;
#endif /* HIF_SDIO */

		default:
			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
					("HTC unhandled record: id:%d length:%d\n",
					 htc_rec_id, htc_rec_len));
			break;
		}

		if (A_FAILED(status)) {
			break;
		}

		/* advance buffer past this record for next time around */
		pBuffer += htc_rec_len;
		Length -= htc_rec_len;
	}

	if (A_FAILED(status))
		debug_dump_bytes(pOrigBuffer, origLength, "BAD Recv Trailer");

	AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-htc_process_trailer\n"));
	return status;

}
