/*
 * DHD debug ring API and structures - implementation
 *
 * Copyright (C) 2020, Broadcom.
 *
 *      Unless you and Broadcom execute a separate written software license
 * agreement governing use of this software, this software is licensed to you
 * under the terms of the GNU General Public License version 2 (the "GPL"),
 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
 * following added to such license:
 *
 *      As a special exception, the copyright holders of this software give you
 * permission to link this software with independent modules, and to copy and
 * distribute the resulting executable under terms of your choice, provided that
 * you also meet, for each linked independent module, the terms and conditions of
 * the license of that module.  An independent module is a module which is not
 * derived from this software.  The special exception does not apply to any
 * modifications of the software.
 *
 *
 * <<Broadcom-WL-IPTag/Open:>>
 *
 * $Id$
 */
#include <typedefs.h>
#include <osl.h>
#include <bcmutils.h>
#include <bcmendian.h>
#include <dngl_stats.h>
#include <dhd.h>
#include <dhd_dbg.h>
#include <dhd_dbg_ring.h>

dhd_dbg_ring_t *
dhd_dbg_ring_alloc_init(dhd_pub_t *dhd, uint16 ring_id,
	char *ring_name, uint32 ring_sz, void *allocd_buf,
	bool pull_inactive)
{
	dhd_dbg_ring_t *ring = NULL;
	int ret = 0;
	unsigned long flags = 0;

	ring = MALLOCZ(dhd->osh, sizeof(dhd_dbg_ring_t));
	if (!ring)
		goto fail;

	ret = dhd_dbg_ring_init(dhd, ring, ring_id,
			(uint8 *)ring_name, ring_sz,
			allocd_buf, pull_inactive);
	if (ret != BCME_OK) {
		DHD_ERROR(("%s: unable to init ring %s!\n",
				__FUNCTION__, ring_name));
		goto fail;
	}
	DHD_DBG_RING_LOCK(ring->lock, flags);
	ring->state = RING_ACTIVE;
	ring->threshold = 0;
	DHD_DBG_RING_UNLOCK(ring->lock, flags);

	return ring;

fail:
	if (ring) {
		dhd_dbg_ring_deinit(dhd, ring);
		ring->ring_buf = NULL;
		ring->ring_size = 0;
		MFREE(dhd->osh, ring, sizeof(dhd_dbg_ring_t));
	}
	return NULL;
}

void
dhd_dbg_ring_dealloc_deinit(void **ring_ptr, dhd_pub_t *dhd)
{
	dhd_dbg_ring_t *ring = NULL;
	dhd_dbg_ring_t **dbgring = (dhd_dbg_ring_t **)ring_ptr;

	if (!dbgring)
		return;

	ring = *dbgring;

	if (ring) {
		dhd_dbg_ring_deinit(dhd, ring);
		ring->ring_buf = NULL;
		ring->ring_size = 0;
		MFREE(dhd->osh, ring, sizeof(dhd_dbg_ring_t));
		*dbgring = NULL;
	}
}

int
dhd_dbg_ring_init(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring, uint16 id, uint8 *name,
		uint32 ring_sz, void *allocd_buf, bool pull_inactive)
{
	void *buf;
	unsigned long flags = 0;

	if (allocd_buf == NULL) {
		return BCME_NOMEM;
	} else {
		buf = allocd_buf;
	}

	ring->lock = DHD_DBG_RING_LOCK_INIT(dhdp->osh);

	DHD_DBG_RING_LOCK(ring->lock, flags);
	ring->id = id;
	strlcpy((char *)ring->name, (char *)name, sizeof(ring->name));
	ring->ring_size = ring_sz;
	ring->wp = ring->rp = 0;
	ring->ring_buf = buf;
	ring->threshold = DBGRING_FLUSH_THRESHOLD(ring);
	ring->state = RING_SUSPEND;
	ring->rem_len = 0;
	ring->sched_pull = TRUE;
	ring->pull_inactive = pull_inactive;
	DHD_DBG_RING_UNLOCK(ring->lock, flags);

	return BCME_OK;
}

void
dhd_dbg_ring_deinit(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring)
{
	unsigned long flags = 0;

	DHD_DBG_RING_LOCK(ring->lock, flags);
	ring->id = 0;
	ring->name[0] = 0;
	ring->wp = ring->rp = 0;
	memset(&ring->stat, 0, sizeof(ring->stat));
	ring->threshold = 0;
	ring->state = RING_STOP;
	DHD_DBG_RING_UNLOCK(ring->lock, flags);

	DHD_DBG_RING_LOCK_DEINIT(dhdp->osh, ring->lock);
}

