/*
 * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
 *
 * 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 "hif.h"
#include "hif_io32.h"
#include "ce_api.h"
#include "ce_main.h"
#include "ce_internal.h"
#include "ce_reg.h"
#include "qdf_lock.h"
#include "regtable.h"
#include "hif_main.h"
#include "hif_debug.h"
#include "hif_napi.h"
#include "qdf_module.h"

#ifdef IPA_OFFLOAD
#ifdef QCA_WIFI_3_0
#define CE_IPA_RING_INIT(ce_desc)                       \
	do {                                            \
		ce_desc->gather = 0;                    \
		ce_desc->enable_11h = 0;                \
		ce_desc->meta_data_low = 0;             \
		ce_desc->packet_result_offset = 64;     \
		ce_desc->toeplitz_hash_enable = 0;      \
		ce_desc->addr_y_search_disable = 0;     \
		ce_desc->addr_x_search_disable = 0;     \
		ce_desc->misc_int_disable = 0;          \
		ce_desc->target_int_disable = 0;        \
		ce_desc->host_int_disable = 0;          \
		ce_desc->dest_byte_swap = 0;            \
		ce_desc->byte_swap = 0;                 \
		ce_desc->type = 2;                      \
		ce_desc->tx_classify = 1;               \
		ce_desc->buffer_addr_hi = 0;            \
		ce_desc->meta_data = 0;                 \
		ce_desc->nbytes = 128;                  \
	} while (0)
#else
#define CE_IPA_RING_INIT(ce_desc)                       \
	do {                                            \
		ce_desc->byte_swap = 0;                 \
		ce_desc->nbytes = 60;                   \
		ce_desc->gather = 0;                    \
	} while (0)
#endif /* QCA_WIFI_3_0 */
#endif /* IPA_OFFLOAD */

static int war1_allow_sleep;
/* io32 write workaround */
static int hif_ce_war1;

/**
 * hif_ce_war_disable() - disable ce war gobally
 */
void hif_ce_war_disable(void)
{
	hif_ce_war1 = 0;
}

/**
 * hif_ce_war_enable() - enable ce war gobally
 */
void hif_ce_war_enable(void)
{
	hif_ce_war1 = 1;
}

/*
 * Note: For MCL, #if defined (HIF_CONFIG_SLUB_DEBUG_ON) needs to be checked
 * for defined here
 */
#if defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF)

#define CE_DEBUG_PRINT_BUF_SIZE(x) (((x) * 3) - 1)
#define CE_DEBUG_DATA_PER_ROW 16

static const char *ce_event_type_to_str(enum hif_ce_event_type type);

/**
 * get_next_record_index() - get the next record index
 * @table_index: atomic index variable to increment
 * @array_size: array size of the circular buffer
 *
 * Increment the atomic index and reserve the value.
 * Takes care of buffer wrap.
 * Guaranteed to be thread safe as long as fewer than array_size contexts
 * try to access the array.  If there are more than array_size contexts
 * trying to access the array, full locking of the recording process would
 * be needed to have sane logging.
 */
static int get_next_record_index(qdf_atomic_t *table_index, int array_size)
{
	int record_index = qdf_atomic_inc_return(table_index);

	if (record_index == array_size)
		qdf_atomic_sub(array_size, table_index);

	while (record_index >= array_size)
		record_index -= array_size;
	return record_index;
}

#ifdef HIF_CE_DEBUG_DATA_BUF
/**
 * hif_ce_desc_data_record() - Record data pointed by the CE descriptor
 * @event: structure detailing a ce event
 * @len: length of the data
 * Return:
 */
static void hif_ce_desc_data_record(struct hif_ce_desc_event *event, int len)
{
	uint8_t *data = NULL;

	if (!event->data)
		return;

	if (event->memory && len > 0)
		data = qdf_nbuf_data((qdf_nbuf_t)event->memory);

	event->actual_data_len = 0;
	qdf_mem_zero(event->data, CE_DEBUG_MAX_DATA_BUF_SIZE);

	if (data && len > 0) {
		qdf_mem_copy(event->data, data,
				((len < CE_DEBUG_MAX_DATA_BUF_SIZE) ?
				 len : CE_DEBUG_MAX_DATA_BUF_SIZE));
		event->actual_data_len = len;
	}
}
#endif

/**
 * hif_record_ce_desc_event() - record ce descriptor events
 * @scn: hif_softc
 * @ce_id: which ce is the event occurring on
 * @type: what happened
 * @descriptor: pointer to the descriptor posted/completed
 * @memory: virtual address of buffer related to the descriptor
 * @index: index that the descriptor was/will be at.
 */
void hif_record_ce_desc_event(struct hif_softc *scn, int ce_id,
				enum hif_ce_event_type type,
				union ce_desc *descriptor,
				void *memory, int index,
				int len)
{
	int record_index;
	struct hif_ce_desc_event *event;

	struct ce_desc_hist *ce_hist = &scn->hif_ce_desc_hist;
	struct hif_ce_desc_event *hist_ev = NULL;

	if (ce_id < CE_COUNT_MAX)
		hist_ev = (struct hif_ce_desc_event *)ce_hist->hist_ev[ce_id];
	else
		return;

	if (ce_id >= CE_COUNT_MAX)
		return;

	if (!ce_hist->enable[ce_id])
		return;

	if (!hist_ev)
		return;

	record_index = get_next_record_index(
			&ce_hist->history_index[ce_id], HIF_CE_HISTORY_MAX);

	event = &hist_ev[record_index];

	event->type = type;
	event->time = qdf_get_log_timestamp();

	if (descriptor != NULL) {
		qdf_mem_copy(&event->descriptor, descriptor, sizeof(union ce_desc));
	} else {
		qdf_mem_zero(&event->descriptor, sizeof(union ce_desc));
	}

	event->memory = memory;
	event->index = index;

#ifdef HIF_CE_DEBUG_DATA_BUF
	if (ce_hist->data_enable[ce_id])
		hif_ce_desc_data_record(event, len);
#endif
}
qdf_export_symbol(hif_record_ce_desc_event);

/**
 * ce_init_ce_desc_event_log() - initialize the ce event log
 * @ce_id: copy engine id for which we are initializing the log
 * @size: size of array to dedicate
 *
 * Currently the passed size is ignored in favor of a precompiled value.
 */
void ce_init_ce_desc_event_log(struct hif_softc *scn, int ce_id, int size)
{
	struct ce_desc_hist *ce_hist = &scn->hif_ce_desc_hist;
	qdf_atomic_init(&ce_hist->history_index[ce_id]);
	qdf_mutex_create(&ce_hist->ce_dbg_datamem_lock[ce_id]);
}

/**
 * ce_deinit_ce_desc_event_log() - deinitialize the ce event log
 * @ce_id: copy engine id for which we are deinitializing the log
 *
 */
inline void ce_deinit_ce_desc_event_log(struct hif_softc *scn, int ce_id)
{
	struct ce_desc_hist *ce_hist = &scn->hif_ce_desc_hist;

	qdf_mutex_destroy(&ce_hist->ce_dbg_datamem_lock[ce_id]);
}

#else /* (HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF) */
void hif_record_ce_desc_event(struct hif_softc *scn,
		int ce_id, enum hif_ce_event_type type,
		union ce_desc *descriptor, void *memory,
		int index, int len)
{
}
qdf_export_symbol(hif_record_ce_desc_event);

inline void ce_init_ce_desc_event_log(struct hif_softc *scn, int ce_id,
					int size)
{
}

void ce_deinit_ce_desc_event_log(struct hif_softc *scn, int ce_id)
{
}
#endif /*defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF) */

#ifdef NAPI_YIELD_BUDGET_BASED
bool hif_ce_service_should_yield(struct hif_softc *scn,
				 struct CE_state *ce_state)
{
	bool yield =  hif_max_num_receives_reached(scn, ce_state->receive_count);

	/* Setting receive_count to MAX_NUM_OF_RECEIVES when this count goes
	 * beyond MAX_NUM_OF_RECEIVES for NAPI backet calulation issue. This
	 * can happen in fast path handling as processing is happenning in
	 * batches.
	 */
	if (yield)
		ce_state->receive_count = MAX_NUM_OF_RECEIVES;

	return yield;
}
#else
/**
 * hif_ce_service_should_yield() - return true if the service is hogging the cpu
 * @scn: hif context
 * @ce_state: context of the copy engine being serviced
 *
 * Return: true if the service should yield
 */
bool hif_ce_service_should_yield(struct hif_softc *scn,
				 struct CE_state *ce_state)
{
	bool yield, time_limit_reached, rxpkt_thresh_reached = 0;

