/*
 * wl ltecx command module
 *
 * Broadcom Proprietary and Confidential. Copyright (C) 2017,
 * All Rights Reserved.
 * 
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
 * the contents of this file may not be disclosed to third parties, copied
 * or duplicated in any form, in whole or in part, without the prior
 * written permission of Broadcom.
 *
 *
 * <<Broadcom-WL-IPTag/Proprietary:>>
 *
 * $Id: wluc_ltecx.c 458728 2014-02-27 18:15:25Z $
 */

#ifdef WIN32
#include <windows.h>
#endif

#include <wlioctl.h>

#if	defined(DONGLEBUILD)
#include <typedefs.h>
#include <osl.h>
#endif

/* Because IL_BIGENDIAN was removed there are few warnings that need
 * to be fixed. Windows was not compiled earlier with IL_BIGENDIAN.
 * Hence these warnings were not seen earlier.
 * For now ignore the following warnings
 */
#ifdef WIN32
#pragma warning(push)
#pragma warning(disable : 4244)
#pragma warning(disable : 4761)
#endif

#include <bcmutils.h>
#include <bcmendian.h>
#include "wlu_common.h"
#include "wlu.h"

/* LTE coex funcs */
static cmd_func_t wl_wci2_config;
static cmd_func_t wl_mws_params;
static cmd_func_t wl_mws_wci2_msg;
static cmd_func_t wl_mws_frame_config;
static cmd_func_t wl_mws_antmap;
static cmd_func_t wl_mws_oclmap;
static cmd_func_t wl_mws_scanreq_bm;

static cmd_t wl_ltecx_cmds[] = {
	{ "wci2_config", wl_wci2_config, WLC_GET_VAR, WLC_SET_VAR,
	"Get/Set LTE coex MWS signaling config\n"
	"\tUsage: wl wci2_config <rxassert_off> <rxassert_jit> <rxdeassert_off> <rxdeassert_jit> "
	"<txassert_off> <txassert_jit> <txdeassert_off> <txdeassert_jit> "
	"<patassert_off> <patassert_jit> <inactassert_off> <inactassert_jit> "
	"<scanfreqassert_off> <scanfreqassert_jit> <priassert_off_req>"},
	{ "mws_params", wl_mws_params, WLC_GET_VAR, WLC_SET_VAR,
	"Get/Set LTE coex MWS channel params\n"
	"\tUsage: wl mws_params <rx_center_freq> <tx_center_freq> "
	"<rx_channel_bw> <tx_channel_bw> <channel_en> <channel_type>"},
	{ "mws_debug_msg", wl_mws_wci2_msg, WLC_GET_VAR, WLC_SET_VAR,
	"Get/Set LTE coex BT-SIG message\n"
	"\tUsage: wl mws_debug_msg <Message> <Interval 20us-32000us> "
	"<Repeats>"},
	{ "mws_frame_config", wl_mws_frame_config, WLC_GET_VAR, WLC_SET_VAR,
	"Get/Set LTE Frame configuration\n"
	"\tUsage: wl mws_frame_config <mws_frame_dur> <mws_framesync_assert_offset>"
	"<mws_framesync_assert_jitter> <mws_num_periods>"
	"{<mws_period_dur[i]> <mws_period_type>[i]}"},
	{ "mws_antenna_selection", wl_mws_antmap, WLC_GET_VAR, WLC_SET_VAR,
	"Get/Set Antenna selection params\n"
	"\tUsage: wl mws_antenna_selection <band-AntTx-combo1> <band-AntTx-combo2> "
	"<band-AntTx-combo3> <band-AntTx-combo4>\n"},
	{ "mws_ocl_override", wl_mws_oclmap, WLC_GET_VAR, WLC_SET_VAR,
	"Get/Set OCL maps\n"
	"\tUsage: wl mws_ocl_override <bitmap_2G> <bitmap_5G_lo> "
	"<bitmap_5G_mid> <bitmap_5G_high>\n"},
	{ "mws_scanreq_bm", wl_mws_scanreq_bm, WLC_GET_VAR, WLC_SET_VAR,
	"\tusage: wl mws_scanreq_bm [idx 2.4G-bitmap 5G-bitmap-lo 5G-bitmap-mid 5G-bitmap-hi]\n"
	"Set/Get the channel bitmaps corresponding to MWS (cellular) scan index <idx>"},
	{ NULL, NULL, 0, 0, NULL }
};

