/*
 * Driver O/S-independent utility routines
 *
 * 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/Dual:>>
 */

#include <typedefs.h>
#include <bcmdefs.h>

#include <stdarg.h>

#ifdef BCMDRIVER
#include <osl.h>
#else /* !BCMDRIVER */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifndef ASSERT
#define ASSERT(exp)
#endif
#endif /* !BCMDRIVER */

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

int
BCMPOSTTRAPFN(bcm_xtlv_hdr_size)(bcm_xtlv_opts_t opts)
{
	int len = (int)OFFSETOF(bcm_xtlv_t, data); /* nominal */
	if (opts & BCM_XTLV_OPTION_LENU8) --len;
	if (opts & BCM_XTLV_OPTION_IDU8) --len;

	return len;
}

bool
bcm_valid_xtlv(const bcm_xtlv_t *elt, int buf_len, bcm_xtlv_opts_t opts)
{
	return elt != NULL &&
	        buf_len >= bcm_xtlv_hdr_size(opts) &&
		buf_len  >= bcm_xtlv_size(elt, opts);
}

int
BCMPOSTTRAPFN(bcm_xtlv_size_for_data)(int dlen, bcm_xtlv_opts_t opts)
{
	int hsz;

	hsz = bcm_xtlv_hdr_size(opts);
	return ((opts & BCM_XTLV_OPTION_ALIGN32) ? ALIGN_SIZE(dlen + hsz, 4)
		: (dlen + hsz));
}

int
bcm_xtlv_size(const bcm_xtlv_t *elt, bcm_xtlv_opts_t opts)
{
	int size;	/* size including header, data, and any pad */
	int len;	/* length wthout padding */

	len = BCM_XTLV_LEN_EX(elt, opts);
	size = bcm_xtlv_size_for_data(len, opts);
	return size;
}

int
bcm_xtlv_len(const bcm_xtlv_t *elt, bcm_xtlv_opts_t opts)
{
	const uint8 *lenp;
	int len;

	lenp = (const uint8 *)elt + OFFSETOF(bcm_xtlv_t, len); /* nominal */
	if (opts & BCM_XTLV_OPTION_IDU8) {
		--lenp;
	}

	if (opts & BCM_XTLV_OPTION_LENU8) {
		len = *lenp;
	} else if (opts & BCM_XTLV_OPTION_LENBE) {
		len = (uint32)hton16(elt->len);
	} else {
		len = ltoh16_ua(lenp);
	}

	return len;
}

int
bcm_xtlv_id(const bcm_xtlv_t *elt, bcm_xtlv_opts_t opts)
{
	int id = 0;
	if (opts & BCM_XTLV_OPTION_IDU8) {
		id =  *(const uint8 *)elt;
	} else if (opts & BCM_XTLV_OPTION_IDBE) {
		id = (uint32)hton16(elt->id);
	} else {
		id = ltoh16_ua((const uint8 *)elt);
	}

	return id;
}

bcm_xtlv_t *
bcm_next_xtlv(const bcm_xtlv_t *elt, int *buflen, bcm_xtlv_opts_t opts)
{
	uint sz;

	COV_TAINTED_DATA_SINK(buflen);
	COV_NEG_SINK(buflen);

	/* validate current elt */
	if (!bcm_valid_xtlv(elt, *buflen, opts))
		return NULL;

	/* advance to next elt */
	sz = BCM_XTLV_SIZE_EX(elt, opts);
	elt = (const bcm_xtlv_t*)((const uint8 *)elt + sz);

#if defined(__COVERITY__)
	/* The 'sz' value is tainted in Coverity because it is read from the tainted data pointed
	 * to by 'elt'.  However, bcm_valid_xtlv() verifies that the elt pointer is a valid element,
	 * so its size, sz = BCM_XTLV_SIZE_EX(elt, opts), is in the bounds of the buffer.
	 * Clearing the tainted attribute of 'sz' for Coverity.
	 */
	__coverity_tainted_data_sanitize__(sz);
	if (sz > *buflen) {
		return NULL;
	}
#endif /* __COVERITY__ */

	*buflen -= sz;

	/* validate next elt */
	if (!bcm_valid_xtlv(elt, *buflen, opts))
		return NULL;

	COV_TAINTED_DATA_ARG(elt);

	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST()
	return (bcm_xtlv_t *)(elt);
	GCC_DIAGNOSTIC_POP()
}