	time_limit_reached =
		sched_clock() > ce_state->ce_service_yield_time ? 1 : 0;

	if (!time_limit_reached)
		rxpkt_thresh_reached = hif_max_num_receives_reached
					(scn, ce_state->receive_count);

	/* Setting receive_count to MAX_NUM_OF_RECEIVES when this count goes
	 * beyond MAX_NUM_OF_RECEIVES for NAPI backet calulation issue. This
	 * can happen in fast path handling as processing is happenning in
	 * batches.
	 */
	if (rxpkt_thresh_reached)
		ce_state->receive_count = MAX_NUM_OF_RECEIVES;

	yield =  time_limit_reached || rxpkt_thresh_reached;

	if (yield && ce_state->htt_rx_data)
		hif_napi_update_yield_stats(ce_state,
					    time_limit_reached,
					    rxpkt_thresh_reached);
	return yield;
}
qdf_export_symbol(hif_ce_service_should_yield);
#endif

/*
 * Guts of ce_send, used by both ce_send and ce_sendlist_send.
 * The caller takes responsibility for any needed locking.
 */

void war_ce_src_ring_write_idx_set(struct hif_softc *scn,
				   u32 ctrl_addr, unsigned int write_index)
{
	if (hif_ce_war1) {
		void __iomem *indicator_addr;

		indicator_addr = scn->mem + ctrl_addr + DST_WATERMARK_ADDRESS;

		if (!war1_allow_sleep
		    && ctrl_addr == CE_BASE_ADDRESS(CDC_WAR_DATA_CE)) {
			hif_write32_mb(scn, indicator_addr,
				       (CDC_WAR_MAGIC_STR | write_index));
		} else {
			unsigned long irq_flags;

			local_irq_save(irq_flags);
			hif_write32_mb(scn, indicator_addr, 1);

			/*
			 * PCIE write waits for ACK in IPQ8K, there is no
			 * need to read back value.
			 */
			(void)hif_read32_mb(scn, indicator_addr);
			/* conservative */
			(void)hif_read32_mb(scn, indicator_addr);

			CE_SRC_RING_WRITE_IDX_SET(scn,
						  ctrl_addr, write_index);

			hif_write32_mb(scn, indicator_addr, 0);
			local_irq_restore(irq_flags);
		}
	} else {
		CE_SRC_RING_WRITE_IDX_SET(scn, ctrl_addr, write_index);
	}
}

qdf_export_symbol(war_ce_src_ring_write_idx_set);

int
ce_send(struct CE_handle *copyeng,
		void *per_transfer_context,
		qdf_dma_addr_t buffer,
		uint32_t nbytes,
		uint32_t transfer_id,
		uint32_t flags,
		uint32_t user_flag)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	int status;
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(CE_state->scn);

	qdf_spin_lock_bh(&CE_state->ce_index_lock);
	status = hif_state->ce_services->ce_send_nolock(copyeng,
			per_transfer_context, buffer, nbytes,
			transfer_id, flags, user_flag);
	qdf_spin_unlock_bh(&CE_state->ce_index_lock);

	return status;
}
qdf_export_symbol(ce_send);

unsigned int ce_sendlist_sizeof(void)
{
	return sizeof(struct ce_sendlist);
}

void ce_sendlist_init(struct ce_sendlist *sendlist)
{
	struct ce_sendlist_s *sl = (struct ce_sendlist_s *)sendlist;

	sl->num_items = 0;
}

int
ce_sendlist_buf_add(struct ce_sendlist *sendlist,
					qdf_dma_addr_t buffer,
					uint32_t nbytes,
					uint32_t flags,
					uint32_t user_flags)
{
	struct ce_sendlist_s *sl = (struct ce_sendlist_s *)sendlist;
	unsigned int num_items = sl->num_items;
	struct ce_sendlist_item *item;

	if (num_items >= CE_SENDLIST_ITEMS_MAX) {
		QDF_ASSERT(num_items < CE_SENDLIST_ITEMS_MAX);
		return QDF_STATUS_E_RESOURCES;
	}

	item = &sl->item[num_items];
	item->send_type = CE_SIMPLE_BUFFER_TYPE;
	item->data = buffer;
	item->u.nbytes = nbytes;
	item->flags = flags;
	item->user_flags = user_flags;
	sl->num_items = num_items + 1;
	return QDF_STATUS_SUCCESS;
}

int
ce_sendlist_send(struct CE_handle *copyeng,
		 void *per_transfer_context,
		 struct ce_sendlist *sendlist, unsigned int transfer_id)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(CE_state->scn);

	return hif_state->ce_services->ce_sendlist_send(copyeng,
			per_transfer_context, sendlist, transfer_id);
}

#ifndef AH_NEED_TX_DATA_SWAP
#define AH_NEED_TX_DATA_SWAP 0
#endif

/**
 * ce_batch_send() - sends bunch of msdus at once
 * @ce_tx_hdl : pointer to CE handle
 * @msdu : list of msdus to be sent
 * @transfer_id : transfer id
 * @len : Downloaded length
 * @sendhead : sendhead
 *
 * Assumption : Called with an array of MSDU's
 * Function:
 * For each msdu in the array
 * 1. Send each msdu
 * 2. Increment write index accordinlgy.
 *
 * Return: list of msds not sent
 */
qdf_nbuf_t ce_batch_send(struct CE_handle *ce_tx_hdl,  qdf_nbuf_t msdu,
		uint32_t transfer_id, u_int32_t len, uint32_t sendhead)
{
	struct CE_state *ce_state = (struct CE_state *)ce_tx_hdl;
	struct hif_softc *scn = ce_state->scn;
	struct CE_ring_state *src_ring = ce_state->src_ring;
	u_int32_t ctrl_addr = ce_state->ctrl_addr;
	/*  A_target_id_t targid = TARGID(scn);*/

	uint32_t nentries_mask = src_ring->nentries_mask;
	uint32_t sw_index, write_index;

	struct CE_src_desc *src_desc_base =
		(struct CE_src_desc *)src_ring->base_addr_owner_space;
	uint32_t *src_desc;

	struct CE_src_desc lsrc_desc = {0};
	int deltacount = 0;
	qdf_nbuf_t freelist = NULL, hfreelist = NULL, tempnext;

	DATA_CE_UPDATE_SWINDEX(src_ring->sw_index, scn, ctrl_addr);
	sw_index = src_ring->sw_index;
	write_index = src_ring->write_index;

	deltacount = CE_RING_DELTA(nentries_mask, write_index, sw_index-1);

	while (msdu) {
		tempnext = qdf_nbuf_next(msdu);

		if (deltacount < 2) {
			if (sendhead)
				return msdu;
			HIF_ERROR("%s: Out of descriptors", __func__);
			src_ring->write_index = write_index;
			war_ce_src_ring_write_idx_set(scn, ctrl_addr,
					write_index);

			sw_index = src_ring->sw_index;
			write_index = src_ring->write_index;

			deltacount = CE_RING_DELTA(nentries_mask, write_index,
					sw_index-1);
			if (freelist == NULL) {
				freelist = msdu;
				hfreelist = msdu;
			} else {
				qdf_nbuf_set_next(freelist, msdu);
				freelist = msdu;
			}
			qdf_nbuf_set_next(msdu, NULL);
			msdu = tempnext;
			continue;
		}

		src_desc = (uint32_t *)CE_SRC_RING_TO_DESC(src_desc_base,
				write_index);

		src_desc[0]   = qdf_nbuf_get_frag_paddr(msdu, 0);

		lsrc_desc.meta_data = transfer_id;
		if (len  > msdu->len)
			len =  msdu->len;
		lsrc_desc.nbytes = len;
		/*  Data packet is a byte stream, so disable byte swap */
		lsrc_desc.byte_swap = AH_NEED_TX_DATA_SWAP;
		lsrc_desc.gather    = 0; /*For the last one, gather is not set*/

		src_desc[1] = ((uint32_t *)&lsrc_desc)[1];


		src_ring->per_transfer_context[write_index] = msdu;
		write_index = CE_RING_IDX_INCR(nentries_mask, write_index);

		if (sendhead)
			break;
		qdf_nbuf_set_next(msdu, NULL);
		msdu = tempnext;

	}


	src_ring->write_index = write_index;
	war_ce_src_ring_write_idx_set(scn, ctrl_addr, write_index);

	return hfreelist;
}

/**
 * ce_update_tx_ring() - Advance sw index.
 * @ce_tx_hdl : pointer to CE handle
 * @num_htt_cmpls : htt completions received.
 *
 * Function:
 * Increment the value of sw index of src ring
 * according to number of htt completions
 * received.
 *
 * Return: void
 */