static char *buf;

/* module initialization */
void
wluc_ltecx_module_init(void)
{
	/* get the global buf */
	buf = wl_get_buf();

	/* register ltecx commands */
	wl_module_cmds_register(wl_ltecx_cmds);
}

static int
wl_wci2_config(void *wl, cmd_t *cmd, char **argv)
{
	uint32 val;
	char *endptr = NULL;
	uint argc;
	wci2_config_t wci2_config;
	uint16 *configp = (uint16 *)&wci2_config;
	int ret, i;

	UNUSED_PARAMETER(cmd);

	val = 0;

	/* eat command name */
	argv++;
	/* arg count */
	for (argc = 0; argv[argc]; argc++);

	memset(&wci2_config, '\0', sizeof(wci2_config_t));

	if (argc == 0) {
		/* Get and print the values */
		ret = wlu_iovar_getbuf(wl, "wci2_config", &wci2_config, sizeof(wci2_config_t),
		buf, WLC_IOCTL_SMLEN);
		if (ret)
			return ret;

		printf("rxassert_off %d rxassert_jit %d rxdeassert_off %d rxdeassert_jit %d "
			"txassert_off %d txassert_jit %d txdeassert_off %d txdeassert_jit %d "
			"patassert_off %d patassert_jit %d inactassert_off %d inactassert_jit %d "
			"scanfreqassert_off %d scanfreqassert_jit %d priassert_off_req %d\n",
			dtoh16(((uint16 *)buf)[0]), dtoh16(((uint16 *)buf)[1]),
			dtoh16(((uint16 *)buf)[2]), dtoh16(((uint16 *)buf)[3]),
			dtoh16(((uint16 *)buf)[4]), dtoh16(((uint16 *)buf)[5]),
			dtoh16(((uint16 *)buf)[6]), dtoh16(((uint16 *)buf)[7]),
			dtoh16(((uint16 *)buf)[8]), dtoh16(((uint16 *)buf)[9]),
			dtoh16(((uint16 *)buf)[10]), dtoh16(((uint16 *)buf)[11]),
			dtoh16(((uint16 *)buf)[12]), dtoh16(((uint16 *)buf)[13]),
			dtoh16(((uint16 *)buf)[14]));
		return 0;
	}

	if (argc < 15)
		goto usage;

	for (i = 0; i < 15; ++i) {
		val = strtoul(argv[i], &endptr, 0);
		if (*endptr != '\0')
			goto usage;
		configp[i] = htod16((uint16)val);
	}
	return wlu_iovar_setbuf(wl, "wci2_config", &wci2_config, sizeof(wci2_config_t),
		buf, WLC_IOCTL_SMLEN);

usage:
	return BCME_USAGE_ERROR;
}