void
dhd_dbg_ring_sched_pull(dhd_dbg_ring_t *ring, uint32 pending_len,
		os_pullreq_t pull_fn, void *os_pvt, const int id)
{
	unsigned long flags = 0;

	DHD_DBG_RING_LOCK(ring->lock, flags);
	/* if the current pending size is bigger than threshold and
	 * threshold is set
	 */
	if (ring->threshold > 0 &&
	   (pending_len >= ring->threshold) && ring->sched_pull) {
		/*
		 * Update the state and release the lock before calling
		 * the pull_fn. Do not transfer control to other layers
		 * with locks held. If the call back again calls into
		 * the same layer fro this context, can lead to deadlock.
		 */
		ring->sched_pull = FALSE;
		DHD_DBG_RING_UNLOCK(ring->lock, flags);
		pull_fn(os_pvt, id);
	} else {
		DHD_DBG_RING_UNLOCK(ring->lock, flags);
	}
}

uint32
dhd_dbg_ring_get_pending_len(dhd_dbg_ring_t *ring)
{
	uint32 pending_len = 0;
	unsigned long flags = 0;

	DHD_DBG_RING_LOCK(ring->lock, flags);
	if (ring->stat.written_bytes > ring->stat.read_bytes) {
		pending_len = ring->stat.written_bytes - ring->stat.read_bytes;
	} else if (ring->stat.written_bytes < ring->stat.read_bytes) {
		pending_len = PENDING_LEN_MAX - ring->stat.read_bytes + ring->stat.written_bytes;
	} else {
		pending_len = 0;
	}
	DHD_DBG_RING_UNLOCK(ring->lock, flags);

	return pending_len;
}