#ifdef DATA_CE_SW_INDEX_NO_INLINE_UPDATE
void ce_update_tx_ring(struct CE_handle *ce_tx_hdl, uint32_t num_htt_cmpls)
{
	struct CE_state *ce_state = (struct CE_state *)ce_tx_hdl;
	struct CE_ring_state *src_ring = ce_state->src_ring;
	uint32_t nentries_mask = src_ring->nentries_mask;
	/*
	 * Advance the s/w index:
	 * This effectively simulates completing the CE ring descriptors
	 */
	src_ring->sw_index =
		CE_RING_IDX_ADD(nentries_mask, src_ring->sw_index,
				num_htt_cmpls);
}
#else
void ce_update_tx_ring(struct CE_handle *ce_tx_hdl, uint32_t num_htt_cmpls)
{}
#endif

/**
 * ce_send_single() - sends
 * @ce_tx_hdl : pointer to CE handle
 * @msdu : msdu to be sent
 * @transfer_id : transfer id
 * @len : Downloaded length
 *
 * Function:
 * 1. Send one msdu
 * 2. Increment write index of src ring accordinlgy.
 *
 * Return: int: CE sent status
 */
int ce_send_single(struct CE_handle *ce_tx_hdl, qdf_nbuf_t msdu,
		uint32_t transfer_id, u_int32_t len)
{
	struct CE_state *ce_state = (struct CE_state *)ce_tx_hdl;
	struct hif_softc *scn = ce_state->scn;
	struct CE_ring_state *src_ring = ce_state->src_ring;
	uint32_t ctrl_addr = ce_state->ctrl_addr;
	/*A_target_id_t targid = TARGID(scn);*/

	uint32_t nentries_mask = src_ring->nentries_mask;
	uint32_t sw_index, write_index;

	struct CE_src_desc *src_desc_base =
		(struct CE_src_desc *)src_ring->base_addr_owner_space;
	uint32_t *src_desc;

	struct CE_src_desc lsrc_desc = {0};
	enum hif_ce_event_type event_type;

	DATA_CE_UPDATE_SWINDEX(src_ring->sw_index, scn, ctrl_addr);
	sw_index = src_ring->sw_index;
	write_index = src_ring->write_index;

	if (qdf_unlikely(CE_RING_DELTA(nentries_mask, write_index,
					sw_index-1) < 1)) {
		/* ol_tx_stats_inc_ring_error(sc->scn->pdev_txrx_handle, 1); */
		HIF_ERROR("%s: ce send fail %d %d %d", __func__, nentries_mask,
			  write_index, sw_index);
		return 1;
	}

	src_desc = (uint32_t *)CE_SRC_RING_TO_DESC(src_desc_base, write_index);

	src_desc[0] = qdf_nbuf_get_frag_paddr(msdu, 0);

	lsrc_desc.meta_data = transfer_id;
	lsrc_desc.nbytes = len;
	/*  Data packet is a byte stream, so disable byte swap */
	lsrc_desc.byte_swap = AH_NEED_TX_DATA_SWAP;
	lsrc_desc.gather    = 0; /* For the last one, gather is not set */

	src_desc[1] = ((uint32_t *)&lsrc_desc)[1];


	src_ring->per_transfer_context[write_index] = msdu;

	if (((struct CE_src_desc *)src_desc)->gather)
		event_type = HIF_TX_GATHER_DESC_POST;
	else if (qdf_unlikely(ce_state->state != CE_RUNNING))
		event_type = HIF_TX_DESC_SOFTWARE_POST;
	else
		event_type = HIF_TX_DESC_POST;

	hif_record_ce_desc_event(scn, ce_state->id, event_type,
				(union ce_desc *)src_desc, msdu,
				write_index, len);

	write_index = CE_RING_IDX_INCR(nentries_mask, write_index);

	src_ring->write_index = write_index;

	war_ce_src_ring_write_idx_set(scn, ctrl_addr, write_index);

	return QDF_STATUS_SUCCESS;
}

/**
 * ce_recv_buf_enqueue() - enqueue a recv buffer into a copy engine
 * @coyeng: copy engine handle
 * @per_recv_context: virtual address of the nbuf
 * @buffer: physical address of the nbuf
 *
 * Return: 0 if the buffer is enqueued
 */
int
ce_recv_buf_enqueue(struct CE_handle *copyeng,
		    void *per_recv_context, qdf_dma_addr_t buffer)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(CE_state->scn);

	return hif_state->ce_services->ce_recv_buf_enqueue(copyeng,
			per_recv_context, buffer);
}
qdf_export_symbol(ce_recv_buf_enqueue);

void
ce_send_watermarks_set(struct CE_handle *copyeng,
		       unsigned int low_alert_nentries,
		       unsigned int high_alert_nentries)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	uint32_t ctrl_addr = CE_state->ctrl_addr;
	struct hif_softc *scn = CE_state->scn;

	CE_SRC_RING_LOWMARK_SET(scn, ctrl_addr, low_alert_nentries);
	CE_SRC_RING_HIGHMARK_SET(scn, ctrl_addr, high_alert_nentries);
}

void
ce_recv_watermarks_set(struct CE_handle *copyeng,
		       unsigned int low_alert_nentries,
		       unsigned int high_alert_nentries)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	uint32_t ctrl_addr = CE_state->ctrl_addr;
	struct hif_softc *scn = CE_state->scn;

	CE_DEST_RING_LOWMARK_SET(scn, ctrl_addr,
				low_alert_nentries);
	CE_DEST_RING_HIGHMARK_SET(scn, ctrl_addr,
				high_alert_nentries);
}

unsigned int ce_send_entries_avail(struct CE_handle *copyeng)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	struct CE_ring_state *src_ring = CE_state->src_ring;
	unsigned int nentries_mask = src_ring->nentries_mask;
	unsigned int sw_index;
	unsigned int write_index;

	qdf_spin_lock(&CE_state->ce_index_lock);
	sw_index = src_ring->sw_index;
	write_index = src_ring->write_index;
	qdf_spin_unlock(&CE_state->ce_index_lock);

	return CE_RING_DELTA(nentries_mask, write_index, sw_index - 1);
}

unsigned int ce_recv_entries_avail(struct CE_handle *copyeng)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	struct CE_ring_state *dest_ring = CE_state->dest_ring;
	unsigned int nentries_mask = dest_ring->nentries_mask;
	unsigned int sw_index;
	unsigned int write_index;

	qdf_spin_lock(&CE_state->ce_index_lock);
	sw_index = dest_ring->sw_index;
	write_index = dest_ring->write_index;
	qdf_spin_unlock(&CE_state->ce_index_lock);

	return CE_RING_DELTA(nentries_mask, write_index, sw_index - 1);
}

/*
 * Guts of ce_send_entries_done.
 * The caller takes responsibility for any necessary locking.
 */
unsigned int ce_send_entries_done(struct CE_handle *copyeng)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	unsigned int nentries;
	struct hif_softc *scn = CE_state->scn;
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);

	qdf_spin_lock(&CE_state->ce_index_lock);
	nentries = hif_state->ce_services->ce_send_entries_done_nolock(
						CE_state->scn, CE_state);
	qdf_spin_unlock(&CE_state->ce_index_lock);

	return nentries;
}

/*
 * Guts of ce_recv_entries_done.
 * The caller takes responsibility for any necessary locking.
 */
unsigned int ce_recv_entries_done(struct CE_handle *copyeng)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	unsigned int nentries;
	struct hif_softc *scn = CE_state->scn;
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);

	qdf_spin_lock(&CE_state->ce_index_lock);
	nentries = hif_state->ce_services->ce_recv_entries_done_nolock(
						CE_state->scn, CE_state);
	qdf_spin_unlock(&CE_state->ce_index_lock);

	return nentries;
}

/*
 * Guts of ce_completed_recv_next.
 * The caller takes responsibility for any necessary locking.
 */
int
ce_completed_recv_next(struct CE_handle *copyeng,
		       void **per_CE_contextp,
		       void **per_transfer_contextp,
		       qdf_dma_addr_t *bufferp,
		       unsigned int *nbytesp,
		       unsigned int *transfer_idp, unsigned int *flagsp)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	int status;
	struct hif_softc *scn = CE_state->scn;
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
	struct ce_ops *ce_services;

	ce_services = hif_state->ce_services;
	qdf_spin_lock_bh(&CE_state->ce_index_lock);
	status =
		ce_services->ce_completed_recv_next_nolock(CE_state,
				per_CE_contextp, per_transfer_contextp, bufferp,
					      nbytesp, transfer_idp, flagsp);
	qdf_spin_unlock_bh(&CE_state->ce_index_lock);

	return status;
}

