blob: 772af42c0027a67d30ad0ac94737dea7acf9a7ce [file] [log] [blame]
/*
* wl ota test 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_ota_test.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"
static cmd_func_t wl_ota_loadtest, wl_otatest_status, wl_load_cmd_stream;
static cmd_func_t wl_ota_teststop, wl_otatest_rssi;
static cmd_t wl_ota_cmds[] = {
{ "ota_teststop", wl_ota_teststop, -1, WLC_SET_VAR,
"\tUsage: ota_teststop"
},
{ "ota_loadtest", wl_ota_loadtest, -1, WLC_SET_VAR,
"\tUsage: ota_loadtest [filename] \n"
"\t\tpicks up ota_test.txt if file is not given"
},
{ "ota_stream", wl_load_cmd_stream, -1, WLC_SET_VAR,
"\tUsage: wl ota_stream start : to start the test\n"
"\twl ota_stream ota_sync \n"
"\twl ota_stream test_setup synchtimeoout(seconds) synchbreak/loop synchmac txmac rxmac \n"
"\twl ota_stream ota_tx chan bandwidth contrlchan rates stf txant rxant tx_ifs tx_len"
"num_pkt pwrctrl start:delta:end \n"
"\twl ota_stream ota_rx chan bandwidth contrlchan -1 stf txant rxant tx_ifs"
"tx_len num_pkt \n"
"\twl ota_stream stop : to stop the test"
},
{ "ota_teststatus", wl_otatest_status, WLC_GET_VAR, -1,
"\tUsage: otatest_status"
"\t\tDisplays current running test details"
"\totatest_status n "
"\t\tdisplays test arguments for nth line"
},
{ "ota_rssi", wl_otatest_rssi, WLC_GET_VAR, -1,
"\tUsage: wl ota_rssi"
"\t\tDisplays RSSI values for each ota_rx test"
},
{ NULL, NULL, 0, 0, NULL }
};
static char *buf;
/* module initialization */
void
wluc_ota_module_init(void)
{
(void)g_swap;
/* get the global buf */
buf = wl_get_buf();
/* register ota test commands */
wl_module_cmds_register(wl_ota_cmds);
}
#define WL_OTA_STRING_MAX_LEN 100
#define WL_OTA_CMDSTREAM_MAX_LEN 200
/* test_setup cmd argument ordering */
enum {
WL_OTA_SYNC_TIMEOUT = 1, /* Timeout in seconds */
WL_OTA_SYNCFAIL_ACTION, /* Fail actio -1/0/1 */
WL_OTA_SYNC_MAC, /* Mac address for sync */
WL_OTA_TX_MAC, /* Mac address for tx test */
WL_OTA_RX_MAC, /* Mac address for rx test */
WL_OTA_LOOP_TEST /* Put test into loop mode */
};
/* ota_tx / ota_rx format ordering */
enum {
WL_OTA_CUR_TEST, /* ota_tx or ota_rx */
WL_OTA_CHAN, /* cur channel */
WL_OTA_BW, /* cur bandwidth */
WL_OTA_CONTROL_BAND, /* cur control band */
WL_OTA_RATE, /* cur rate */
WL_OTA_STF_MODE, /* cur stf mode */
WL_OTA_TXANT, /* tx ant to be used */
WL_OTA_RXANT, /* rx ant to be used */
WL_OTA_TX_IFS, /* ifs */
WL_OTA_TX_PKT_LEN, /* pkt length */
WL_OTA_TX_NUM_PKT, /* num of packets */
WL_OTA_PWR_CTRL_ON, /* power control on/off */
WL_OTA_PWR_SWEEP, /* start:delta:stop */
WL_OTA_LDPC, /* Use LDPC Encoding */
WL_OTA_SGI /* Use Short Guard Interval */
};
/* Various error chcking options */
enum {
WL_OTA_SYNCFAILACTION,
WL_OTA_CTRLBANDVALID,
WL_OTA_TXANTVALID,
WL_OTA_RXANTVALID,
WL_OTA_PWRCTRLVALID
};
/* Display init test seq */
void
wl_ota_display_test_init_info(wl_ota_test_status_t *init_info)
{
printf("Test Init Summary\n");
printf("----------------------------------------------------------\n");
printf("Toatl Number of test req %d\n\n", init_info->test_cnt);
printf("Sync timeout %d synch fail action: %d \n", init_info->sync_timeout,
init_info->sync_fail_action);
printf("Sync Mac address : \t");
printf("%s\n", wl_ether_etoa(&(init_info->sync_mac)));
printf("Tx Mac address : \t");
printf("%s\n", wl_ether_etoa(&(init_info->tx_mac)));
printf("Rx Mac address : \t");
printf("%s\n", wl_ether_etoa(&(init_info->rx_mac)));
printf("Test in Loop mode : %d \n", init_info->loop_test);
printf("\n\n\n");
}
static void
wl_ota_display_rt_info(uint16 rate)
{
if (rate & VHT_MCS_INUSE) {
printf("v");
printf("%d ", rate & OTA_RATE_MASK);
} else if (rate & HT_MCS_INUSE) {
printf("m");
printf("%d ", rate & OTA_RATE_MASK);
} else if (rate == 11) {
printf("5.5 ");
} else {
printf("%d ", (rate & OTA_RATE_MASK) / 2);
}
}
/* display nth tesr arg details */
void
wl_ota_display_test_option(wl_ota_test_args_t *test_arg, int16 cnt)
{
uint8 i;
printf("Test cnt %d \n", cnt);
printf("-----------------------------------------------------------\n");
printf("Curr Test : %s\n", ((test_arg->cur_test == 0) ? "TX" : "RX"));
printf("Wait for sync enabled %d \n", test_arg->wait_for_sync);
printf("Channel : %d", test_arg->chan);
printf("\t Bandwidth : %s ", ((test_arg->bw == WL_OTA_TEST_BW_20MHZ) ? "20" :
((test_arg->bw == WL_OTA_TEST_BW_40MHZ) ? "40" : "20 in 40")));
printf("\t Control Band : %c \n", test_arg->control_band);
printf("Rates : ");
for (i = 0; i < test_arg->rt_info.rate_cnt; i++)
wl_ota_display_rt_info(test_arg->rt_info.rate_val_mbps[i]);
printf("\nStf mode : %d \n", test_arg->stf_mode);
printf("Txant: %d(0x%2x) rxant: %d(0x%2x) \n",
test_arg->txant, test_arg->txant, test_arg->rxant, test_arg->rxant);
printf("Pkt eng Options : ifs %d len: %d num: %d \n", test_arg->pkteng.delay,
test_arg->pkteng.length, test_arg->pkteng.nframes);
printf("Tx power sweep options :\nPower control %d \nstart pwr: %d "
"delta: %d end pwr : %d \n", test_arg->pwr_info.pwr_ctrl_on,
test_arg->pwr_info.start_pwr, test_arg->pwr_info.delta_pwr,
test_arg->pwr_info.end_pwr);
}
/* do minimum string validations possible */
/* Make stricter conditions in future */
static int
wl_ota_validate_string(uint8 arg, void* value)
{
int ret = 0;
uint8 cores;
switch (arg) {
case WL_OTA_TXANTVALID:
case WL_OTA_RXANTVALID:
/* check if the 'txCore bitmask' of txant/rxant parameter is valid or not */
cores = WL_OTA_TEST_GET_CORE(*(uint8*) value);
if (cores > 7)
ret = -1;
break;
case WL_OTA_CTRLBANDVALID:
if ((strncmp((char *)value, "l", 1)) && (strncmp((char *)value, "u", 1)))
ret = -1;
break;
case WL_OTA_PWRCTRLVALID:
case WL_OTA_SYNCFAILACTION:
if ((*(int8 *)value < -2) || (*(int8 *)value > 1))
ret = -1;
break;
default:
break;
}
return ret;
}
/* convert power info string to integer */
/* start:delta:end */
static int
wl_ota_pwrinfo_parse(const char *tok_bkp, wl_ota_test_args_t *test_arg)
{
char *endptr = NULL;
int ret = 0;
/* convert string to int */
/* Read start pwr */
test_arg->pwr_info.start_pwr = (int8)strtol(tok_bkp, &endptr, 10);
if (*endptr == ':') {
endptr++;
tok_bkp = endptr;
} else {
return -1;
}
/* read delta pwr */
test_arg->pwr_info.delta_pwr = (int8)strtol(tok_bkp, &endptr, 10);
if (*endptr == ':') {
endptr++;
tok_bkp = endptr;
} else {
return -1;
}
/* read end pwr */
test_arg->pwr_info.end_pwr = (int8)strtol(tok_bkp, &endptr, 10);
if ((*endptr != '\0') && (*endptr != '\n') && (*endptr != ' '))
ret = -1;
return ret;
}
/* parsing the test init seq line */
static int
wl_ota_parse_test_init(wl_ota_test_vector_t * init_info, char * tok, uint16 cnt)
{
int ret = 0;
char * endptr = NULL;
switch (cnt) {
case WL_OTA_SYNC_TIMEOUT:
init_info->sync_timeout = (uint8)strtol(tok, &endptr, 10);
if (*endptr != '\0')
ret = -1;
break;
case WL_OTA_SYNCFAIL_ACTION:
init_info->sync_fail_action = (int8)strtol(tok, &endptr, 10);
if (*endptr != '\0') {
ret = -1;
break;
} else {
ret = wl_ota_validate_string(WL_OTA_SYNCFAILACTION,
&(init_info->sync_fail_action));
}
break;
case WL_OTA_SYNC_MAC:
if (!wl_ether_atoe(tok, &(init_info->sync_mac)))
ret = -1;
break;
case WL_OTA_TX_MAC:
if (!wl_ether_atoe(tok, &(init_info->tx_mac)))
ret = -1;
break;
case WL_OTA_RX_MAC:
if (!wl_ether_atoe(tok, &(init_info->rx_mac)))
ret = -1;
break;
case WL_OTA_LOOP_TEST:
init_info->loop_test = (int8)strtol(tok, &endptr, 10);
if ((*endptr != '\0') && (*endptr != '\n') && (*endptr != ' '))
ret = -1;
break;
default:
break;
}
return ret;
}
/* parse test arguments */
static int
wl_ota_test_parse_test_option(wl_ota_test_args_t *test_arg, char * tok, uint16 cnt,
char rt_string[])
{
char * endptr = NULL;
uint16 tok_len = 0;
int ret = 0;
if (test_arg->cur_test == WL_OTA_TEST_RX) {
switch (cnt) {
case WL_OTA_PWR_CTRL_ON:
case WL_OTA_PWR_SWEEP:
return 0;
break;
default:
break;
}
}
switch (cnt) {
case WL_OTA_CUR_TEST:
if (strncmp(tok, "ota_tx", 6) == 0)
test_arg->cur_test = WL_OTA_TEST_TX;
else if (strncmp(tok, "ota_rx", 6) == 0)
test_arg->cur_test = WL_OTA_TEST_RX;
else
ret = -1;
break;
case WL_OTA_CHAN:
test_arg->chan = (uint8)strtol(tok, &endptr, 10);
if (*endptr != '\0')
ret = -1;
break;
case WL_OTA_BW:
if (strncmp(tok, "20/40", 5) == 0) {
test_arg->bw = WL_OTA_TEST_BW_20MHZ;
} else if (strncmp(tok, "20", 2) == 0) {
test_arg->bw = WL_OTA_TEST_BW_20MHZ;
} else if (strncmp(tok, "40", 2) == 0) {
test_arg->bw = WL_OTA_TEST_BW_40MHZ;
} else if (strncmp(tok, "80", 2) == 0) {
test_arg->bw = WL_OTA_TEST_BW_80MHZ;
} else {
ret = -1;
}
break;
case WL_OTA_CONTROL_BAND:
test_arg->control_band = *tok;
ret = wl_ota_validate_string(WL_OTA_CTRLBANDVALID, tok);
break;
case WL_OTA_RATE:
tok_len = strlen(tok);
if (tok_len > WL_OTA_STRING_MAX_LEN) {
ret = -1;
goto fail;
}
strncpy(rt_string, tok, tok_len);
break;
case WL_OTA_STF_MODE:
#ifndef D11AC_IOTYPES
if (strncmp(tok, "siso", 4) == 0)
test_arg->stf_mode = OTA_STF_SISO;
else if (strncmp(tok, "cdd", 3) == 0)
test_arg->stf_mode = OTA_STF_CDD;
else if (strncmp(tok, "stbc", 4) == 0)
test_arg->stf_mode = OTA_STF_STBC;
else if (strncmp(tok, "sdm", 3) == 0)
test_arg->stf_mode = OTA_STF_SDM;
else
ret = -1;
#endif
break;
case WL_OTA_TXANT:
test_arg->txant = (uint8) strtol(tok, &endptr, 0);
if (*endptr != '\0') {
ret = -1;
goto fail;
}
ret = wl_ota_validate_string(WL_OTA_TXANTVALID, &test_arg->txant);
break;
case WL_OTA_RXANT:
test_arg->rxant = (uint8)strtol(tok, &endptr, 0);
if (*endptr != '\0') {
ret = -1;
goto fail;
}
ret = wl_ota_validate_string(WL_OTA_RXANTVALID, &test_arg->rxant);
break;
case WL_OTA_TX_IFS:
test_arg->pkteng.delay = (uint16)strtol(tok, &endptr, 10);
if (*endptr != '\0')
ret = -1;
break;
case WL_OTA_TX_PKT_LEN:
test_arg->pkteng.length = (uint16)strtol(tok, &endptr, 10);
if (*endptr != '\0')
ret = -1;
break;
case WL_OTA_TX_NUM_PKT:
test_arg->pkteng.nframes = (uint16)strtol(tok, &endptr, 10);
if ((*endptr != '\0') && (*endptr != '\n') && (*endptr != ' '))
ret = -1;
break;
case WL_OTA_PWR_CTRL_ON:
test_arg->pwr_info.pwr_ctrl_on = (int8)strtol(tok, &endptr, 10);
if (*endptr != '\0') {
ret = -1;
goto fail;
}
ret = wl_ota_validate_string(WL_OTA_PWRCTRLVALID,
&test_arg->pwr_info.pwr_ctrl_on);
break;
case WL_OTA_PWR_SWEEP:
ret = wl_ota_pwrinfo_parse(tok, test_arg);
break;
case WL_OTA_LDPC:
test_arg->ldpc = (uint8)strtol(tok, &endptr, 10);
if (*endptr != '\0')
ret = -1;
break;
case WL_OTA_SGI:
test_arg->sgi = (uint8)strtol(tok, &endptr, 10);
if (*endptr != '\0')
ret = -1;
break;
default:
break;
}
fail:
return ret;
}
static int
wl_ota_test_parse_rate_string(wl_ota_test_args_t *test_arg, char rt_string[100])
{
uint8 cnt = 0;
char * tok = NULL;
char rate_st[5] = "\0";
uint16 int_val = 0;
uint16 tok_len = 0;
int ret = 0;
tok = strtok(rt_string, ",");
/* convert rate strings to int array */
while (tok != NULL) {
strncpy(rate_st, " ", 4);
/* skip rate parsing if its rx test case */
if (test_arg->cur_test == WL_OTA_TEST_RX) {
test_arg->rt_info.rate_val_mbps[cnt] = 0;
cnt = 1;
break;
}
/* Support a max of 30 rates */
if (cnt >= WL_OTA_TEST_MAX_NUM_RATE) {
ret = -1;
break;
}
tok_len = strlen(tok);
if (tok_len > 5) {
ret = -1;
break;
}
strncpy(rate_st, tok, tok_len);
if (strncmp(rate_st, "5.5", 3) == 0) {
int_val = 11;
} else {
if (rate_st[0] == 'm') {
rate_st[0] = ' ';
int_val = atoi(rate_st);
int_val |= HT_MCS_INUSE;
} else if (rate_st[0] == 'v') {
rate_st[0] = ' ';
int_val = atoi(rate_st);
int_val |= VHT_MCS_INUSE;
} else {
int_val = 2 * atoi(rate_st);
}
}
test_arg->rt_info.rate_val_mbps[cnt] = int_val;
tok = strtok(NULL, ",");
cnt++;
}
test_arg->rt_info.rate_cnt = cnt;
return ret;
}
static int
wl_ota_test_parse_arg(char line[], wl_ota_test_vector_t *ota_test_vctr, uint16 *test_cnt,
uint8 *ota_sync_found)
{
char * tok = NULL;
char rt_string[WL_OTA_STRING_MAX_LEN] = "\0";
uint16 cnt = 0;
int ret = 0;
tok = strtok(line, " ");
if (tok == NULL)
goto fail;
/* Initialize the power arguments */
ota_test_vctr->test_arg[*test_cnt].pwr_info.pwr_ctrl_on = -1;
ota_test_vctr->test_arg[*test_cnt].pwr_info.start_pwr = -1;
ota_test_vctr->test_arg[*test_cnt].pwr_info.delta_pwr = -1;
ota_test_vctr->test_arg[*test_cnt].pwr_info.end_pwr = -1;
if (!strncmp(tok, "test_setup", 10)) {
/* Parse test setup details */
cnt = 0;
while (tok != NULL) {
if ((ret = wl_ota_parse_test_init(ota_test_vctr, tok, cnt)) != 0)
return ret;
tok = strtok(NULL, " ");
cnt++;
}
} else if (!(strncmp(tok, "ota_tx", 6)) || (!strncmp(tok, "ota_rx", 6))) {
/* parse tx /rx test argumenst */
cnt = 0;
while (tok != NULL) {
if ((ret = wl_ota_test_parse_test_option
(&(ota_test_vctr->test_arg[*test_cnt]),
tok, cnt, rt_string)) != 0) {
goto fail;
}
tok = strtok(NULL, " ");
cnt++;
}
/* split rate string into integer array */
if ((ret = wl_ota_test_parse_rate_string(&(ota_test_vctr->test_arg[*test_cnt]),
rt_string)) != 0) {
goto fail;
}
/* Add sync option if specified by user */
ota_test_vctr->test_arg[*test_cnt].wait_for_sync = (*ota_sync_found);
/* Reset ota_sync_found for next test arg */
*ota_sync_found = 0;
/* Increment test cnt */
*test_cnt = *test_cnt + 1;
} else if (strncmp(tok, "ota_sync", 8) == 0) {
/* detect if a sync packet is required */
*ota_sync_found = 1;
ret = 0;
}
fail:
return (ret);
}
static int
wl_load_cmd_stream(void *wl, cmd_t *cmd, char **argv)
{
int ret = -1;
char test_arg[WL_OTA_CMDSTREAM_MAX_LEN] = "\0";
uint16 test_cnt = 0;
uint8 * ptr1 = NULL;
uint8 i, num_loop = 0;
uint8 ota_sync_found = 0;
uint cmdlen = 0;
wl_seq_cmd_pkt_t *next_cmd;
wl_ota_test_vector_t *ota_test_vctr = NULL;
argv++;
if (*argv == NULL) {
return ret;
} else if (!strncmp(argv[0], "start", 5)) {
ret = wl_seq_start(wl, cmd, argv);
} else if (!strncmp(argv[0], "stop", 4)) {
ret = 0;
/* test info pointer */
ota_test_vctr = (wl_ota_test_vector_t *)malloc(sizeof(wl_ota_test_vector_t));
if (ota_test_vctr == NULL) {
fprintf(stderr, "Failed to allocate %d bytes of memory \n",
(uint16)sizeof(wl_ota_test_vector_t));
return BCME_NOMEM;
}
/* Assign a new pointer so that byte wise operation is possible */
ptr1 = (uint8 *)ota_test_vctr;
/* Passing test structure to dongle happens in steps */
/* For OTA implementations its split up into chunks of 1200 bytes */
num_loop = sizeof(wl_ota_test_vector_t) / WL_OTA_ARG_PARSE_BLK_SIZE;
if (!cmd_batching_mode) {
printf("calling ota_stream stop when it's already out of batching mode\n");
ret = BCME_ERROR;
goto fail;
}
cmd_batching_mode = FALSE;
next_cmd = cmd_list.head;
if (next_cmd == NULL) {
printf("no command batched\n");
ret = 0;
goto fail;
}
test_cnt = 0;
while (next_cmd != NULL) {
/* Max number of test options is ARRAYSIZE(ota_test_vctr->test_arg) */
if (test_cnt == ARRAYSIZE(ota_test_vctr->test_arg))
break;
if ((ret = wl_ota_test_parse_arg(next_cmd->data, ota_test_vctr, &test_cnt,
&ota_sync_found)) != 0) {
printf("Error Parsing the test command \n");
ret = BCME_BADARG;
goto fail;
}
next_cmd = next_cmd->next;
}
ota_test_vctr->test_cnt = test_cnt;
/* Full size of wl_ota_test_vector_t can not be parse through wl */
/* max size whihc can be passed from host to dongle is limited by eth size */
for (i = 0; i <= num_loop; i++) {
/* pass on the test info to wl->test_info structure */
if ((ret = wlu_var_setbuf(wl, "ota_loadtest", ptr1 + i *
WL_OTA_ARG_PARSE_BLK_SIZE, WL_OTA_ARG_PARSE_BLK_SIZE)) < 0) {
fprintf(stderr, "host to dongle download failed to pass %d"
"bytes in stage %d \n",
WL_OTA_ARG_PARSE_BLK_SIZE, i);
}
}
fail:
clean_up_cmd_list();
free(ota_test_vctr);
} else {
cmdlen = sizeof(test_arg) - 1;
while (*argv) {
strncat(test_arg, *argv, cmdlen);
cmdlen -= strlen(*argv);
argv++;
if (*argv) {
strncat(test_arg, " ", 1);
cmdlen--;
}
if (*argv && cmdlen < (strlen(*argv)))
{
fprintf(stderr, "\n Insufficient length for cmd buffer\n");
return -1;
}
}
return add_one_batched_cmd(WLC_SET_VAR, test_arg, strlen(test_arg));
}
return ret;
}
int
ota_loadtest(void *wl, char *command, char **argv)
{
int ret = -1;
FILE *fp;
const char *fname = "ota_test.txt";
char line[WL_OTA_CMDSTREAM_MAX_LEN] = "\0";
char line_bkp[WL_OTA_CMDSTREAM_MAX_LEN] = "\0";
uint16 test_cnt = 0;
uint8 * ptr1 = NULL;
uint8 i, num_loop = 0;
uint8 ota_sync_found = 0;
wl_ota_test_vector_t *ota_test_vctr = NULL;
UNUSED_PARAMETER(wl);
/* Read the file name */
if (argv[1]) {
fname = argv[1];
} else {
fprintf(stderr, "Missing ota test flow file name\n");
return BCME_BADARG;
}
/* test info pointer */
ota_test_vctr = (wl_ota_test_vector_t *)malloc(sizeof(wl_ota_test_vector_t));
if (ota_test_vctr == NULL) {
fprintf(stderr, "Failed to allocate %d bytes of memory \n",
(uint16)sizeof(wl_ota_test_vector_t));
return BCME_NOMEM;
}
/* Assign a new pointer so that byte wide operation is possible */
ptr1 = (uint8 *)ota_test_vctr;
/* find number of iterations required to parse full block form host to dongle */
num_loop = sizeof(wl_ota_test_vector_t) / WL_OTA_ARG_PARSE_BLK_SIZE;
/* open the flow file */
if ((fp = fopen(fname, "r")) == NULL) {
fprintf(stderr, "Problem opening file %s\n", fname);
free(ota_test_vctr);
return BCME_BADARG;
}
/* Updating version for wl_ota_test_vector_t */
ota_test_vctr->version = WL_OTA_TESTVEC_T_VERSION;
test_cnt = 0;
while (1) {
fgets(line, WL_OTA_CMDSTREAM_MAX_LEN - 1, fp);
if (feof(fp)) {
break;
}
/* Max number of test options is ARRAYSIZE(ota_test_vctr->test_arg) */
if (test_cnt == ARRAYSIZE(ota_test_vctr->test_arg))
break;
strncpy(line_bkp, line, WL_OTA_CMDSTREAM_MAX_LEN - 1);
if ((ret = wl_ota_test_parse_arg(line_bkp, ota_test_vctr,
&test_cnt, &ota_sync_found)) != 0) {
printf("Flow File Error: \nError Parsing string : %s \n", line);
ret = BCME_BADARG;
goto fail;
}
}
if (ota_sync_found) {
ret = -1;
printf("Flow File Error : \nFile can not end with ota_sync\n");
goto fail;
}
ota_test_vctr->test_cnt = test_cnt;
/* Full size of wl_ota_test_vector_t can not be parse through wl */
/* max size whihc can be passed from host to dongle is limited by eth size */
for (i = 0; i <= num_loop; i++) {
/* pass on the test info to wl->test_info structure */
if ((ret = wlu_var_setbuf(wl, command, ptr1 + i * WL_OTA_ARG_PARSE_BLK_SIZE,
WL_OTA_ARG_PARSE_BLK_SIZE)) < 0) {
fprintf(stderr, "host to dongle download failed to pass %d"
"bytes in stage %d \n",
WL_OTA_ARG_PARSE_BLK_SIZE, i);
break;
}
}
fail:
/* close the fp */
if (fp)
fclose(fp);
free(ota_test_vctr);
return ret;
}
static int
wl_ota_loadtest(void *wl, cmd_t *cmd, char **argv)
{
int ret = 0;
UNUSED_PARAMETER(wl); UNUSED_PARAMETER(cmd);
ret = ota_loadtest(wl, "ota_loadtest", argv);
return ret;
}
void
wl_otatest_display_skip_test_reason(int8 skip_test_reason)
{
switch (skip_test_reason) {
case 0 :
printf("Test successfully finished\n");
break;
case WL_OTA_SKIP_TEST_CAL_FAIL:
printf("Phy cal Failure \n");
break;
case WL_OTA_SKIP_TEST_SYNCH_FAIL:
printf("Sync Packet failure \n");
break;
case WL_OTA_SKIP_TEST_FILE_DWNLD_FAIL:
printf("File download Failure \n");
break;
case WL_OTA_SKIP_TEST_NO_TEST_FOUND:
printf("No test found in the flow file \n");
break;
case WL_OTA_SKIP_TEST_WL_NOT_UP:
printf("WL Not UP \n");
break;
case WL_OTA_SKIP_TEST_UNKNOWN_CALL:
printf("Erroneous scheduling of test. Not intended \n");
break;
default:
printf("Unknown test state \n");
break;
}
}
static int
wl_otatest_status(void *wl, cmd_t *cmd, char **argv)
{
int ret = 0;
int16 cnt = 0;
wl_ota_test_status_t *test_status = NULL;
wl_ota_test_vector_t *ota_test_vctr = NULL;
UNUSED_PARAMETER(wl); UNUSED_PARAMETER(cmd);
test_status = (wl_ota_test_status_t *)buf;
if (argv[1]) {
cnt = atoi(argv[1]);
if ((cnt < 1) || ((uint16)cnt > ARRAYSIZE(ota_test_vctr->test_arg))) {
printf("Error, Out of range \n");
return BCME_RANGE;
}
/* read nth test arg details */
if ((ret = wlu_iovar_getbuf(wl, cmd->name, &cnt, sizeof(uint16),
buf, WLC_IOCTL_MAXLEN)) < 0)
return ret;
if (cnt > (test_status->test_cnt)) {
printf("Error : Number of test seq downloaded %d \n",
test_status->test_cnt);
return BCME_RANGE;
}
/* Display Test init info */
wl_ota_display_test_init_info(test_status);
/* Dsiplay test arg info */
wl_ota_display_test_option(&(test_status->test_arg), cnt);
} else {
/* read back current state */
if ((ret = wlu_iovar_getbuf(wl, cmd->name, NULL, 0,
buf, WLC_IOCTL_MAXLEN)) < 0)
return ret;
cnt = test_status->cur_test_cnt;
switch (test_status->test_stage) {
case WL_OTA_TEST_IDLE: /* Idle state */
printf("Init state \n");
break;
case WL_OTA_TEST_ACTIVE: /* Active test state */
/* Read back details for current test arg */
cnt++;
ret = wlu_iovar_getbuf(wl, cmd->name, &cnt, sizeof(uint16),
buf, WLC_IOCTL_MAXLEN);
if (test_status->sync_status == WL_OTA_SYNC_ACTIVE)
printf("Waiting for sync \n");
else
wl_ota_display_test_option(&(test_status->test_arg), cnt);
break;
case WL_OTA_TEST_SUCCESS: /* Test Finished */
printf("Test completed \n");
break;
case WL_OTA_TEST_FAIL: /* Test Failed to complete */
wl_otatest_display_skip_test_reason(test_status->skip_test_reason);
break;
default:
printf("Invalid test Phase \n");
break;
}
}
return ret;
}
static int
wl_otatest_rssi(void *wl, cmd_t *cmd, char **argv)
{
int ret = 0;
int16 cnt = 0, rssi;
wl_ota_test_rssi_t *test_rssi = NULL;
wl_ota_rx_rssi_t *rx_rssi = NULL;
if (*++(argv)) {
printf("Too many arguments\n");
return BCME_ERROR;
}
test_rssi = (wl_ota_test_rssi_t *)buf;
if ((ret = wlu_iovar_getbuf(wl, cmd->name, NULL, 0,
buf, WLC_IOCTL_MEDLEN)) < 0)
return ret;
if (test_rssi->version != WL_OTARSSI_T_VERSION)
return BCME_VERSION;
rx_rssi = test_rssi->rx_rssi;
for (cnt = 0; cnt < test_rssi->testcnt; cnt++) {
rssi = dtoh16(rx_rssi[cnt].rssi);
if (rssi < 0)
printf("-%d.%02d ", ((-rssi) >> 2),
((-rssi) & 0x3)*25);
else
printf("%d.%02d ", (rssi >> 2),
(rssi & 0x3)*25);
}
printf("\n");
return ret;
}
/* To stop the ota test suite */
static int
wl_ota_teststop(void *wl, cmd_t *cmd, char **argv)
{
UNUSED_PARAMETER(argv);
return (wlu_iovar_setint(wl, cmd->name, 1));
}