int
bcm_xtlv_buf_init(bcm_xtlvbuf_t *tlv_buf, uint8 *buf, uint16 len, bcm_xtlv_opts_t opts)
{
	if (!tlv_buf || !buf || !len)
		return BCME_BADARG;

	tlv_buf->opts = opts;
	tlv_buf->size = len;
	tlv_buf->head = buf;
	tlv_buf->buf  = buf;
	return BCME_OK;
}

uint16
bcm_xtlv_buf_len(bcm_xtlvbuf_t *tbuf)
{
	uint16 len;

	if (tbuf)
		len = (uint16)(tbuf->buf - tbuf->head);
	else
		len = 0;

	return len;
}

uint16
bcm_xtlv_buf_rlen(bcm_xtlvbuf_t *tbuf)
{
	uint16 rlen;
	if (tbuf)
		rlen = tbuf->size - bcm_xtlv_buf_len(tbuf);
	else
		rlen = 0;

	return rlen;
}

uint8 *
bcm_xtlv_buf(bcm_xtlvbuf_t *tbuf)
{
	return tbuf ? tbuf->buf : NULL;
}

uint8 *
bcm_xtlv_head(bcm_xtlvbuf_t *tbuf)
{
	return tbuf ? tbuf->head : NULL;
}

void
BCMPOSTTRAPFN(bcm_xtlv_pack_xtlv)(bcm_xtlv_t *xtlv, uint16 type, uint16 len, const uint8 *data,
	bcm_xtlv_opts_t opts)
{
	uint8 *data_buf;
	bcm_xtlv_opts_t mask = BCM_XTLV_OPTION_IDU8 | BCM_XTLV_OPTION_LENU8;

	if (!(opts & mask)) {		/* default */
		uint8 *idp = (uint8 *)xtlv;
		uint8 *lenp = idp + sizeof(xtlv->id);
		htol16_ua_store(type, idp);
		htol16_ua_store(len, lenp);
		data_buf = lenp + sizeof(uint16);
	} else if ((opts & mask) == mask) { /* u8 id and u8 len */
		uint8 *idp = (uint8 *)xtlv;
		uint8 *lenp = idp + 1;
		*idp = (uint8)type;
		*lenp = (uint8)len;
		data_buf = lenp + sizeof(uint8);
	} else if (opts & BCM_XTLV_OPTION_IDU8) { /* u8 id, u16 len */
		uint8 *idp = (uint8 *)xtlv;
		uint8 *lenp = idp + 1;
		*idp = (uint8)type;
		htol16_ua_store(len, lenp);
		data_buf = lenp + sizeof(uint16);
	} else if (opts & BCM_XTLV_OPTION_LENU8) { /* u16 id, u8 len */
		uint8 *idp = (uint8 *)xtlv;
		uint8 *lenp = idp + sizeof(uint16);
		htol16_ua_store(type, idp);
		*lenp = (uint8)len;
		data_buf = lenp + sizeof(uint8);
	} else {
		ASSERT(!"Unexpected xtlv option");
		return;
	}

	if (opts & BCM_XTLV_OPTION_LENU8) {
		ASSERT(len <= 0x00ff);
		len &= 0xff;
	}

	if (data != NULL) {
		memcpy(data_buf, data, len);
	}
}

/* xtlv header is always packed in LE order */
void
bcm_xtlv_unpack_xtlv(const bcm_xtlv_t *xtlv, uint16 *type, uint16 *len,
	const uint8 **data, bcm_xtlv_opts_t opts)
{
	if (type)
		*type = (uint16)bcm_xtlv_id(xtlv, opts);
	if (len)
		*len = (uint16)bcm_xtlv_len(xtlv, opts);
	if (data)
		*data = (const uint8 *)xtlv + BCM_XTLV_HDR_SIZE_EX(opts);
}