QDF_STATUS
ce_revoke_recv_next(struct CE_handle *copyeng,
		    void **per_CE_contextp,
		    void **per_transfer_contextp, qdf_dma_addr_t *bufferp)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(CE_state->scn);

	return hif_state->ce_services->ce_revoke_recv_next(copyeng,
			per_CE_contextp, per_transfer_contextp, bufferp);
}

QDF_STATUS
ce_cancel_send_next(struct CE_handle *copyeng,
		void **per_CE_contextp,
		void **per_transfer_contextp,
		qdf_dma_addr_t *bufferp,
		unsigned int *nbytesp,
		unsigned int *transfer_idp,
		uint32_t *toeplitz_hash_result)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(CE_state->scn);

	return hif_state->ce_services->ce_cancel_send_next
		(copyeng, per_CE_contextp, per_transfer_contextp,
		 bufferp, nbytesp, transfer_idp, toeplitz_hash_result);
}
qdf_export_symbol(ce_cancel_send_next);

int
ce_completed_send_next(struct CE_handle *copyeng,
		       void **per_CE_contextp,
		       void **per_transfer_contextp,
		       qdf_dma_addr_t *bufferp,
		       unsigned int *nbytesp,
		       unsigned int *transfer_idp,
		       unsigned int *sw_idx,
		       unsigned int *hw_idx,
		       unsigned int *toeplitz_hash_result)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	struct hif_softc *scn = CE_state->scn;
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
	struct ce_ops *ce_services;
	int status;

	ce_services = hif_state->ce_services;
	qdf_spin_lock_bh(&CE_state->ce_index_lock);
	status =
		ce_services->ce_completed_send_next_nolock(CE_state,
					per_CE_contextp, per_transfer_contextp,
					bufferp, nbytesp, transfer_idp, sw_idx,
					      hw_idx, toeplitz_hash_result);
	qdf_spin_unlock_bh(&CE_state->ce_index_lock);

	return status;
}

#ifdef ATH_11AC_TXCOMPACT
/* CE engine descriptor reap
 * Similar to ce_per_engine_service , Only difference is ce_per_engine_service
 * does receive and reaping of completed descriptor ,
 * This function only handles reaping of Tx complete descriptor.
 * The Function is called from threshold reap  poll routine
 * hif_send_complete_check so should not countain receive functionality
 * within it .
 */

void ce_per_engine_servicereap(struct hif_softc *scn, unsigned int ce_id)
{
	void *CE_context;
	void *transfer_context;
	qdf_dma_addr_t buf;
	unsigned int nbytes;
	unsigned int id;
	unsigned int sw_idx, hw_idx;
	uint32_t toeplitz_hash_result;
	struct CE_state *CE_state = scn->ce_id_to_state[ce_id];
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);

	if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
		return;

	hif_record_ce_desc_event(scn, ce_id, HIF_CE_REAP_ENTRY,
			NULL, NULL, 0, 0);

	/* Since this function is called from both user context and
	 * tasklet context the spinlock has to lock the bottom halves.
	 * This fix assumes that ATH_11AC_TXCOMPACT flag is always
	 * enabled in TX polling mode. If this is not the case, more
	 * bottom halve spin lock changes are needed. Due to data path
	 * performance concern, after internal discussion we've decided
	 * to make minimum change, i.e., only address the issue occurred
	 * in this function. The possible negative effect of this minimum
	 * change is that, in the future, if some other function will also
	 * be opened to let the user context to use, those cases need to be
	 * addressed by change spin_lock to spin_lock_bh also.
	 */

	qdf_spin_lock_bh(&CE_state->ce_index_lock);

	if (CE_state->send_cb) {
		{
			struct ce_ops *ce_services = hif_state->ce_services;
			/* Pop completed send buffers and call the
			 * registered send callback for each
			 */
			while (ce_services->ce_completed_send_next_nolock
				 (CE_state, &CE_context,
				  &transfer_context, &buf,
				  &nbytes, &id, &sw_idx, &hw_idx,
				  &toeplitz_hash_result) ==
				  QDF_STATUS_SUCCESS) {
				if (ce_id != CE_HTT_H2T_MSG) {
					qdf_spin_unlock_bh(
						&CE_state->ce_index_lock);
					CE_state->send_cb(
						(struct CE_handle *)
						CE_state, CE_context,
						transfer_context, buf,
						nbytes, id, sw_idx, hw_idx,
						toeplitz_hash_result);
					qdf_spin_lock_bh(
						&CE_state->ce_index_lock);
				} else {
					struct HIF_CE_pipe_info *pipe_info =
						(struct HIF_CE_pipe_info *)
						CE_context;

					qdf_spin_lock_bh(&pipe_info->
						 completion_freeq_lock);
					pipe_info->num_sends_allowed++;
					qdf_spin_unlock_bh(&pipe_info->
						   completion_freeq_lock);
				}
			}
		}
	}

	qdf_spin_unlock_bh(&CE_state->ce_index_lock);

	hif_record_ce_desc_event(scn, ce_id, HIF_CE_REAP_EXIT,
			NULL, NULL, 0, 0);
	Q_TARGET_ACCESS_END(scn);
}

#endif /*ATH_11AC_TXCOMPACT */

/*
 * ce_engine_service_reg:
 *
 * Called from ce_per_engine_service and goes through the regular interrupt
 * handling that does not involve the WLAN fast path feature.
 *
 * Returns void
 */