int
dhd_dbg_ring_push(dhd_dbg_ring_t *ring, dhd_dbg_ring_entry_t *hdr, void *data)
{
	unsigned long flags;
	uint32 w_len;
	uint32 avail_size;
	dhd_dbg_ring_entry_t *w_entry, *r_entry;

	if (!ring || !hdr || !data) {
		return BCME_BADARG;
	}

	DHD_DBG_RING_LOCK(ring->lock, flags);

	if (ring->state != RING_ACTIVE) {
		DHD_DBG_RING_UNLOCK(ring->lock, flags);
		return BCME_OK;
	}

	w_len = ENTRY_LENGTH(hdr);

	DHD_DBGIF(("%s: RING%d[%s] hdr->len=%u, w_len=%u, wp=%d, rp=%d, ring_start=0x%p;"
		" ring_size=%u\n",
		__FUNCTION__, ring->id, ring->name, hdr->len, w_len, ring->wp, ring->rp,
		ring->ring_buf, ring->ring_size));

	if (w_len > ring->ring_size) {
		DHD_DBG_RING_UNLOCK(ring->lock, flags);
		DHD_ERROR(("%s: RING%d[%s] w_len=%u, ring_size=%u,"
			" write size exceeds ring size !\n",
			__FUNCTION__, ring->id, ring->name, w_len, ring->ring_size));
		return BCME_ERROR;
	}
	/* Claim the space */
	do {
		avail_size = DBG_RING_CHECK_WRITE_SPACE(ring->rp, ring->wp, ring->ring_size);
		if (avail_size <= w_len) {
			/* Prepare the space */
			if (ring->rp <= ring->wp) {
				ring->tail_padded = TRUE;
				ring->rem_len = ring->ring_size - ring->wp;
				DHD_DBGIF(("%s: RING%d[%s] Insuffient tail space,"
					" rp=%d, wp=%d, rem_len=%d, ring_size=%d,"
					" avail_size=%d, w_len=%d\n", __FUNCTION__,
					ring->id, ring->name, ring->rp, ring->wp,
					ring->rem_len, ring->ring_size, avail_size,
					w_len));

				/* 0 pad insufficient tail space */
				memset((uint8 *)ring->ring_buf + ring->wp, 0, ring->rem_len);
				/* If read pointer is still at the beginning, make some room */
				if (ring->rp == 0) {
					r_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf +
						ring->rp);
					ring->rp += ENTRY_LENGTH(r_entry);
					ring->stat.read_bytes += ENTRY_LENGTH(r_entry);
					DHD_DBGIF(("%s: rp at 0, move by one entry length"
						" (%u bytes)\n",
						__FUNCTION__, (uint32)ENTRY_LENGTH(r_entry)));
				}
				if (ring->rp == ring->wp) {
					ring->rp = 0;
				}
				ring->wp = 0;
				DHD_DBGIF(("%s: new rp=%u, wp=%u\n",
					__FUNCTION__, ring->rp, ring->wp));
			} else {
				/* Not enough space for new entry, free some up */
				r_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf +
					ring->rp);
				/* check bounds before incrementing read ptr */
				if (ring->rp + ENTRY_LENGTH(r_entry) >= ring->ring_size) {
					DHD_ERROR(("%s: RING%d[%s] rp points out of boundary,"
						"ring->wp=%u, ring->rp=%u, ring->ring_size=%d\n",
						__FUNCTION__, ring->id, ring->name, ring->wp,
						ring->rp, ring->ring_size));
					ASSERT(0);
					DHD_DBG_RING_UNLOCK(ring->lock, flags);
					return BCME_BUFTOOSHORT;
				}
				ring->rp += ENTRY_LENGTH(r_entry);
				/* skip padding if there is one */
				if (ring->tail_padded &&
					((ring->rp + ring->rem_len) == ring->ring_size)) {
					DHD_DBGIF(("%s: RING%d[%s] Found padding,"
						" avail_size=%d, w_len=%d, set rp = 0\n",
						__FUNCTION__,
						ring->id, ring->name, avail_size, w_len));
					ring->rp = 0;
					ring->tail_padded = FALSE;
					ring->rem_len = 0;
				}
				ring->stat.read_bytes += ENTRY_LENGTH(r_entry);
				DHD_DBGIF(("%s: RING%d[%s] read_bytes=%d, wp=%d, rp=%d\n",
					__FUNCTION__, ring->id, ring->name, ring->stat.read_bytes,
					ring->wp, ring->rp));
			}
		} else {
			break;
		}
	} while (TRUE);

	/* check before writing to the ring */
	if (ring->wp + w_len >= ring->ring_size) {
		DHD_ERROR(("%s: RING%d[%s] wp pointed out of ring boundary, "
			"wp=%d, ring_size=%d, w_len=%u\n", __FUNCTION__, ring->id,
			ring->name, ring->wp, ring->ring_size, w_len));
		ASSERT(0);
		DHD_DBG_RING_UNLOCK(ring->lock, flags);
		return BCME_BUFTOOLONG;
	}

	w_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf + ring->wp);
	/* header */
	memcpy(w_entry, hdr, DBG_RING_ENTRY_SIZE);
	w_entry->len = hdr->len;
	/* payload */
	memcpy((char *)w_entry + DBG_RING_ENTRY_SIZE, data, w_entry->len);
	/* update write pointer */
	ring->wp += w_len;

	/* update statistics */
	ring->stat.written_records++;
	ring->stat.written_bytes += w_len;
	DHD_DBGIF(("%s : RING%d[%s] written_records %d, written_bytes %d, read_bytes=%d,"
		" ring->threshold=%d, wp=%d, rp=%d\n", __FUNCTION__, ring->id, ring->name,
		ring->stat.written_records, ring->stat.written_bytes, ring->stat.read_bytes,
		ring->threshold, ring->wp, ring->rp));

	DHD_DBG_RING_UNLOCK(ring->lock, flags);
	return BCME_OK;
}

/*
 * This function folds ring->lock, so callers of this function
 * should not hold ring->lock.
 */