static int
wl_mws_params(void *wl, cmd_t *cmd, char **argv)
{
	uint32 val;
	char *endptr = NULL;
	uint argc;
	mws_params_t mws_params;
	uint16 *paramsp = (uint16 *)&mws_params;
	int ret, i;

	UNUSED_PARAMETER(cmd);

	val = 0;

	/* eat command name */
	argv++;

	/* arg count */
	for (argc = 0; argv[argc]; argc++);

	memset(&mws_params, '\0', sizeof(mws_params_t));

	if (argc == 0) {
		/* Get and print the values */
		ret = wlu_iovar_getbuf(wl, "mws_params", &mws_params, sizeof(mws_params_t),
		buf, WLC_IOCTL_SMLEN);
		if (ret)
			return ret;

		printf("rx_center_freq %d tx_center_freq %d  rx_channel_bw %d tx_channel_bw %d "
			"channel_en %d channel_type %d\n",
			dtoh16(((uint16 *)buf)[0]), dtoh16(((uint16 *)buf)[1]),
			dtoh16(((uint16 *)buf)[2]), dtoh16(((uint16 *)buf)[3]), buf[8], buf[9]);
		return 0;
	}

	if (argc < 6)
		goto usage;
	for (i = 0; i < 4; ++i) {
		val = strtoul(argv[i], &endptr, 0);
		if (*endptr != '\0')
			goto usage;
		paramsp[i] = htod16((uint16)val);
	}
	val = strtoul(argv[i], &endptr, 0);
	if (*endptr != '\0')
		goto usage;
	mws_params.mws_channel_en = val;
	++i;
	val = strtoul(argv[i], &endptr, 0);
	if (*endptr != '\0')
		goto usage;
	mws_params.mws_channel_type = val;

	return wlu_iovar_setbuf(wl, "mws_params", &mws_params, sizeof(mws_params_t),
		buf, WLC_IOCTL_SMLEN);

usage:
	return BCME_USAGE_ERROR;
}

static int
wl_mws_wci2_msg(void *wl, cmd_t *cmd, char **argv)
{
	uint32 val;
	char *endptr = NULL;
	uint argc;
	mws_wci2_msg_t mws_wci2_msg;
	uint16 *paramsp = (uint16 *)&mws_wci2_msg;
	int ret, i = 0;

	UNUSED_PARAMETER(cmd);

	val = 0;

	/* eat command name */
	argv++;

	/* arg count */
	for (argc = 0; argv[argc]; argc++);

	memset(&mws_wci2_msg, '\0', sizeof(mws_wci2_msg_t));

	if (argc == 0) {
		/* Get and print the values */
		ret = wlu_iovar_getbuf(wl, "mws_debug_msg", &mws_wci2_msg, sizeof(mws_wci2_msg_t),
		buf, WLC_IOCTL_SMLEN);
		if (ret)
			return ret;

		printf("Message %d Interval %d  Repeats %d \n",
			dtoh16(((uint16 *)buf)[0]), dtoh16(((uint16 *)buf)[1]),
			dtoh16(((uint16 *)buf)[2]));
		return 0;
	}

	if (argc < 3)
		goto usage;

	for (i = 0; i < 3; ++i) {
		val = strtoul(argv[i], &endptr, 0);
		if (*endptr != '\0')
			goto usage;
		paramsp[i] = htod16((uint16)val);
	}
	if ((paramsp[1] < 20) || (paramsp[1] > 32000))
		goto usage;
	return wlu_iovar_setbuf(wl, "mws_debug_msg", &mws_wci2_msg, sizeof(mws_wci2_msg_t),
		buf, WLC_IOCTL_SMLEN);

usage:
	return BCME_USAGE_ERROR;
}