void ce_engine_service_reg(struct hif_softc *scn, int CE_id)
{
	struct CE_state *CE_state = scn->ce_id_to_state[CE_id];
	uint32_t ctrl_addr = CE_state->ctrl_addr;
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
	void *CE_context;
	void *transfer_context;
	qdf_dma_addr_t buf;
	unsigned int nbytes;
	unsigned int id;
	unsigned int flags;
	unsigned int more_comp_cnt = 0;
	unsigned int more_snd_comp_cnt = 0;
	unsigned int sw_idx, hw_idx;
	uint32_t toeplitz_hash_result;
	uint32_t mode = hif_get_conparam(scn);

more_completions:
	if (CE_state->recv_cb) {

		/* Pop completed recv buffers and call
		 * the registered recv callback for each
		 */
		while (hif_state->ce_services->ce_completed_recv_next_nolock
				(CE_state, &CE_context, &transfer_context,
				&buf, &nbytes, &id, &flags) ==
				QDF_STATUS_SUCCESS) {
			qdf_spin_unlock(&CE_state->ce_index_lock);
			CE_state->recv_cb((struct CE_handle *)CE_state,
					  CE_context, transfer_context, buf,
					  nbytes, id, flags);

			qdf_spin_lock(&CE_state->ce_index_lock);
			/*
			 * EV #112693 -
			 * [Peregrine][ES1][WB342][Win8x86][Performance]
			 * BSoD_0x133 occurred in VHT80 UDP_DL
			 * Break out DPC by force if number of loops in
			 * hif_pci_ce_recv_data reaches MAX_NUM_OF_RECEIVES
			 * to avoid spending too long time in
			 * DPC for each interrupt handling. Schedule another
			 * DPC to avoid data loss if we had taken
			 * force-break action before apply to Windows OS
			 * only currently, Linux/MAC os can expand to their
			 * platform if necessary
			 */

			/* Break the receive processes by
			 * force if force_break set up
			 */
			if (qdf_unlikely(CE_state->force_break)) {
				qdf_atomic_set(&CE_state->rx_pending, 1);
				return;
			}
		}
	}

	/*
	 * Attention: We may experience potential infinite loop for below
	 * While Loop during Sending Stress test.
	 * Resolve the same way as Receive Case (Refer to EV #112693)
	 */

	if (CE_state->send_cb) {
		/* Pop completed send buffers and call
		 * the registered send callback for each
		 */

#ifdef ATH_11AC_TXCOMPACT
		while (hif_state->ce_services->ce_completed_send_next_nolock
			 (CE_state, &CE_context,
			 &transfer_context, &buf, &nbytes,
			 &id, &sw_idx, &hw_idx,
			 &toeplitz_hash_result) == QDF_STATUS_SUCCESS) {

			if (CE_id != CE_HTT_H2T_MSG ||
			    QDF_IS_EPPING_ENABLED(mode)) {
				qdf_spin_unlock(&CE_state->ce_index_lock);
				CE_state->send_cb((struct CE_handle *)CE_state,
						  CE_context, transfer_context,
						  buf, nbytes, id, sw_idx,
						  hw_idx, toeplitz_hash_result);
				qdf_spin_lock(&CE_state->ce_index_lock);
			} else {
				struct HIF_CE_pipe_info *pipe_info =
					(struct HIF_CE_pipe_info *)CE_context;

				qdf_spin_lock_bh(&pipe_info->
					      completion_freeq_lock);
				pipe_info->num_sends_allowed++;
				qdf_spin_unlock_bh(&pipe_info->
						completion_freeq_lock);
			}
		}
#else                           /*ATH_11AC_TXCOMPACT */
		while (hif_state->ce_services->ce_completed_send_next_nolock
			 (CE_state, &CE_context,
			  &transfer_context, &buf, &nbytes,
			  &id, &sw_idx, &hw_idx,
			  &toeplitz_hash_result) == QDF_STATUS_SUCCESS) {
			qdf_spin_unlock(&CE_state->ce_index_lock);
			CE_state->send_cb((struct CE_handle *)CE_state,
				  CE_context, transfer_context, buf,
				  nbytes, id, sw_idx, hw_idx,
				  toeplitz_hash_result);
			qdf_spin_lock(&CE_state->ce_index_lock);
		}
#endif /*ATH_11AC_TXCOMPACT */
	}

more_watermarks:
	if (CE_state->misc_cbs) {
		if (CE_state->watermark_cb &&
				hif_state->ce_services->watermark_int(CE_state,
					&flags)) {
			qdf_spin_unlock(&CE_state->ce_index_lock);
			/* Convert HW IS bits to software flags */
			CE_state->watermark_cb((struct CE_handle *)CE_state,
					CE_state->wm_context, flags);
			qdf_spin_lock(&CE_state->ce_index_lock);
		}
	}

	/*
	 * Clear the misc interrupts (watermark) that were handled above,
	 * and that will be checked again below.
	 * Clear and check for copy-complete interrupts again, just in case
	 * more copy completions happened while the misc interrupts were being
	 * handled.
	 */
	if (!ce_srng_based(scn)) {
		if (TARGET_REGISTER_ACCESS_ALLOWED(scn)) {
			CE_ENGINE_INT_STATUS_CLEAR(scn, ctrl_addr,
					   CE_WATERMARK_MASK |
					   HOST_IS_COPY_COMPLETE_MASK);
		} else {
			qdf_atomic_set(&CE_state->rx_pending, 0);
			hif_err_rl("%s: target access is not allowed",
				   __func__);
			return;
		}
	}

	/*
	 * Now that per-engine interrupts are cleared, verify that
	 * no recv interrupts arrive while processing send interrupts,
	 * and no recv or send interrupts happened while processing
	 * misc interrupts.Go back and check again.Keep checking until
	 * we find no more events to process.
	 */
	if (CE_state->recv_cb &&
		hif_state->ce_services->ce_recv_entries_done_nolock(scn,
				CE_state)) {
		if (QDF_IS_EPPING_ENABLED(mode) ||
		    more_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) {
			goto more_completions;
		} else {
			if (!ce_srng_based(scn)) {
				HIF_ERROR(
					"%s:Potential infinite loop detected during Rx processing nentries_mask:0x%x sw read_idx:0x%x hw read_idx:0x%x",
					__func__,
					CE_state->dest_ring->nentries_mask,
					CE_state->dest_ring->sw_index,
					CE_DEST_RING_READ_IDX_GET(scn,
							  CE_state->ctrl_addr));
			}
		}
	}

	if (CE_state->send_cb &&
		hif_state->ce_services->ce_send_entries_done_nolock(scn,
				CE_state)) {
		if (QDF_IS_EPPING_ENABLED(mode) ||
		    more_snd_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) {
			goto more_completions;
		} else {
			if (!ce_srng_based(scn)) {
				HIF_ERROR(
					"%s:Potential infinite loop detected during send completion nentries_mask:0x%x sw read_idx:0x%x hw read_idx:0x%x",
					__func__,
					CE_state->src_ring->nentries_mask,
					CE_state->src_ring->sw_index,
					CE_SRC_RING_READ_IDX_GET(scn,
							 CE_state->ctrl_addr));
			}
		}
	}

	if (CE_state->misc_cbs && CE_state->watermark_cb) {
		if (hif_state->ce_services->watermark_int(CE_state, &flags))
			goto more_watermarks;
	}

	qdf_atomic_set(&CE_state->rx_pending, 0);
}

/*
 * Guts of interrupt handler for per-engine interrupts on a particular CE.
 *
 * Invokes registered callbacks for recv_complete,
 * send_complete, and watermarks.
 *
 * Returns: number of messages processed
 */
int ce_per_engine_service(struct hif_softc *scn, unsigned int CE_id)
{
	struct CE_state *CE_state = scn->ce_id_to_state[CE_id];

	if (hif_is_nss_wifi_enabled(scn) && (CE_state->htt_rx_data))
		return CE_state->receive_count;

	if (Q_TARGET_ACCESS_BEGIN(scn) < 0) {
		HIF_ERROR("[premature rc=0]");
		return 0; /* no work done */
	}

	/* Clear force_break flag and re-initialize receive_count to 0 */
	CE_state->receive_count = 0;
	CE_state->force_break = 0;
	CE_state->ce_service_start_time = sched_clock();
	CE_state->ce_service_yield_time =
		CE_state->ce_service_start_time +
		hif_get_ce_service_max_yield_time(
			(struct hif_opaque_softc *)scn);

	qdf_spin_lock(&CE_state->ce_index_lock);

	CE_state->service(scn, CE_id);

	qdf_spin_unlock(&CE_state->ce_index_lock);

	if (Q_TARGET_ACCESS_END(scn) < 0)
		HIF_ERROR("<--[premature rc=%d]", CE_state->receive_count);
	return CE_state->receive_count;
}
qdf_export_symbol(ce_per_engine_service);

/*
 * Handler for per-engine interrupts on ALL active CEs.
 * This is used in cases where the system is sharing a
 * single interrput for all CEs
 */

void ce_per_engine_service_any(int irq, struct hif_softc *scn)
{
	int CE_id;
	uint32_t intr_summary;

	if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
		return;

	if (!qdf_atomic_read(&scn->tasklet_from_intr)) {
		for (CE_id = 0; CE_id < scn->ce_count; CE_id++) {
			struct CE_state *CE_state = scn->ce_id_to_state[CE_id];

			if (qdf_atomic_read(&CE_state->rx_pending)) {
				qdf_atomic_set(&CE_state->rx_pending, 0);
				ce_per_engine_service(scn, CE_id);
			}
		}

		Q_TARGET_ACCESS_END(scn);
		return;
	}

	intr_summary = CE_INTERRUPT_SUMMARY(scn);

	for (CE_id = 0; intr_summary && (CE_id < scn->ce_count); CE_id++) {
		if (intr_summary & (1 << CE_id))
			intr_summary &= ~(1 << CE_id);
		else
			continue;       /* no intr pending on this CE */

		ce_per_engine_service(scn, CE_id);
	}

	Q_TARGET_ACCESS_END(scn);
}

/*Iterate the CE_state list and disable the compl interrupt
 * if it has been registered already.
 */
void ce_disable_any_copy_compl_intr_nolock(struct hif_softc *scn)
{
	int CE_id;

	if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
		return;

	for (CE_id = 0; CE_id < scn->ce_count; CE_id++) {
		struct CE_state *CE_state = scn->ce_id_to_state[CE_id];
		uint32_t ctrl_addr = CE_state->ctrl_addr;

		/* if the interrupt is currently enabled, disable it */
		if (!CE_state->disable_copy_compl_intr
		    && (CE_state->send_cb || CE_state->recv_cb))
			CE_COPY_COMPLETE_INTR_DISABLE(scn, ctrl_addr);

		if (CE_state->watermark_cb)
			CE_WATERMARK_INTR_DISABLE(scn, ctrl_addr);
	}
	Q_TARGET_ACCESS_END(scn);
}

void ce_enable_any_copy_compl_intr_nolock(struct hif_softc *scn)
{
	int CE_id;

	if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
		return;

	for (CE_id = 0; CE_id < scn->ce_count; CE_id++) {
		struct CE_state *CE_state = scn->ce_id_to_state[CE_id];
		uint32_t ctrl_addr = CE_state->ctrl_addr;

		/*
		 * If the CE is supposed to have copy complete interrupts
		 * enabled (i.e. there a callback registered, and the
		 * "disable" flag is not set), then re-enable the interrupt.
		 */
		if (!CE_state->disable_copy_compl_intr
		    && (CE_state->send_cb || CE_state->recv_cb))
			CE_COPY_COMPLETE_INTR_ENABLE(scn, ctrl_addr);

		if (CE_state->watermark_cb)
			CE_WATERMARK_INTR_ENABLE(scn, ctrl_addr);
	}
	Q_TARGET_ACCESS_END(scn);
}