int
dhd_dbg_ring_pull_single(dhd_dbg_ring_t *ring, void *data, uint32 buf_len, bool strip_header)
{
	dhd_dbg_ring_entry_t *r_entry = NULL;
	uint32 rlen = 0;
	char *buf = NULL;

	if (!ring || !data || buf_len <= 0) {
		return 0;
	}

	/* pull from ring is allowed for inactive (suspended) ring
	 * in case of ecounters only, this is because, for ecounters
	 * when a trap occurs the ring is suspended and data is then
	 * pulled to dump it to a file. For other rings if ring is
	 * not in active state return without processing (as before)
	 */
	if (!ring->pull_inactive && (ring->state != RING_ACTIVE)) {
		goto exit;
	}

	if (ring->rp == ring->wp) {
		goto exit;
	}

	DHD_DBGIF(("%s: RING%d[%s] buf_len=%u, wp=%d, rp=%d, ring_start=0x%p; ring_size=%u\n",
		__FUNCTION__, ring->id, ring->name, buf_len, ring->wp, ring->rp,
		ring->ring_buf, ring->ring_size));

	r_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf + ring->rp);

	/* Boundary Check */
	rlen = ENTRY_LENGTH(r_entry);
	if ((ring->rp + rlen) > ring->ring_size) {
		DHD_ERROR(("%s: entry len %d is out of boundary of ring size %d,"
			" current ring %d[%s] - rp=%d\n", __FUNCTION__, rlen,
			ring->ring_size, ring->id, ring->name, ring->rp));
		rlen = 0;
		goto exit;
	}

	if (strip_header) {
		rlen = r_entry->len;
		buf = (char *)r_entry + DBG_RING_ENTRY_SIZE;
	} else {
		rlen = ENTRY_LENGTH(r_entry);
		buf = (char *)r_entry;
	}
	if (rlen > buf_len) {
		DHD_ERROR(("%s: buf len %d is too small for entry len %d\n",
			__FUNCTION__, buf_len, rlen));
		DHD_ERROR(("%s: ring %d[%s] - ring size=%d, wp=%d, rp=%d\n",
			__FUNCTION__, ring->id, ring->name, ring->ring_size,
			ring->wp, ring->rp));
		ASSERT(0);
		rlen = 0;
		goto exit;
	}

	memcpy(data, buf, rlen);
	/* update ring context */
	ring->rp += ENTRY_LENGTH(r_entry);
	/* don't pass wp but skip padding if there is one */
	if (ring->rp != ring->wp &&
	    ring->tail_padded && ((ring->rp + ring->rem_len) >= ring->ring_size)) {
		DHD_DBGIF(("%s: RING%d[%s] Found padding, rp=%d, wp=%d\n",
			__FUNCTION__, ring->id, ring->name, ring->rp, ring->wp));
		ring->rp = 0;
		ring->tail_padded = FALSE;
		ring->rem_len = 0;
	}
	if (ring->rp >= ring->ring_size) {
		DHD_ERROR(("%s: RING%d[%s] rp pointed out of ring boundary,"
			" rp=%d, ring_size=%d\n", __FUNCTION__, ring->id,
			ring->name, ring->rp, ring->ring_size));
		ASSERT(0);
		rlen = 0;
		goto exit;
	}
	ring->stat.read_bytes += ENTRY_LENGTH(r_entry);
	DHD_DBGIF(("%s RING%d[%s]read_bytes %d, wp=%d, rp=%d\n", __FUNCTION__,
		ring->id, ring->name, ring->stat.read_bytes, ring->wp, ring->rp));

exit:

	return rlen;
}

int
dhd_dbg_ring_pull(dhd_dbg_ring_t *ring, void *data, uint32 buf_len, bool strip_hdr)
{
	int32 r_len, total_r_len = 0;

	if (!ring || !data)
		return 0;

	if (!ring->pull_inactive && (ring->state != RING_ACTIVE)) {
		return 0;
	}

	while (buf_len > 0) {
		r_len = dhd_dbg_ring_pull_single(ring, data, buf_len, strip_hdr);
		if (r_len == 0)
			break;
		data = (uint8 *)data + r_len;
		buf_len -= r_len;
		total_r_len += r_len;
	}

	return total_r_len;
}

int
dhd_dbg_ring_config(dhd_dbg_ring_t *ring, int log_level, uint32 threshold)
{
	unsigned long flags = 0;

	if (!ring)
		return BCME_BADADDR;

	if (ring->state == RING_STOP)
		return BCME_UNSUPPORTED;

	DHD_DBG_RING_LOCK(ring->lock, flags);

	if (log_level == 0)
		ring->state = RING_SUSPEND;
	else
		ring->state = RING_ACTIVE;

	ring->log_level = log_level;
	ring->threshold = MIN(threshold, DBGRING_FLUSH_THRESHOLD(ring));

	DHD_DBG_RING_UNLOCK(ring->lock, flags);

	return BCME_OK;
}

void
dhd_dbg_ring_start(dhd_dbg_ring_t *ring)
{
	if (!ring)
		return;

	/* Initialize the information for the ring */
	ring->state = RING_SUSPEND;
	ring->log_level = 0;
	ring->rp = ring->wp = 0;
	ring->threshold = 0;
	memset(&ring->stat, 0, sizeof(struct ring_statistics));
	memset(ring->ring_buf, 0, ring->ring_size);
}