int
bcm_xtlv_put_data(bcm_xtlvbuf_t *tbuf, uint16 type, const uint8 *data, int n)
{
	bcm_xtlv_t *xtlv;
	int size;

	if (tbuf == NULL)
		return BCME_BADARG;

	size = bcm_xtlv_size_for_data(n, tbuf->opts);
	if (bcm_xtlv_buf_rlen(tbuf) < size)
		return BCME_NOMEM;

	xtlv = (bcm_xtlv_t *)bcm_xtlv_buf(tbuf);
	bcm_xtlv_pack_xtlv(xtlv, type, (uint16)n, data, tbuf->opts);
	tbuf->buf += size; /* note: data may be NULL, reserves space */
	return BCME_OK;
}

static int
bcm_xtlv_put_int(bcm_xtlvbuf_t *tbuf, uint16 type, const uint8 *data, int n, int int_sz)
{
	bcm_xtlv_t *xtlv;
	int xtlv_len;
	uint8 *xtlv_data;
	int err = BCME_OK;

	if (tbuf == NULL) {
		err = BCME_BADARG;
		goto done;
	}

	xtlv = (bcm_xtlv_t *)bcm_xtlv_buf(tbuf);

	/* put type and length in xtlv and reserve data space */
	xtlv_len = n * int_sz;
	err = bcm_xtlv_put_data(tbuf, type, NULL, xtlv_len);
	if (err != BCME_OK)
		goto done;

	xtlv_data = (uint8 *)xtlv + bcm_xtlv_hdr_size(tbuf->opts);

	/* write data w/ little-endianness into buffer - single loop, aligned access */
	for (; n != 0; --n, xtlv_data += int_sz, data += int_sz) {
		switch (int_sz) {
		case sizeof(uint8):
			break;
		case sizeof(uint16):
			{
				uint16 v =  load16_ua(data);
				htol16_ua_store(v, xtlv_data);
				break;
			}
		case sizeof(uint32):
			{
				uint32 v = load32_ua(data);
				htol32_ua_store(v, xtlv_data);
				break;
			}
		case sizeof(uint64):
			{
				uint64 v = load64_ua(data);
				htol64_ua_store(v, xtlv_data);
				break;
			}
		default:
			err = BCME_UNSUPPORTED;
			goto done;
		}
	}

done:
	return err;
}

int
bcm_xtlv_put16(bcm_xtlvbuf_t *tbuf, uint16 type, const uint16 *data, int n)
{
	return bcm_xtlv_put_int(tbuf, type, (const uint8 *)data, n, sizeof(uint16));
}

int
bcm_xtlv_put32(bcm_xtlvbuf_t *tbuf, uint16 type, const uint32 *data, int n)
{
	return bcm_xtlv_put_int(tbuf, type, (const uint8 *)data, n, sizeof(uint32));
}

int
bcm_xtlv_put64(bcm_xtlvbuf_t *tbuf, uint16 type, const uint64 *data, int n)
{
	return bcm_xtlv_put_int(tbuf, type, (const uint8 *)data, n, sizeof(uint64));
}

/*
 *  upacks xtlv record from buf checks the type
 *  copies data to callers buffer
 *  advances tlv pointer to next record
 *  caller's resposible for dst space check
 */
int
bcm_unpack_xtlv_entry(const uint8 **tlv_buf, uint16 xpct_type, uint16 xpct_len,
	uint8 *dst_data, bcm_xtlv_opts_t opts)
{
	const bcm_xtlv_t *ptlv = (const bcm_xtlv_t *)*tlv_buf;
	uint16 len;
	uint16 type;
	const uint8 *data;

	ASSERT(ptlv);

	bcm_xtlv_unpack_xtlv(ptlv, &type, &len, &data, opts);
	if (len) {
		if ((type != xpct_type) || (len > xpct_len))
			return BCME_BADARG;
		if (dst_data && data)
			memcpy(dst_data, data, len); /* copy data to dst */
	}

	*tlv_buf += BCM_XTLV_SIZE_EX(ptlv, opts);
	return BCME_OK;
}