/**
 * ce_send_cb_register(): register completion handler
 * @copyeng: CE_state representing the ce we are adding the behavior to
 * @fn_ptr: callback that the ce should use when processing tx completions
 * @disable_interrupts: if the interupts should be enabled or not.
 *
 * Caller should guarantee that no transactions are in progress before
 * switching the callback function.
 *
 * Registers the send context before the fn pointer so that if the cb is valid
 * the context should be valid.
 *
 * Beware that currently this function will enable completion interrupts.
 */
void
ce_send_cb_register(struct CE_handle *copyeng,
		    ce_send_cb fn_ptr,
		    void *ce_send_context, int disable_interrupts)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	struct hif_softc *scn;
	struct HIF_CE_state *hif_state;

	if (CE_state == NULL) {
		HIF_ERROR("%s: Error CE state = NULL", __func__);
		return;
	}
	scn = CE_state->scn;
	hif_state = HIF_GET_CE_STATE(scn);
	if (hif_state == NULL) {
		HIF_ERROR("%s: Error HIF state = NULL", __func__);
		return;
	}
	CE_state->send_context = ce_send_context;
	CE_state->send_cb = fn_ptr;
	hif_state->ce_services->ce_per_engine_handler_adjust(CE_state,
							disable_interrupts);
}
qdf_export_symbol(ce_send_cb_register);

/**
 * ce_recv_cb_register(): register completion handler
 * @copyeng: CE_state representing the ce we are adding the behavior to
 * @fn_ptr: callback that the ce should use when processing rx completions
 * @disable_interrupts: if the interupts should be enabled or not.
 *
 * Registers the send context before the fn pointer so that if the cb is valid
 * the context should be valid.
 *
 * Caller should guarantee that no transactions are in progress before
 * switching the callback function.
 */
void
ce_recv_cb_register(struct CE_handle *copyeng,
		    CE_recv_cb fn_ptr,
		    void *CE_recv_context, int disable_interrupts)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	struct hif_softc *scn;
	struct HIF_CE_state *hif_state;

	if (CE_state == NULL) {
		HIF_ERROR("%s: ERROR CE state = NULL", __func__);
		return;
	}
	scn = CE_state->scn;
	hif_state = HIF_GET_CE_STATE(scn);
	if (hif_state == NULL) {
		HIF_ERROR("%s: Error HIF state = NULL", __func__);
		return;
	}
	CE_state->recv_context = CE_recv_context;
	CE_state->recv_cb = fn_ptr;
	hif_state->ce_services->ce_per_engine_handler_adjust(CE_state,
							disable_interrupts);
}
qdf_export_symbol(ce_recv_cb_register);

/**
 * ce_watermark_cb_register(): register completion handler
 * @copyeng: CE_state representing the ce we are adding the behavior to
 * @fn_ptr: callback that the ce should use when processing watermark events
 *
 * Caller should guarantee that no watermark events are being processed before
 * switching the callback function.
 */
void
ce_watermark_cb_register(struct CE_handle *copyeng,
			 CE_watermark_cb fn_ptr, void *CE_wm_context)
{
	struct CE_state *CE_state = (struct CE_state *)copyeng;
	struct hif_softc *scn = CE_state->scn;
	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);

	CE_state->watermark_cb = fn_ptr;
	CE_state->wm_context = CE_wm_context;
	hif_state->ce_services->ce_per_engine_handler_adjust(CE_state,
							0);
	if (fn_ptr)
		CE_state->misc_cbs = 1;
}

bool ce_get_rx_pending(struct hif_softc *scn)
{
	int CE_id;

	for (CE_id = 0; CE_id < scn->ce_count; CE_id++) {
		struct CE_state *CE_state = scn->ce_id_to_state[CE_id];

		if (qdf_atomic_read(&CE_state->rx_pending))
			return true;
	}

	return false;
}

/**
 * ce_check_rx_pending() - ce_check_rx_pending
 * @CE_state: context of the copy engine to check
 *
 * Return: true if there per_engine_service
 *	didn't process all the rx descriptors.
 */
bool ce_check_rx_pending(struct CE_state *CE_state)
{
	if (qdf_atomic_read(&CE_state->rx_pending))
		return true;
	else
		return false;
}
qdf_export_symbol(ce_check_rx_pending);

#ifdef IPA_OFFLOAD
/**
 * ce_ipa_get_resource() - get uc resource on copyengine
 * @ce: copyengine context
 * @ce_sr: copyengine source ring resource info
 * @ce_sr_ring_size: copyengine source ring size
 * @ce_reg_paddr: copyengine register physical address
 *
 * Copy engine should release resource to micro controller
 * Micro controller needs
 *  - Copy engine source descriptor base address
 *  - Copy engine source descriptor size
 *  - PCI BAR address to access copy engine regiser
 *
 * Return: None
 */
void ce_ipa_get_resource(struct CE_handle *ce,
			 qdf_shared_mem_t **ce_sr,
			 uint32_t *ce_sr_ring_size,
			 qdf_dma_addr_t *ce_reg_paddr)
{
	struct CE_state *CE_state = (struct CE_state *)ce;
	uint32_t ring_loop;
	struct CE_src_desc *ce_desc;
	qdf_dma_addr_t phy_mem_base;
	struct hif_softc *scn = CE_state->scn;

	if (CE_UNUSED == CE_state->state) {
		*qdf_mem_get_dma_addr_ptr(scn->qdf_dev,
			&CE_state->scn->ipa_ce_ring->mem_info) = 0;
		*ce_sr_ring_size = 0;
		return;
	}

	/* Update default value for descriptor */
	for (ring_loop = 0; ring_loop < CE_state->src_ring->nentries;
	     ring_loop++) {
		ce_desc = (struct CE_src_desc *)
			  ((char *)CE_state->src_ring->base_addr_owner_space +
			   ring_loop * (sizeof(struct CE_src_desc)));
		CE_IPA_RING_INIT(ce_desc);
	}

	/* Get BAR address */
	hif_read_phy_mem_base(CE_state->scn, &phy_mem_base);

	*ce_sr = CE_state->scn->ipa_ce_ring;
	*ce_sr_ring_size = (uint32_t)(CE_state->src_ring->nentries *
		sizeof(struct CE_src_desc));
	*ce_reg_paddr = phy_mem_base + CE_BASE_ADDRESS(CE_state->id) +
			SR_WR_INDEX_ADDRESS;
}
#endif /* IPA_OFFLOAD */

#ifdef HIF_CE_DEBUG_DATA_BUF
/**
 * hif_dump_desc_data_buf() - record ce descriptor events
 * @buf: buffer to copy to
 * @pos: Current position till which the buf is filled
 * @data: Data to be copied
 * @data_len: Length of the data to be copied
 */
static uint32_t hif_dump_desc_data_buf(uint8_t *buf, ssize_t pos,
					uint8_t *data, uint32_t data_len)
{
	pos += snprintf(buf + pos, PAGE_SIZE - pos, "Data:(Max%dBytes)\n",
			CE_DEBUG_MAX_DATA_BUF_SIZE);

	if ((data_len > 0) && data) {
		if (data_len < 16) {
			hex_dump_to_buffer(data,
						CE_DEBUG_DATA_PER_ROW,
						16, 1, buf + pos,
						(ssize_t)PAGE_SIZE - pos,
						false);
			pos += CE_DEBUG_PRINT_BUF_SIZE(data_len);
			pos += snprintf(buf + pos, PAGE_SIZE - pos, "\n");
		} else {
			uint32_t rows = (data_len / 16) + 1;
			uint32_t row = 0;

			for (row = 0; row < rows; row++) {
				hex_dump_to_buffer(data + (row * 16),
							CE_DEBUG_DATA_PER_ROW,
							16, 1, buf + pos,
							(ssize_t)PAGE_SIZE
							- pos, false);
				pos +=
				CE_DEBUG_PRINT_BUF_SIZE(CE_DEBUG_DATA_PER_ROW);
				pos += snprintf(buf + pos, PAGE_SIZE - pos,
						"\n");
			}
		}
	}

	return pos;
}
#endif

/*
 * Note: For MCL, #if defined (HIF_CONFIG_SLUB_DEBUG_ON) needs to be checked
 * for defined here
 */