static int
wl_mws_frame_config(void *wl, cmd_t *cmd, char **argv)
{
	uint32 val;
	char *endptr = NULL;
	uint argc;
	mws_frame_config_t mws_frame_config;
	uint16 *paramsp = (uint16 *)&mws_frame_config;
	int ret, j = 3, k = 4, l = 20;
	uint8 i = 0;

	UNUSED_PARAMETER(cmd);

	val = 0;

	/* eat command name */
	argv++;

	/* arg count */
	for (argc = 0; argv[argc]; argc++);

	memset(&mws_frame_config, '\0', sizeof(mws_frame_config_t));

	if (argc == 0) {
		/* Get and print the values */
		ret = wlu_iovar_getbuf(wl, "mws_frame_config", &mws_frame_config,
		sizeof(mws_frame_config_t), buf, WLC_IOCTL_SMLEN);
		if (ret) {
			return ret;
		}
		printf("mws_frame_dur %d us mws_framesync_assert_offset %d "
		"mws_framesync_assert_jitter %d mws_num_periods %d \n",
		dtoh16(((uint16 *)buf)[0]), dtoh16(((uint16 *)buf)[1]),
		dtoh16(((uint16 *)buf)[2]), buf[27]);
		for (i = 0; i < buf[27]; i++) {
			printf("mws_period_dur[%d] %d us mws_period_type[%d] %d\n",
			i, dtoh16(((uint16 *)buf)[j]), i, buf[l]);
			j++;
			l++;
		}
		return 0;
	}

	if (argc <= 4)
		goto usage;
	/* Loop to populate the first three elements of the structure */
	for (i = 0; i < 3; ++i) {
		val = strtoul(argv[i], &endptr, 0);
		if (*endptr != '\0')
			goto usage;
		paramsp[i] = htod16((uint16)val);
	}

	val = strtoul(argv[3], &endptr, 0);
		if (*endptr != '\0')
			goto usage;
		mws_frame_config.mws_num_periods = val;

	/* Error check for insufficient data entered */
	if ((uint8)argc != ((mws_frame_config.mws_num_periods * 2) + 4)) {
		goto usage;
	}
	/* Loop to populate the arrays of size equal to mws_frame_config.mws_num_periods */
	for (i = 0; i < mws_frame_config.mws_num_periods; i++)
	{
		val = strtoul(argv[k], &endptr, 0);
		if (*endptr != '\0') {
			goto usage;
		}
		mws_frame_config.mws_period_dur[i] = val;
		k++;

		val = strtoul(argv[k], &endptr, 0);
		if (*endptr != '\0') {
			goto usage;
		}
		mws_frame_config.mws_period_type[i] = val;
		k++;
	}
	/* Set the values */
	return wlu_iovar_setbuf(wl, "mws_frame_config", &mws_frame_config,
		sizeof(mws_frame_config_t), buf, WLC_IOCTL_SMLEN);

	usage:
	return BCME_USAGE_ERROR;
}

static int
wl_mws_antmap(void *wl, cmd_t *cmd, char **argv)
{
	uint32 val;
	char *endptr = NULL;
	uint argc;
	mws_ant_map_t mws_antmap;
	uint16 *paramsp = (uint16 *)&mws_antmap;
	int ret, i = 0, j = 0;
	uint16 error_mask = 0xc000;
	uint16 ant_set[4];
	UNUSED_PARAMETER(cmd);
	val = 0;
	/* eat command name */
	argv++;
	/* arg count */
	for (argc = 0; argv[argc]; argc++);
	memset(&mws_antmap, '\0', sizeof(mws_antmap));
	if (argc == 0) {
		/* Get and print the values */
		ret = wlu_iovar_getbuf(wl, "mws_antenna_selection",
			&mws_antmap, sizeof(mws_antmap),
			buf, WLC_IOCTL_SMLEN);
		if (ret)
			return ret;
		printf("band_ant_combo1 %x band_ant_combo2 %x "
			"band_ant_combo3 %x band_ant_combo4 %x\n",
			dtoh16(((uint16 *)buf)[0]), dtoh16(((uint16 *)buf)[1]),
			dtoh16(((uint16 *)buf)[2]), dtoh16(((uint16 *)buf)[3]));
		return 0;
	}
	if (argc < 4)
		goto usage;
	for (i = 0; i < 4; ++i) {
		val = strtoul(argv[i], &endptr, 0);
		if (*endptr != '\0')
			goto usage;
		paramsp[i] = htod16((uint16)val);
		ant_set[i] = (paramsp[i] & error_mask) >> 14;
		for (j = 0; j < i; ++j) {
			if (ant_set[i] == ant_set[j]) {
				printf("duplicate band ant_tx combiniation\n");
				goto usage;
			}
		}
	}
	return wlu_iovar_setbuf(wl, "mws_antenna_selection", paramsp, sizeof(mws_antmap),
		buf, WLC_IOCTL_SMLEN);
usage:
	return BCME_USAGE_ERROR;
}