/*
 *  packs user data into tlv record and advances tlv pointer to next xtlv slot
 *  buflen is used for tlv_buf space check
 */
int
bcm_pack_xtlv_entry(uint8 **tlv_buf, uint16 *buflen, uint16 type, uint16 len,
	const uint8 *src_data, bcm_xtlv_opts_t opts)
{
	bcm_xtlv_t *ptlv = (bcm_xtlv_t *)*tlv_buf;
	int size;

	ASSERT(ptlv);

	size = bcm_xtlv_size_for_data(len, opts);

	/* copy data from tlv buffer to dst provided by user */
	if (size > *buflen) {
		return BCME_BADLEN;
	}

	bcm_xtlv_pack_xtlv(ptlv, type, len, src_data, opts);

	/* advance callers pointer to tlv buff */
	*tlv_buf = (uint8*)(*tlv_buf) + size;
	/* decrement the len */
	*buflen -= (uint16)size;
	return BCME_OK;
}

/*
 *  unpack all xtlv records from the issue a callback
 *  to set function one call per found tlv record
 */
int
bcm_unpack_xtlv_buf(void *ctx, const uint8 *tlv_buf, uint16 buflen, bcm_xtlv_opts_t opts,
	bcm_xtlv_unpack_cbfn_t *cbfn)
{
	uint16 len;
	uint16 type;
	int res = BCME_OK;
	int size;
	const bcm_xtlv_t *ptlv;
	int sbuflen = buflen;
	const uint8 *data;
	int hdr_size;

	ASSERT(!buflen || tlv_buf);
	ASSERT(!buflen || cbfn);

	hdr_size = BCM_XTLV_HDR_SIZE_EX(opts);
	while (sbuflen >= hdr_size) {
		ptlv = (const bcm_xtlv_t *)tlv_buf;

		bcm_xtlv_unpack_xtlv(ptlv, &type, &len, &data, opts);
		size = bcm_xtlv_size_for_data(len, opts);

		sbuflen -= size;

		/* check for buffer overrun */
		if (sbuflen < 0) {
			break;
		}

		if ((res = cbfn(ctx, data, type, len)) != BCME_OK) {
			break;
		}
		tlv_buf += size;
	}
	return res;
}

int
bcm_pack_xtlv_buf(void *ctx, uint8 *tlv_buf, uint16 buflen, bcm_xtlv_opts_t opts,
	bcm_pack_xtlv_next_info_cbfn_t get_next, bcm_pack_xtlv_pack_next_cbfn_t pack_next,
	int *outlen)
{
	int res = BCME_OK;
	uint16 tlv_id;
	uint16 tlv_len;
	uint8 *startp;
	uint8 *endp;
	uint8 *buf;
	bool more;
	int size;
	int hdr_size;

	ASSERT(get_next && pack_next);

	buf = tlv_buf;
	startp = buf;
	endp = (uint8 *)buf + buflen;
	more = TRUE;
	hdr_size = BCM_XTLV_HDR_SIZE_EX(opts);

	while (more && (buf < endp)) {
		more = get_next(ctx, &tlv_id, &tlv_len);
		size = bcm_xtlv_size_for_data(tlv_len, opts);
		if ((buf + size) > endp) {
			res = BCME_BUFTOOSHORT;
			goto done;
		}

		bcm_xtlv_pack_xtlv((bcm_xtlv_t *)buf, tlv_id, tlv_len, NULL, opts);
		pack_next(ctx, tlv_id, tlv_len, buf + hdr_size);
		buf += size;
	}

	if (more)
		res = BCME_BUFTOOSHORT;

done:
	if (outlen) {
		*outlen = (int)(buf - startp);
	}
	return res;
}

/*
 *  pack xtlv buffer from memory according to xtlv_desc_t
 */