#if defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF)
static const char *ce_event_type_to_str(enum hif_ce_event_type type)
{
	switch (type) {
	case HIF_RX_DESC_POST:
		return "HIF_RX_DESC_POST";
	case HIF_RX_DESC_COMPLETION:
		return "HIF_RX_DESC_COMPLETION";
	case HIF_TX_GATHER_DESC_POST:
		return "HIF_TX_GATHER_DESC_POST";
	case HIF_TX_DESC_POST:
		return "HIF_TX_DESC_POST";
	case HIF_TX_DESC_SOFTWARE_POST:
		return "HIF_TX_DESC_SOFTWARE_POST";
	case HIF_TX_DESC_COMPLETION:
		return "HIF_TX_DESC_COMPLETION";
	case FAST_RX_WRITE_INDEX_UPDATE:
		return "FAST_RX_WRITE_INDEX_UPDATE";
	case FAST_RX_SOFTWARE_INDEX_UPDATE:
		return "FAST_RX_SOFTWARE_INDEX_UPDATE";
	case FAST_TX_WRITE_INDEX_UPDATE:
		return "FAST_TX_WRITE_INDEX_UPDATE";
	case FAST_TX_WRITE_INDEX_SOFTWARE_UPDATE:
		return "FAST_TX_WRITE_INDEX_SOFTWARE_UPDATE";
	case FAST_TX_SOFTWARE_INDEX_UPDATE:
		return "FAST_TX_SOFTWARE_INDEX_UPDATE";
	case RESUME_WRITE_INDEX_UPDATE:
		return "RESUME_WRITE_INDEX_UPDATE";
	case HIF_IRQ_EVENT:
		return "HIF_IRQ_EVENT";
	case HIF_CE_TASKLET_ENTRY:
		return "HIF_CE_TASKLET_ENTRY";
	case HIF_CE_TASKLET_RESCHEDULE:
		return "HIF_CE_TASKLET_RESCHEDULE";
	case HIF_CE_TASKLET_EXIT:
		return "HIF_CE_TASKLET_EXIT";
	case HIF_CE_REAP_ENTRY:
		return "HIF_CE_REAP_ENTRY";
	case HIF_CE_REAP_EXIT:
		return "HIF_CE_REAP_EXIT";
	case NAPI_SCHEDULE:
		return "NAPI_SCHEDULE";
	case NAPI_POLL_ENTER:
		return "NAPI_POLL_ENTER";
	case NAPI_COMPLETE:
		return "NAPI_COMPLETE";
	case NAPI_POLL_EXIT:
		return "NAPI_POLL_EXIT";
	case HIF_RX_NBUF_ALLOC_FAILURE:
		return "HIF_RX_NBUF_ALLOC_FAILURE";
	case HIF_RX_NBUF_MAP_FAILURE:
		return "HIF_RX_NBUF_MAP_FAILURE";
	case HIF_RX_NBUF_ENQUEUE_FAILURE:
		return "HIF_RX_NBUF_ENQUEUE_FAILURE";
	default:
		return "invalid";
	}
}

/**
 * hif_dump_desc_event() - record ce descriptor events
 * @buf: Buffer to which to be copied
 * @ce_id: which ce is the event occurring on
 * @index: index that the descriptor was/will be at.
 */
ssize_t hif_dump_desc_event(struct hif_softc *scn, char *buf)
{
	struct hif_ce_desc_event *event;
	uint64_t secs, usecs;
	ssize_t len = 0;
	struct ce_desc_hist *ce_hist = NULL;
	struct hif_ce_desc_event *hist_ev = NULL;

	if (!scn)
		return -EINVAL;

	ce_hist = &scn->hif_ce_desc_hist;

	if (ce_hist->hist_id >= CE_COUNT_MAX ||
	    ce_hist->hist_index >= HIF_CE_HISTORY_MAX) {
		qdf_print("Invalid values");
		return -EINVAL;
	}

	hist_ev =
		(struct hif_ce_desc_event *)ce_hist->hist_ev[ce_hist->hist_id];

	if (!hist_ev) {
		qdf_print("Low Memory");
		return -EINVAL;
	}

	event = &hist_ev[ce_hist->hist_index];

	qdf_log_timestamp_to_secs(event->time, &secs, &usecs);

	len += snprintf(buf, PAGE_SIZE - len,
			"\nTime:%lld.%06lld, CE:%d, EventType: %s, EventIndex: %d\nDataAddr=%pK",
			secs, usecs, ce_hist->hist_id,
			ce_event_type_to_str(event->type),
			event->index, event->memory);
#ifdef HIF_CE_DEBUG_DATA_BUF
	len += snprintf(buf + len, PAGE_SIZE - len, ", Data len=%d",
			event->actual_data_len);
#endif

	len += snprintf(buf + len, PAGE_SIZE - len, "\nCE descriptor: ");

	hex_dump_to_buffer(&event->descriptor, sizeof(union ce_desc),
				16, 1, buf + len,
				(ssize_t)PAGE_SIZE - len, false);
	len += CE_DEBUG_PRINT_BUF_SIZE(sizeof(union ce_desc));
	len += snprintf(buf + len, PAGE_SIZE - len, "\n");

#ifdef HIF_CE_DEBUG_DATA_BUF
	if (ce_hist->data_enable[ce_hist->hist_id])
		len = hif_dump_desc_data_buf(buf, len, event->data,
						(event->actual_data_len <
						 CE_DEBUG_MAX_DATA_BUF_SIZE) ?
						event->actual_data_len :
						CE_DEBUG_MAX_DATA_BUF_SIZE);
#endif /*HIF_CE_DEBUG_DATA_BUF*/

	len += snprintf(buf + len, PAGE_SIZE - len, "END\n");

	return len;
}

/*
 * hif_store_desc_trace_buf_index() -
 * API to get the CE id and CE debug storage buffer index
 *
 * @dev: network device
 * @attr: sysfs attribute
 * @buf: data got from the user
 *
 * Return total length
 */
ssize_t hif_input_desc_trace_buf_index(struct hif_softc *scn,
					const char *buf, size_t size)
{
	struct ce_desc_hist *ce_hist = NULL;

	if (!scn)
		return -EINVAL;

	ce_hist = &scn->hif_ce_desc_hist;

	if (!size) {
		pr_err("%s: Invalid input buffer.\n", __func__);
		return -EINVAL;
	}

	if (sscanf(buf, "%u %u", (unsigned int *)&ce_hist->hist_id,
		   (unsigned int *)&ce_hist->hist_index) != 2) {
		pr_err("%s: Invalid input value.\n", __func__);
		return -EINVAL;
	}
	if ((ce_hist->hist_id >= CE_COUNT_MAX) ||
	   (ce_hist->hist_index >= HIF_CE_HISTORY_MAX)) {
		qdf_print("Invalid values");
		return -EINVAL;
	}

	return size;
}

#endif /*defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF) */

#ifdef HIF_CE_DEBUG_DATA_BUF
/*
 * hif_ce_en_desc_hist() -
 * API to enable recording the CE desc history
 *
 * @dev: network device
 * @attr: sysfs attribute
 * @buf: buffer to copy the data.
 *
 * Starts recording the ce desc history
 *
 * Return total length copied
 */
ssize_t hif_ce_en_desc_hist(struct hif_softc *scn, const char *buf, size_t size)
{
	struct ce_desc_hist *ce_hist = NULL;
	uint32_t cfg = 0;
	uint32_t ce_id = 0;

	if (!scn)
		return -EINVAL;

	ce_hist = &scn->hif_ce_desc_hist;

	if (!size) {
		pr_err("%s: Invalid input buffer.\n", __func__);
		return -EINVAL;
	}

	if (sscanf(buf, "%u %u", (unsigned int *)&ce_id,
		   (unsigned int *)&cfg) != 2) {
		pr_err("%s: Invalid input: Enter CE Id<sp><1/0>.\n", __func__);
		return -EINVAL;
	}
	if (ce_id >= CE_COUNT_MAX) {
		qdf_print("Invalid value CE Id");
		return -EINVAL;
	}

	if ((cfg > 1 || cfg < 0)) {
		qdf_print("Invalid values: enter 0 or 1");
		return -EINVAL;
	}

	if (!ce_hist->hist_ev[ce_id])
		return -EINVAL;

	qdf_mutex_acquire(&ce_hist->ce_dbg_datamem_lock[ce_id]);
	if (cfg == 1) {
		if (ce_hist->data_enable[ce_id] == 1) {
			qdf_print("\nAlready Enabled");
		} else {
			if (alloc_mem_ce_debug_hist_data(scn, ce_id)
							== QDF_STATUS_E_NOMEM){
				ce_hist->data_enable[ce_id] = 0;
				qdf_print("%s:Memory Alloc failed");
			} else
				ce_hist->data_enable[ce_id] = 1;
		}
	} else if (cfg == 0) {
		if (ce_hist->data_enable[ce_id] == 0) {
			qdf_print("\nAlready Disabled");
		} else {
			ce_hist->data_enable[ce_id] = 0;
				free_mem_ce_debug_hist_data(scn, ce_id);
		}
	}
	qdf_mutex_release(&ce_hist->ce_dbg_datamem_lock[ce_id]);

	return size;
}