static int
wl_mws_oclmap(void *wl, cmd_t *cmd, char **argv)
{
	uint32 val;
	char *endptr = NULL;
	uint argc;
	wl_mws_ocl_override_t mws_oclmap;
	uint16 *paramsp = (uint16 *)&mws_oclmap;
	int ret, i = 0;
	UNUSED_PARAMETER(cmd);
	val = 0;
	/* eat command name */
	argv++;
	/* arg count */
	for (argc = 0; argv[argc]; argc++);
	memset(&mws_oclmap, '\0', sizeof(mws_oclmap));
	if (argc == 0) {
		/* Get and print the values */
		ret = wlu_iovar_getbuf(wl, "mws_ocl_override",
			&mws_oclmap, sizeof(mws_oclmap),
			buf, WLC_IOCTL_SMLEN);
		if (ret)
			return ret;
		printf(" bitmap_2g %x bitmap_5g_lo %x "
			"babitmap_5g_mid %x bitmap_5g_high %x\n",
			dtoh16(((uint16 *)buf)[1]), dtoh16(((uint16 *)buf)[2]),
			dtoh16(((uint16 *)buf)[3]), dtoh16(((uint16 *)buf)[4]));
		return 0;
	}
	if (argc < 4)
		goto usage;
	paramsp[0] = WL_MWS_OCL_OVERRIDE_VERSION;
	for (i = 0; i < 4; ++i) {
		val = strtoul(argv[i], &endptr, 0);
		if (*endptr != '\0')
			goto usage;
		paramsp[i+1] = htod16((uint16)val);
	}
	return wlu_iovar_setbuf(wl, "mws_ocl_override", paramsp, sizeof(mws_oclmap),
		buf, WLC_IOCTL_SMLEN);
usage:
	return BCME_USAGE_ERROR;
}

static int
wl_mws_scanreq_bm(void *wl, cmd_t *cmd, char **argv)
{
	mws_scanreq_params_t mws_scanreq_params;
	uint16 *paramsp = (uint16 *)&mws_scanreq_params;
	char *endptr = NULL;
	uint32 val;
	uint argc, i;
	int err;

	UNUSED_PARAMETER(cmd);

	/* eat command name */
	argv++;

	/* arg count */
	for (argc = 0; argv[argc]; argc++);

	memset(&mws_scanreq_params, 0, sizeof(mws_scanreq_params_t));

	if (argc == 0) {
		goto usage;
	} else if (argc == 1) {
		val = strtoul(argv[0], &endptr, 0);
		if (*endptr != '\0')
			goto usage;
		mws_scanreq_params.idx = htod16((uint16)val);

		if ((mws_scanreq_params.idx < 1) || (mws_scanreq_params.idx > 31)) {
			printf("LTE Index should be in range 1-31\n");
			goto usage;
		}

		err = wlu_iovar_getbuf(wl, cmd->name, &mws_scanreq_params,
			sizeof(mws_scanreq_params_t), buf, WLC_IOCTL_SMLEN);
		if (err < 0)
			return err;
		mws_scanreq_params = *(mws_scanreq_params_t *)buf;
		printf("\n Current LTE Timesharing coex : \n"
		"\t LTE channel index = %d\n \t 2G Channel = %d \n\t 5G low channel= %d\n"
		"\t 5G Middle channel= %d\n\t 5G High channel= %d\n",
		mws_scanreq_params.idx, mws_scanreq_params.bm_2g, mws_scanreq_params.bm_5g_lo,
		mws_scanreq_params.bm_5g_mid, mws_scanreq_params.bm_5g_hi);
		return 0;
	} else if (argc > 1 && argc < 5) {
		goto usage;
	}
	memset(&mws_scanreq_params, 0, sizeof(mws_scanreq_params_t));
	for (i = 0; i < 5; ++i) {
		val = strtoul(argv[i], &endptr, 0);
		if (*endptr != '\0')
			goto usage;
		paramsp[i] = htod16((uint16)val);
	}

	return wlu_iovar_setbuf(wl, "mws_scanreq_bm", &mws_scanreq_params,
		sizeof(mws_scanreq_params_t), buf, WLC_IOCTL_SMLEN);
usage:
	return BCME_USAGE_ERROR;
}