int
bcm_pack_xtlv_buf_from_mem(uint8 **tlv_buf, uint16 *buflen, const xtlv_desc_t *items,
	bcm_xtlv_opts_t opts)
{
	int res = BCME_OK;
	uint8 *ptlv = *tlv_buf;

	while (items->type != 0) {
		if (items->len && items->ptr) {
			res = bcm_pack_xtlv_entry(&ptlv, buflen, items->type,
				items->len, items->ptr, opts);
			if (res != BCME_OK)
				break;
		}
		items++;
	}

	*tlv_buf = ptlv; /* update the external pointer */
	return res;
}

/*
 *  unpack xtlv buffer to memory according to xtlv_desc_t
 *
 */
int
bcm_unpack_xtlv_buf_to_mem(const uint8 *tlv_buf, int *buflen, xtlv_desc_t *items,
	bcm_xtlv_opts_t opts)
{
	int res = BCME_OK;
	const bcm_xtlv_t *elt;

	elt =  bcm_valid_xtlv((const bcm_xtlv_t *)tlv_buf, *buflen, opts) ?
		(const bcm_xtlv_t *)tlv_buf : NULL;
	if (!elt || !items) {
		res = BCME_BADARG;
		return res;
	}

	for (; elt != NULL && res == BCME_OK; elt = bcm_next_xtlv(elt, buflen, opts)) {
		/*  find matches in desc_t items  */
		xtlv_desc_t *dst_desc = items;
		uint16 len, type;
		const uint8 *data;

		bcm_xtlv_unpack_xtlv(elt, &type, &len, &data, opts);
		while (dst_desc->type != 0) {
			if (type == dst_desc->type) {
				if (len != dst_desc->len) {
					res = BCME_BADLEN;
				} else {
					memcpy(dst_desc->ptr, data, len);
				}
				break;
			}
			dst_desc++;
		}
	}

	if (res == BCME_OK && *buflen != 0)		/* this does not look right */
		res =  BCME_BUFTOOSHORT;

	return res;
}

/*
 * return data pointer of a given ID from xtlv buffer.
 * If the specified xTLV ID is found, on return *datalen will contain
 * the the data length of the xTLV ID.
 */
const uint8*
bcm_get_data_from_xtlv_buf(const uint8 *tlv_buf, uint16 buflen, uint16 id,
	uint16 *datalen, bcm_xtlv_opts_t opts)
{
	const uint8 *retptr = NULL;
	uint16 type, len;
	int size;
	const bcm_xtlv_t *ptlv;
	int sbuflen = buflen;
	const uint8 *data;
	int hdr_size;

	COV_TAINTED_DATA_SINK(buflen);
	COV_NEG_SINK(buflen);

	hdr_size = BCM_XTLV_HDR_SIZE_EX(opts);

	/* Init the datalength */
	if (datalen) {
		*datalen = 0;
	}
	while (sbuflen >= hdr_size) {
		ptlv = (const bcm_xtlv_t *)tlv_buf;
		bcm_xtlv_unpack_xtlv(ptlv, &type, &len, &data, opts);

		size = bcm_xtlv_size_for_data(len, opts);
		sbuflen -= size;
		if (sbuflen < 0) /* buffer overrun? */
			break;

		if (id == type) {
			retptr = data;
			if (datalen)
				*datalen = len;
			break;
		}

		tlv_buf += size;
	}

	COV_TAINTED_DATA_ARG(retptr);

	return retptr;
}

bcm_xtlv_t*
bcm_xtlv_bcopy(const bcm_xtlv_t *src, bcm_xtlv_t *dst,
	int src_buf_len, int dst_buf_len, bcm_xtlv_opts_t opts)
{
	bcm_xtlv_t *dst_next = NULL;
	src =  (src && bcm_valid_xtlv(src, src_buf_len, opts)) ? src : NULL;
	if (src && dst) {
		uint16 type;
		uint16 len;
		const uint8 *data;
		int size;
		bcm_xtlv_unpack_xtlv(src, &type, &len, &data, opts);
		size = bcm_xtlv_size_for_data(len, opts);
		if (size <= dst_buf_len) {
			bcm_xtlv_pack_xtlv(dst, type, len, data, opts);
			dst_next = (bcm_xtlv_t *)((uint8 *)dst + size);
		}
	}

	return dst_next;
}