/*
 * hif_disp_ce_enable_desc_data_hist() -
 * API to display value of data_enable
 *
 * @dev: network device
 * @attr: sysfs attribute
 * @buf: buffer to copy the data.
 *
 * Return total length copied
 */
ssize_t hif_disp_ce_enable_desc_data_hist(struct hif_softc *scn, char *buf)
{
	ssize_t len = 0;
	uint32_t ce_id = 0;
	struct ce_desc_hist *ce_hist = NULL;

	if (!scn)
		return -EINVAL;

	ce_hist = &scn->hif_ce_desc_hist;

	for (ce_id = 0; ce_id < CE_COUNT_MAX; ce_id++) {
		len += snprintf(buf + len, PAGE_SIZE - len, " CE%d: %d\n",
				ce_id, ce_hist->data_enable[ce_id]);
	}

	return len;
}
#endif /* HIF_CE_DEBUG_DATA_BUF */

#ifdef OL_ATH_SMART_LOGGING
#define GUARD_SPACE 10
#define LOG_ID_SZ 4
/*
 * hif_log_src_ce_dump() - Copy all the CE SRC ring to buf
 * @src_ring: SRC ring state
 * @buf_cur: Current pointer in ring buffer
 * @buf_init:Start of the ring buffer
 * @buf_sz: Size of the ring buffer
 * @skb_sz: Max size of the SKB buffer to be copied
 *
 * Dumps all the CE SRC ring descriptors and buffers pointed by them in to
 * the given buf, skb_sz is the max buffer size to be copied
 *
 * Return: Current pointer in ring buffer
 */
static uint8_t *hif_log_src_ce_dump(struct CE_ring_state *src_ring,
				    uint8_t *buf_cur, uint8_t *buf_init,
				    uint32_t buf_sz, uint32_t skb_sz)
{
	struct CE_src_desc *src_ring_base;
	uint32_t len, entry;
	struct CE_src_desc  *src_desc;
	qdf_nbuf_t nbuf;
	uint32_t available_buf;

	src_ring_base = (struct CE_src_desc *)src_ring->base_addr_owner_space;
	len = sizeof(struct CE_ring_state);
	available_buf = buf_sz - (buf_cur - buf_init);
	if (available_buf < (len + GUARD_SPACE)) {
		buf_cur = buf_init;
	}

	qdf_mem_copy(buf_cur, src_ring, sizeof(struct CE_ring_state));
	buf_cur += sizeof(struct CE_ring_state);

	for (entry = 0; entry < src_ring->nentries; entry++) {
		src_desc = CE_SRC_RING_TO_DESC(src_ring_base, entry);
		nbuf = src_ring->per_transfer_context[entry];
		if (nbuf) {
			uint32_t skb_len  = qdf_nbuf_len(nbuf);
			uint32_t skb_cp_len = qdf_min(skb_len, skb_sz);

			len = sizeof(struct CE_src_desc) + skb_cp_len
				+ LOG_ID_SZ + sizeof(skb_cp_len);
			available_buf = buf_sz - (buf_cur - buf_init);
			if (available_buf < (len + GUARD_SPACE)) {
				buf_cur = buf_init;
			}
			qdf_mem_copy(buf_cur, src_desc,
				     sizeof(struct CE_src_desc));
			buf_cur += sizeof(struct CE_src_desc);

			available_buf = buf_sz - (buf_cur - buf_init);
			buf_cur += snprintf(buf_cur, available_buf, "SKB%d",
						skb_cp_len);

			if (skb_cp_len) {
				qdf_mem_copy(buf_cur, qdf_nbuf_data(nbuf),
					     skb_cp_len);
				buf_cur += skb_cp_len;
			}
		} else {
			len = sizeof(struct CE_src_desc) + LOG_ID_SZ;
			available_buf = buf_sz - (buf_cur - buf_init);
			if (available_buf < (len + GUARD_SPACE)) {
				buf_cur = buf_init;
			}
			qdf_mem_copy(buf_cur, src_desc,
				     sizeof(struct CE_src_desc));
			buf_cur += sizeof(struct CE_src_desc);
			available_buf = buf_sz - (buf_cur - buf_init);
			buf_cur += snprintf(buf_cur, available_buf, "NUL");
		}
	}

	return buf_cur;
}

/*
 * hif_log_dest_ce_dump() - Copy all the CE DEST ring to buf
 * @dest_ring: SRC ring state
 * @buf_cur: Current pointer in ring buffer
 * @buf_init:Start of the ring buffer
 * @buf_sz: Size of the ring buffer
 * @skb_sz: Max size of the SKB buffer to be copied
 *
 * Dumps all the CE SRC ring descriptors and buffers pointed by them in to
 * the given buf, skb_sz is the max buffer size to be copied
 *
 * Return: Current pointer in ring buffer
 */
static uint8_t *hif_log_dest_ce_dump(struct CE_ring_state *dest_ring,
				     uint8_t *buf_cur, uint8_t *buf_init,
				     uint32_t buf_sz, uint32_t skb_sz)
{
	struct CE_dest_desc *dest_ring_base;
	uint32_t len, entry;
	struct CE_dest_desc  *dest_desc;
	qdf_nbuf_t nbuf;
	uint32_t available_buf;

	dest_ring_base =
		(struct CE_dest_desc *)dest_ring->base_addr_owner_space;

	len = sizeof(struct CE_ring_state);
	available_buf = buf_sz - (buf_cur - buf_init);
	if (available_buf < (len + GUARD_SPACE)) {
		buf_cur = buf_init;
	}

	qdf_mem_copy(buf_cur, dest_ring, sizeof(struct CE_ring_state));
	buf_cur += sizeof(struct CE_ring_state);

	for (entry = 0; entry < dest_ring->nentries; entry++) {
		dest_desc = CE_DEST_RING_TO_DESC(dest_ring_base, entry);

		nbuf = dest_ring->per_transfer_context[entry];
		if (nbuf) {
			uint32_t skb_len  = qdf_nbuf_len(nbuf);
			uint32_t skb_cp_len = qdf_min(skb_len, skb_sz);

			len = sizeof(struct CE_dest_desc) + skb_cp_len
				+ LOG_ID_SZ + sizeof(skb_cp_len);

			available_buf = buf_sz - (buf_cur - buf_init);
			if (available_buf < (len + GUARD_SPACE)) {
				buf_cur = buf_init;
			}

			qdf_mem_copy(buf_cur, dest_desc,
				     sizeof(struct CE_dest_desc));
			buf_cur += sizeof(struct CE_dest_desc);
			available_buf = buf_sz - (buf_cur - buf_init);
			buf_cur += snprintf(buf_cur, available_buf, "SKB%d",
						skb_cp_len);
			if (skb_cp_len) {
				qdf_mem_copy(buf_cur, qdf_nbuf_data(nbuf),
					     skb_cp_len);
				buf_cur += skb_cp_len;
			}
		} else {
			len = sizeof(struct CE_dest_desc) + LOG_ID_SZ;
			available_buf = buf_sz - (buf_cur - buf_init);
			if (available_buf < (len + GUARD_SPACE)) {
				buf_cur = buf_init;
			}
			qdf_mem_copy(buf_cur, dest_desc,
				     sizeof(struct CE_dest_desc));
			buf_cur += sizeof(struct CE_dest_desc);
			available_buf = buf_sz - (buf_cur - buf_init);
			buf_cur += snprintf(buf_cur, available_buf, "NUL");
		}
	}
	return buf_cur;
}

/**
 * hif_log_ce_dump() - Copy all the CE DEST ring to buf
 * Calls the respective function to dump all the CE SRC/DEST ring descriptors
 * and buffers pointed by them in to the given buf
 */
uint8_t *hif_log_dump_ce(struct hif_softc *scn, uint8_t *buf_cur,
			 uint8_t *buf_init, uint32_t buf_sz,
			 uint32_t ce, uint32_t skb_sz)
{
	struct CE_state *ce_state;
	struct CE_ring_state *src_ring;
	struct CE_ring_state *dest_ring;

	ce_state = scn->ce_id_to_state[ce];
	src_ring = ce_state->src_ring;
	dest_ring = ce_state->dest_ring;

	if (src_ring) {
		buf_cur = hif_log_src_ce_dump(src_ring, buf_cur,
					      buf_init, buf_sz, skb_sz);
	} else if (dest_ring) {
		buf_cur = hif_log_dest_ce_dump(dest_ring, buf_cur,
					       buf_init, buf_sz, skb_sz);
	}

	return buf_cur;
}

qdf_export_symbol(hif_log_dump_ce);
#endif /* OL_ATH_SMART_LOGGING */

