
/*****************************************************************************
* Copyright (c) 2004, 2005 Digi International Inc., All Rights Reserved
*
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
*
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/

#include <bsp.h>
#ifdef BSP_WANT_WIRELESS
#if (BSP_RF_TESTING == TRUE)
#include "cliapi.h"
#include "cli.h"
#include "cli_local.h"
#include "cli_tst_wifi.h"
#include "powersave.h"
#include "tx_api.h"
#include "bsp_api.h"
#include "wln_api.h"
#if MANUFACTURING_MODE
#include "bsp_local.h"
#endif

#if AIROHA_TRANSCEIVER
#include "airoha_pwr_cal.h"
extern BOOLEAN isBOrBGOnly(void);
extern BOOLEAN isAOnly(void);
static BOOLEAN enablePowerControl = FALSE;
static BOOLEAN txPowerInDBM = FALSE;
extern void powerControlForTstWifi(BOOLEAN enable);
#if AIROHA_PWR_CALIBRATION
extern void MacSetTxPowerInDbm(int value);
extern int checkPowerInput (int value);
#endif
#else
BOOLEAN isBOrBGOnly(void)
{
    return TRUE;
}

BOOLEAN isAOnly(void)
{
    return FALSE;
}
#endif
extern void MacSetDirectTxPower (int value);
extern void MacSetQuiet (int enable_quiet);
extern void MacUpdateFccBuffer (unsigned int transmit_mode, unsigned int transmit_rate);
extern void MacContinuousTransmit (int enable, unsigned int transmit_mode, unsigned int transmit_rate);
extern void MacRadioPrepareTXBeacon (unsigned int tx_frame_period);
extern void MacRadioTXRandomBuffer (unsigned int transmit_rate, unsigned int tx_frame_length);
extern void MacRadioTXBeacon (int enable, unsigned int transmit_rate, unsigned int tx_frame_period,
                              unsigned int tx_frame_length);
extern void MacRadioRXTest (int enable, uint32 * rx_frames);
extern void MacWriteRF (uint8 addr, uint32 data);
extern void MacReadRF (uint8 addr, uint32 * data);
extern void MacWriteReg8 (unsigned int offset, uint8 data);
extern uint8 MacReadReg8 (unsigned int offset);
extern void MacWriteReg16 (unsigned int offset, uint16 data);
extern uint16 MacReadReg16 (unsigned int offset);
extern void MacWriteReg32 (unsigned int offset, uint32 data);
extern uint32 MacReadReg32 (unsigned int offset);
extern void MacSetTxPower (int value);

/* enum used to list all tests that can be conducted using the application. */
enum radio_test_t
{
    RADIO_TX_CONTINUOUS_WIRELESS_TEST,
    RADIO_START_CONTINUOUS_TRANSMIT,
    RADIO_STOP_CONTINUOUS_TRANSMIT,
    RADIO_RX_SILENT_WIRELESS_TEST,
    RADIO_TX_PERIODIC_FRAME_TRANSMIT,
    RADIO_WRITE_RF,
    RADIO_READ_RF,
    RADIO_WRITE_REG8,
    RADIO_READ_REG8,
    RADIO_WRITE_REG16,
    RADIO_READ_REG16,
    RADIO_WRITE_REG32,
    RADIO_READ_REG32,
    RADIO_START_TX_PERIODIC_FRAME_TRANSMIT,
    RADIO_STOP_TX_PERIODIC_FRAME_TRANSMIT,
    RADIO_READ_MAC_ADDRESS,
    RADIO_WRITE_MAC_ADDRESS,
    RADIO_READ_VERSION_REVISION,
    RADIO_RERUN_LAST_TEST,  
    RADIO_SLEEP, 
    POWER_SAVE_MODE,
#if (AIROHA_TRANSCEIVER)
    RADIO_ENABLE_CLOSEDLOOP_POWER_CONTROL,
#endif
};


/* Used for quick testing */ 

/* cli_tst_wifi_stay_in_loop, when 0, displays the main menu asking the 
 * user to enter the test number to be run and then asks the user to 
 * enter the test parameters. If set to 1, it reruns the previous test 
 * selected by the user with the new test parameter value entered, 
 * keeping the other test parameters same. */

static int cli_tst_wifi_stay_in_loop = 0;  
static int cli_tst_wifi_quick_test = 0;

#define CTRL_C_CHAR 0x03
#define RADIO_TST_PROMPT ">> "

/* Used where we get input from user. */
#define FCC_INPUT_BUFFER_SIZE 64

/* From drivers/mac/mac_mgmt.c */

/* extern "C" void SetChannel(int channel); */
extern void SetChannel (int channel);

extern wln_params macParams;

/*******************************************************
 * cli_get_number(): This function converts a string to
 * an integer 
 *******************************************************/
int cli_get_number (char *number_string, unsigned int *number_value, unsigned int min, unsigned int max)
{
    char *string_ptr, *p;

    if (number_string == NULL)
    {
        return -1;
    }

    string_ptr = number_string;

    *number_value = strtoul (number_string, &p, 0);

    if ((p == string_ptr) || (p[0] != 0x00) || (*number_value < min) || (*number_value > max))
    {
        return -1;
    }

    return 0;
}




/**************************************************************
 * wireless_test(): This function asks for user input 
 * corresponding to a test selected.
 **************************************************************/
static int wireless_test (int fd, enum radio_test_t test)
{
    /* Used to store the last value for transmit mode */
    static unsigned int cli_tst_wifi_mode = 4;
    /* Used to store the last value for transmit rate */
    static unsigned int cli_tst_wifi_rate = 0;
    /* Used to store the last value for the channel */
    static int cli_tst_wifi_channel = -1;
    /* Used to store the last value for power */
    static int cli_tst_wifi_txpower = -1;
    /* Used to store the last modulation value */
    static unsigned int cli_tst_wifi_modulation = 1;
    /* Used to track if the transmit rate entered is 2 */ 
    static int cli_tst_wifi_rate_2 = 0;
    /* Used to store the test parameter entered by the user at the submenu to be changed for the test */ 
    static char cli_tst_wifi_buffer;
    /* Used to store the last value for frame period */
    static unsigned int cli_tst_wifi_frame_period = 0;
    /* Used to store the last value for frame length */
    static unsigned int cli_tst_wifi_frame_length = 0;
    /* Array containing the modulation rates */
    static unsigned int cli_arr[12] = {10,20,55,110,60,90,120,180,240,360,480,540};

    char input_buffer[FCC_INPUT_BUFFER_SIZE]; /* Used to store user input */
    int retval; 
    static int channel = -1;
    static int txpower = -1;
    char value = (char) 0;
    int error_code;
    static unsigned int transmit_mode = 4;
    static unsigned int transmit_rate = 0;
    uint32 rx_frames = 0;
    static unsigned int tx_frame_period = 0;    /* 20 msecs default tx frame period */
    static unsigned int tx_frame_length = 0;    /* 0 = 1,024 bytes; 1 = 128 bytes */
    static enum radio_test_t last_test; /* last RF parametric test */
    unsigned int tx_rate_displayed = 1; /*used for rerunning a cmd and displaying correct tx rate */
    static int max_power = 0;
    int max_rate, flag = 0, num = 0;
    char var;
    char buffer[FCC_INPUT_BUFFER_SIZE];

    if (test == RADIO_STOP_CONTINUOUS_TRANSMIT)
    {
#if AIROHA_TRANSCEIVER
        MacContinuousTransmit (0, 3, 0);
#else
        MacContinuousTransmit (0, 0, 0);
#endif
        return 0;
    }

    if (test == RADIO_STOP_TX_PERIODIC_FRAME_TRANSMIT)
    {
#if AIROHA_TRANSCEIVER
        MacRadioTXBeacon (0, 3, 0, 0);
#else
        MacRadioTXBeacon (0, 0, 0, 0);
#endif
        return 0;
    }

    if (test != RADIO_RERUN_LAST_TEST)
    {
        /* If the user chooses a test from the main menu, the channel value for the test is entered by the user */
        if (cli_tst_wifi_stay_in_loop == 0)  
        { 
            while (1)
            {
                cli_tst_wifi_channel = -1;
                channel = -1; 
                
                /* 802.11 transmit rf channel*/
                if (isBOrBGOnly())
                {
                    cli_printf (fd, "\r\nEnter wireless channel to transmit/receive on (1 - 14, default is to use current setting) ");   
                }
                else
                {
                    if(isAOnly())
                    {
                        cli_printf (fd, "\r\nEnter wireless channel to transmit/receive on (17 - 51, default is to use current setting) ");   
                    }
                    else
                    {
                        cli_printf (fd, "\r\nEnter wireless channel to transmit/receive on (1 - 51, default is to use current setting) ");   
                        cli_printf (fd, "\r\n1-14 for 802.11 b/g channels");
                        cli_printf (fd, "\r\n15 and 16 are reserved");                        
                    }
                    cli_printf (fd, "\r\n17 for channel L-184");
                    cli_printf (fd, "\r\n18 for channel L-188");
                    cli_printf (fd, "\r\n19 for channel L-192");
                    cli_printf (fd, "\r\n20 for channel L-196");
                    
                    cli_printf (fd, "\r\n21 for channel A-8");
                    cli_printf (fd, "\r\n22 for channel A-12");
                    cli_printf (fd, "\r\n23 for channel A-16");
                    cli_printf (fd, "\r\n24 for channel A-34");
                    cli_printf (fd, "\r\n25 for channel A-36");
                    cli_printf (fd, "\r\n26 for channel A-38");
                    cli_printf (fd, "\r\n27 for channel A-40");
                    cli_printf (fd, "\r\n28 for channel A-42");
                    cli_printf (fd, "\r\n29 for channel A-44");
                    cli_printf (fd, "\r\n30 for channel A-46");
                    cli_printf (fd, "\r\n31 for channel A-48");
                    cli_printf (fd, "\r\n32 for channel A-52");
                    cli_printf (fd, "\r\n33 for channel A-56");
                    cli_printf (fd, "\r\n34 for channel A-60");
                    cli_printf (fd, "\r\n35 for channel A-64");
                    
                    cli_printf (fd, "\r\n36 for channel A-100");
                    cli_printf (fd, "\r\n37 for channel A-104");
                    cli_printf (fd, "\r\n38 for channel A-108");
                    cli_printf (fd, "\r\n39 for channel A-112");
                    cli_printf (fd, "\r\n40 for channel A-116");
                    cli_printf (fd, "\r\n41 for channel A-120");
                    cli_printf (fd, "\r\n42 for channel A-124");
                    cli_printf (fd, "\r\n43 for channel A-128");
                    cli_printf (fd, "\r\n44 for channel A-132");
                    cli_printf (fd, "\r\n45 for channel A-136");
                    cli_printf (fd, "\r\n46 for channel A-140");
                    cli_printf (fd, "\r\n47 for channel A-149");
                    cli_printf (fd, "\r\n48 for channel A-153");
                    cli_printf (fd, "\r\n49 for channel A-157");
                    cli_printf (fd, "\r\n50 for channel A-161");
                    cli_printf (fd, "\r\n51 for channel A-165");
                }
                                        
                cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);
        
                retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);
    
                if (retval < 0)
                {
                    goto EXIT;
                }

                if (retval > 0)
                {
                    if (isBOrBGOnly())
                    {
                        retval = cli_get_number (input_buffer, (unsigned int *) &channel, 1, 14);
                    }
                    else if (isAOnly())
                    {
                        retval = cli_get_number (input_buffer, (unsigned int *) &channel, 17, WLN_CHAN_NUM);
                    }
                    else
                    {
                        retval = cli_get_number (input_buffer, (unsigned int *) &channel, 1, WLN_CHAN_NUM);
                    }

                    if ((retval < 0) || (retval == 15) || (retval == 16))
                    {
                        cli_printf (fd, "\r\nBad channel\r\n");
                        continue;
                    }
                }
                cli_tst_wifi_channel = channel;
                break;
            }
        }

        /* In case of quick test on channel,
         * If the user chooses to change any parameter and rerun the test for the new value without entering the other parameters again */
        if ((cli_tst_wifi_stay_in_loop == 1) && ((test == RADIO_TX_CONTINUOUS_WIRELESS_TEST) || (test == RADIO_TX_PERIODIC_FRAME_TRANSMIT)))
        {
            int freq;
                

            channel = wln_get_chan_info(cli_tst_wifi_channel, &freq);
            cli_printf (fd, "\r\n\nChannel: %d  (%d MHz) ", channel, freq);            
            /* If the user chooses to change a test parameter from the submenu */
            channel = cli_tst_wifi_channel;
        } 
        
        /* If the user chooses a test from the main menu, the power value for the test is entered by the user */
        if (cli_tst_wifi_stay_in_loop == 0)
        { 
            while (1)
            {
                cli_tst_wifi_txpower = -1;
                txpower = -1; 
                if (test == RADIO_RX_SILENT_WIRELESS_TEST)
                {
                    break;
                }

                /* transmit power level */
#if AIROHA_TRANSCEIVER
                {
                	if (txPowerInDBM)
                	{
		                 cli_printf (fd, "\r\nClosed Loop: Enter wireless txpower (1 - %u, default is to use current txpower setting) ", 25);
		                 max_power = 25;
                	}
                	else
                	{
                		 cli_printf (fd, "\r\nOpen Loop: Enter wireless txpower (0 - %u, default is to use current txpower setting) ", 0x3f);
		                 max_power = 0x3f;
                	}
                }
#else
                {
                    cli_printf (fd, "\r\nEnter wireless txpower (0 - %u, default is to use current txpower setting) ", 16/*max tx power is 16dbm*/);
                    max_power = 16;
                }
#endif
               
                cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);
        
                retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);
                
#if !AIROHA_TRANSCEIVER                
                if (retval < 0)
                {
                    goto EXIT;
                }
#endif

                if (retval > 0)
                {
                    retval = cli_get_number (input_buffer, (unsigned int *)&txpower, 0, max_power);
            
                    if (retval < 0)
                    {
                        cli_printf (fd, "\r\nBad power value\r\n");
                        continue;
                    }
                   
                    cli_tst_wifi_txpower = txpower; 
                }

                break;
            }
        }
        
        /* In case of quick test on power. 
         * If the user chooses to change any parameter for the test form the submenu */
        if ((cli_tst_wifi_stay_in_loop == 1) && ((test == RADIO_TX_CONTINUOUS_WIRELESS_TEST) || (test == RADIO_TX_PERIODIC_FRAME_TRANSMIT)))
        {
            switch(cli_tst_wifi_buffer)
            {   
                /* If the user hits '+' to increase power */
                case '+':
                    {
                        txpower = cli_tst_wifi_txpower + 1;
                        cli_tst_wifi_txpower = txpower;
                        break;
                    }
                /* If the user hits '-' to decrease power */
                case '-':
                    {
                        txpower = cli_tst_wifi_txpower - 1;
                        cli_tst_wifi_txpower = txpower;
                        break;
                    }
                /* If the user hits p followed by the new power value which is captured in cli_tst_wifi_txpoweror changes any other test parameter */
                default:
                    {
                        txpower = cli_tst_wifi_txpower;
                        cli_tst_wifi_txpower = txpower;
                        break;
                    }
            }

            cli_printf (fd, "Power: %d   ", txpower);  
        } 

        if ((test == RADIO_TX_PERIODIC_FRAME_TRANSMIT) || (test == RADIO_START_TX_PERIODIC_FRAME_TRANSMIT))
        {
            /* If the user chooses RADIO_TX_PERIODIC_FRAME_TRANSMIT or RADIO_START_TX_PERIODIC_FRAME_TRANSMIT from the main menu, the frame period for the test is entered by the user */
            if (cli_tst_wifi_stay_in_loop == 0) 
            {
                tx_frame_period = 0;
                cli_tst_wifi_frame_period = 0;
                while (1)
                {

                    /* tx frame period 1-100 milliseconds */
                    cli_printf (fd, "\r\nEnter tx frame period (0 - %u msecs, default is to use current 20 msecs setting) ", 100);
                    cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);
        
                    retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);
        
                    if (retval < 0)
                    {
                        goto EXIT;
                    }

                    if (retval > 0)
                    {
                        retval = cli_get_number (input_buffer, &tx_frame_period, 0, 101);
            
                        if (retval < 0)
                        {
                            cli_printf (fd, "\r\nBad tx frame period value\r\n");
                            continue;
                        }
                       
                        cli_tst_wifi_frame_period = tx_frame_period; 
                    }

                    break;
                }
            }
            /* If the user changes any parameter for the test using the submenu, the last frame period value is retained */ 
            else if(test == RADIO_TX_PERIODIC_FRAME_TRANSMIT)
                tx_frame_period = cli_tst_wifi_frame_period;

            /* If the user chooses RADIO_TX_PERIODIC_FRAME_TRANSMIT or RADIO_START_TX_PERIODIC_FRAME_TRANSMIT from the main menu, 
             * the frame length for the test is entered by the user*/
            if (cli_tst_wifi_stay_in_loop == 0) 
            {
                while (1)
                {
                    cli_tst_wifi_frame_length = 0;
                    tx_frame_length = 0;
                    /* tx frame length 128 bytes or 1024 bytes */
                    cli_printf (fd, "\r\nEnter tx frame length (0 = %u bytes, 1 = %u bytes, default is 1,024 bytes) ", 1024, 128);
                    cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);
        
                    retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);
        
                    if (retval < 0)
                    {
                        goto EXIT;
                    }

                    if (retval > 0)
                    {
                        retval = cli_get_number (input_buffer, &tx_frame_length, 0, 2);
            
                        if (retval < 0)
                        {
                            cli_printf (fd, "\r\nBad tx frame length  value\r\n");
                            continue;
                        }
                       
                        cli_tst_wifi_frame_length = tx_frame_length; 
                    }

                    break;
                }
            }
            /* If the user changes any parameter for the test using the submenu, the last frame length value is retained */
            else if(test == RADIO_TX_PERIODIC_FRAME_TRANSMIT)
                tx_frame_length = cli_tst_wifi_frame_length;
        }

        /* If the user chooses a test from the main menu, the transmit mode for the test is entered by the user */
        if (cli_tst_wifi_stay_in_loop == 0)
        { 
            while (1)
            {
                if ((test == RADIO_RX_SILENT_WIRELESS_TEST) || (test == RADIO_TX_PERIODIC_FRAME_TRANSMIT) || 
                    (test == RADIO_START_TX_PERIODIC_FRAME_TRANSMIT))
                {
                    break;
                }
        
                /* transmit pattern */
                cli_printf (fd, "\r\nEnter wireless transmit mode (0=random, 1=zeros, 2=ones, 3=unmodulated, 4=fcc (default 4))");
                cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);
        
                retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);
        
                if (retval < 0)
                {
                    goto EXIT;
                }

                if (retval > 0)
                {
                    retval = cli_get_number (input_buffer, &transmit_mode, 0, 4);
            
                    if (retval < 0)
                    {
                        cli_printf (fd, "\r\nBad transmit mode\r\n");
                        continue;
                    }
      
                    cli_tst_wifi_mode = transmit_mode; 
 
                }

                break;
            }
        }
        /* If the user changes any parameter for the test using the submenu, the last transmit mode is retained */
        else if(test == RADIO_TX_PERIODIC_FRAME_TRANSMIT)    
            transmit_mode = cli_tst_wifi_mode;
 
        /* If the user chooses a test from the main menu, the transmit rate for the test is entered by the user */
        if(cli_tst_wifi_stay_in_loop == 0)   
        {
            while (1)
            {
                transmit_rate = 0;
                cli_tst_wifi_modulation = 1;
                cli_tst_wifi_rate = 0;
                cli_tst_wifi_rate_2 = 0;
                if ((test == RADIO_RX_SILENT_WIRELESS_TEST) || (3 == transmit_mode))
                {
                    break;
                }

                /* 802.11 transmission rate */
#ifdef BSP_ARM9
                    {
                        cli_printf(fd, "\r\nEnter wireless transmit rate (0=1Mbps, 1=2Mbps, 2=5.5Mbps, 3=11Mbps, 4=6Mbps, 5=9Mbps, \r\n 6=12Mbps, 7=18Mbps, 8=24Mbps, 9=36Mbps, 10=48Mbps, 11=54Mbps (default 1Mbps))");
                        max_rate = 11;
                    } 
#else
                    {
                        cli_printf(fd, "\r\nEnter wireless transmit rate (0=1Mbps, 1=2Mbps, 2=5.5Mbps, 3=11Mbps (default 1Mbps))");
                        max_rate = 3;
                    }
#endif
                cli_printf(fd, "\r\n%s", RADIO_TST_PROMPT);
        
                retval = cli_getline(fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);
        
                if (retval < 0)
                {
                    goto EXIT;
                }

                if (retval > 0)
                {

                        retval = cli_get_number(input_buffer, &transmit_rate, 0, max_rate);
            
                    if (retval < 0)
                    {
                        cli_printf(fd, "\r\nUnsupported transmit rate\r\n");
                        continue;
                    }
                  
                    cli_tst_wifi_rate = transmit_rate;
                    cli_tst_wifi_modulation = cli_arr[transmit_rate];
                
                    if(transmit_rate == 2)
                        cli_tst_wifi_rate_2 = 1;
                }

                break;
            } 
        } 
        /* In case of quick test on transmit rate. 
         * If the user changes a parameter for the test using the submenu */
        else if((cli_tst_wifi_stay_in_loop == 1)&&((test == RADIO_TX_CONTINUOUS_WIRELESS_TEST)||(test == RADIO_TX_PERIODIC_FRAME_TRANSMIT)))
        {
            /* If the user changes a test parameter at the sub menu */
            switch(cli_tst_wifi_modulation)
            {
            case 120 :
                transmit_rate = 6;
                break;

            case 180:
                transmit_rate = 7;
                break; 

            case 240:
                transmit_rate = 8;
                break;
              
            case 360: 
                transmit_rate = 9;
                break;
        
            case 480:
                transmit_rate = 10;
                break;

            case 540:
                transmit_rate = 11;
                break;

            case 10:
                transmit_rate = 0;
                break;

            case 20: 
                transmit_rate = 1;
                break;

            case 110:
                transmit_rate = 3;
                break;

            case 60:
                transmit_rate = 4;
                break;

            case 90:
                transmit_rate = 5;
                break;
                    
            case 55:
                transmit_rate = 2;
                break;

            default:
                assert(0);
                break;
            } 

            cli_tst_wifi_rate = transmit_rate;  

            if(cli_tst_wifi_rate_2 == 1)
            {
                cli_printf(fd, "Tx rate: %.1fMbps   ",cli_tst_wifi_modulation/10.0); 
            } 
            else
                cli_printf(fd, "Tx rate: %dMbps   ",cli_tst_wifi_modulation/10);
        } 

        /* memorize the test in case one needs to rerun it */ 
 
        last_test = test; 
    }

    else
    {
        /* rerun the last valid RF parametric test */
        test = last_test;

        switch (transmit_rate)
        {
        case 0:
            tx_rate_displayed = 1;
            break;
        case 1:
            tx_rate_displayed = 2;
            break;
        case 2:
            tx_rate_displayed = 5;
            break;
        case 3:
            tx_rate_displayed = 1;
            break;
        case 4:
            tx_rate_displayed = 11;
            break;
        case 5:
            tx_rate_displayed = 9;
            break;
        case 6:
            tx_rate_displayed = 12;
            break;
        case 7:
            tx_rate_displayed = 18;
            break;
        case 8:
            tx_rate_displayed = 24;
            break;
        case 9:
            tx_rate_displayed = 36;
            break;
        case 10:
            tx_rate_displayed = 48;
            break;
        case 11:
            tx_rate_displayed = 54;
            break;
        default:
            tx_rate_displayed = 0;
            break;
        }

        cli_printf (fd, "\r\nRe-running test=%d, channel=%d, power lvl=%d, tx rate = %d Mbps\r\n", test + 1, wln_get_chan_info(channel, NULL), txpower,
                    tx_rate_displayed);
    }
    
    

		
    /* Set transmit rate and mode */
    switch (test)
    {
        case RADIO_TX_CONTINUOUS_WIRELESS_TEST:
            MacContinuousTransmit (1, transmit_mode, transmit_rate);
            break;
        case RADIO_START_CONTINUOUS_TRANSMIT:
            MacContinuousTransmit (1, transmit_mode, transmit_rate);
            break;
        case RADIO_RX_SILENT_WIRELESS_TEST:
            MacRadioRXTest (1, &rx_frames);
            break;
        case RADIO_TX_PERIODIC_FRAME_TRANSMIT:
        case RADIO_START_TX_PERIODIC_FRAME_TRANSMIT:
            MacRadioTXBeacon (1, transmit_rate, tx_frame_period, tx_frame_length);
            break;
        default:
            error_code = 10;
            goto FAIL;
    } 
    
    if (channel >= 0)
    {
        /* set channel */
        SetChannel (channel);
    }

    if (txpower >= 0)
    {
        /* set power */
#if AIROHA_TRANSCEIVER
#if AIROHA_PWR_CALIBRATION
	if (txPowerInDBM)
	{
		//MacSetTxPower ((unsigned char) txpower);
		if (channel > 16)  
		{
		    // in A bands
		    cli_printf (fd, "\r\n\r\nThe txpower would be %d (if OFDM, txpower would be %d)\n", checkPowerInput(txpower), checkPowerInput(txpower));
		}
		else
		{
		    if (getPowerCalibrationVersion() == CALIBRATION_VERSION_1)
            {
		        cli_printf (fd, "\r\n\r\nThe txpower would be %d (if OFDM, txpower would be %4.3f)\n", checkPowerInput(txpower), (checkPowerInput(txpower) - 3.5));
		    }
		    else if (getPowerCalibrationVersion() == CALIBRATION_VERSION_2 && !isRF_AIROHA_7230() )
		    {
		        cli_printf (fd, "\r\n\r\nThe txpower would be %d (if OFDM, txpower would be %4.3f)\n", checkPowerInput(txpower), (checkPowerInput(txpower) - 4.86));
		    }
		    else
		    {
		        if (transmit_rate == 0 || transmit_rate == 1 || transmit_rate == 2 || transmit_rate == 3)
		        {
		            cli_printf (fd, "\r\n\r\n CCK: The txpower would be %d \n", checkPowerInput(txpower));
		        }
		        else
		        {
		            if (isRF_AIROHA_7230())
		            {
		                if (txpower >= HIGH_POINT_AL7230_BG_OFDM)
    		                cli_printf (fd, "\r\n\r\n OFDM: The txpower would be %d \n", HIGH_POINT_AL7230_BG_OFDM);
    		            else if (txpower <= LOW_POINT_AL7230_BG_OFDM)
    		                cli_printf (fd, "\r\n\r\n OFDM: The txpower would be %d \n", LOW_POINT_AL7230_BG_OFDM);
    		            else
    		                cli_printf (fd, "\r\n\r\n OFDM: The txpower would be %d \n", txpower);
		            }
		            else
		            {
    		            if (txpower >= HIGH_POINT_AL2236_OFDM)
    		                cli_printf (fd, "\r\n\r\n OFDM: The txpower would be %d \n", HIGH_POINT_AL2236_OFDM);
    		            else if (txpower <= LOW_POINT_AL2236_OFDM)
    		                cli_printf (fd, "\r\n\r\n OFDM: The txpower would be %d \n", LOW_POINT_AL2236_OFDM);
    		            else
    		                cli_printf (fd, "\r\n\r\n OFDM: The txpower would be %d \n", txpower);
		            }
		        }
		    }
		}
		    
		MacSetTxPowerInDbm((unsigned char) txpower);
	}
	else
#endif //#if AIROHA_PWR_CALIBRATION
	{
        	MacSetDirectTxPower (txpower);
        }
#else
#if (PLATFORM == connectcorewi9c_a)
	MacSetDirectTxPower ((unsigned char)txpower);
#else
        MacSetTxPower ((unsigned char) txpower);
#endif
#endif
    }
      

    /* Displays the submenu */
    if ((test != RADIO_START_CONTINUOUS_TRANSMIT) && (test != RADIO_START_TX_PERIODIC_FRAME_TRANSMIT))
    {
        cli_printf(fd, "\r\n\nType 'q' to quit test");      
     
        if((test == RADIO_TX_CONTINUOUS_WIRELESS_TEST) || (test == RADIO_TX_PERIODIC_FRAME_TRANSMIT)) 
        {
            cli_printf(fd,"\r\nType 'c' to change channel, followed by the new channel value"); 
            cli_printf(fd,"\r\nType 'm' to change transmit rate, followed by the new rate value"); 
            cli_printf(fd,"\r\nType (+/-) to increase/decrease power");
            cli_printf(fd,"\r\nType 'p' to change power, followed by the new power value \r");
            
#if AIROHA_TRANSCEIVER  
            cli_printf(fd,"\r\nType 's' to show the target tx power setting and the current index and ADC reading \r");
#endif
            
        }
 
    } 
    else
    {
        if (test == RADIO_START_CONTINUOUS_TRANSMIT)
            cli_printf (fd, "\r\n Continuous transmit test in progress...\r\n");
        else
            cli_printf (fd, "\r\n Periodic frame transmit test in progress...\r\n");
    }

    if ((test == RADIO_START_CONTINUOUS_TRANSMIT) || (test == RADIO_START_TX_PERIODIC_FRAME_TRANSMIT))
    {
        return 0;
    }

    while (1)
    {
        /* Eat up any typed characters and look for (q)uit or
           ctrl-c char */
        int var_return = 0;
        char str[FCC_INPUT_BUFFER_SIZE] = "5.5";
            
        if(flag == 0)
            cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT); 
        else
            flag = 0;
       
        /* input_buffer is used to store the input entered by the user at the submenu */
        value = cli_getchar(fd);
        input_buffer[0] = value;

        /* The user has only the quit option at the submenu for any test other than RADIO_TX_CONTINUOUS_WIRELESS_TEST or RADIO_TX_PERIODIC_FRAME_TRANSMTI*/
        if((value != 'q') && (test != RADIO_TX_CONTINUOUS_WIRELESS_TEST) && (test != RADIO_TX_PERIODIC_FRAME_TRANSMIT)) 
        {
            cli_printf(fd, "\rInvalid Input\r");
            cli_tst_wifi_stay_in_loop = 0;
            cli_tst_wifi_quick_test = 1;
            goto EXIT_LOOP;
        }
        
        /* Variable num is 0 when the user is at the submenu and is at 1 when an invalid value was entered and the user is asked to enter it again */
        if(num == 0)
        {
            /* If the user hits 'q' at the submenu, the test is quit and the main menu shows up again */
            if(value == 'q') 
            {
                cli_tst_wifi_stay_in_loop = 0;
                cli_tst_wifi_quick_test = 1;
                goto EXIT_LOOP;
            }
            /* If the user hits 'm' to change modulation, 'p' to change power or 'c' to change channel, followed by the new value for it */
            else if ((value == 'm') || (value == 'p') || (value == 'c'))
            {
                cli_printf(fd,"%c", input_buffer[0]);
                cli_getline(fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT,1,1,1);
            }
        }
        else 
        {
            /* The user can enter a correct value for a previously entered incorrect value of a parameter by just specifying the new value directly */
            if(((input_buffer[0] >= 48) && (input_buffer[0] <= 57)) || (input_buffer[0] == var))
            {
                cli_printf(fd, "%c", input_buffer[0]);
                cli_getline(fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT,1,1,1);
                
                if((input_buffer[0] >= 48) && (input_buffer[0] <= 57))
                {
                    strcpy(buffer, input_buffer);
                    strcpy(input_buffer, &var);
                    strcpy(input_buffer+1, buffer);
                }
            }
            else
                input_buffer[0] = (char)0;
        }

        switch(input_buffer[0])
        {   
            /* If the user chooses to change the power at the submenu */
            case 'p':
                var = 'p';
                /* Converts the power entered as string by the user, to a number */
                var_return = cli_get_number(input_buffer+1, (unsigned int *)&cli_tst_wifi_txpower,1,16);
                cli_tst_wifi_buffer = 'p';
                
                /* If the power entered exceeds the maximum limit, it is set to the maximum. */
                if(cli_tst_wifi_txpower > max_power)
                    cli_tst_wifi_txpower = max_power;
                /* If the power entered is below the lower limit, it is set to the minimum valid value */
                else if (cli_tst_wifi_txpower < 0)
                    cli_tst_wifi_txpower = 0;

                goto EXIT_LOOP;
                break;
                                   
            /*If the user chooses to increase power by hitting '+' */
            case '+':
                cli_tst_wifi_buffer = '+';
                
                /* If the user tries to increment the power above the maximum limit, it is set to the maximum valid value */
                if((cli_tst_wifi_txpower + 1) > max_power)
                    cli_tst_wifi_txpower = max_power - 1;
                
                goto EXIT_LOOP;
               
                break;
#if (AIROHA_TRANSCEIVER  && AIROHA_PWR_CALIBRATION)         
            /*If the user chooses to increase power by hitting '+' */
            case 's':
            	
                cli_printf(fd,"\r\n\nTarget power = %8.3f dbm, AirohaIndex =%d, ADC reading = %d \n", _wapc.CustIndex, _wapc.AirohaIndex, _wapc.Rawdata);
                 
                goto EXIT_LOOP;
               
                break;
#endif                
                   
            /* If the user chooses to decrease power by hitting '-' */
            case '-': 
                cli_tst_wifi_buffer = '-'; 
                
                /* If the user tries decrementing the value below the lower limit, it is set to the minimum valid value */
                if((cli_tst_wifi_txpower - 1) < 0)
                    cli_tst_wifi_txpower = 1;
                
                goto EXIT_LOOP;
                
                break;
                
            /* If the user chooses to change the channel at the submenu */
            case 'c':     
                var = 'c';
                /* Converts the channel input as string from the user, to a number */
                if (isBOrBGOnly())
                {
                    var_return = cli_get_number(input_buffer+1, (unsigned int *)&cli_tst_wifi_channel, 1, 14); 
                }
                else if (isAOnly())
                {
                    var_return = cli_get_number(input_buffer+1, (unsigned int *)&cli_tst_wifi_channel, 17, WLN_CHAN_NUM); 
                }
                else
                {
                    var_return = cli_get_number(input_buffer+1, (unsigned int *)&cli_tst_wifi_channel, 1, WLN_CHAN_NUM); 
                }
               
                /* Validating the channel value entered */
                if (isBOrBGOnly())
                {
                    if((cli_tst_wifi_channel > 0) && (cli_tst_wifi_channel < 15)) 
                    {
                            cli_tst_wifi_buffer = 'c';
                            goto EXIT_LOOP;
                    }
                    /* If an incorrect channel is entered, the user is asked to re-enter it.
                    * It can be entered either by hitting c again and then the new channel value 
                    * or by entering the new value directly */
                    else
                    {
                        cli_printf(fd,"\r\n\nBad channel, enter again c(1-14)\r");
                            num = 1;
                            continue;
                    }   
                }
                else if (isAOnly())
                {
                    if((cli_tst_wifi_channel >= 17) && (cli_tst_wifi_channel <= WLN_CHAN_NUM)) 
                    {
                            cli_tst_wifi_buffer = 'c';
                            goto EXIT_LOOP;
                    }
                    /* If an incorrect channel is entered, the user is asked to re-enter it.
                    * It can be entered either by hitting c again and then the new channel value 
                    * or by entering the new value directly */
                    else
                    {
                        cli_printf(fd,"\r\n\nBad channel, enter again c(17-51)\r");
                            num = 1;
                            continue;
                    }   
                }
                else
                {
                    if((cli_tst_wifi_channel > 0)&&(cli_tst_wifi_channel <= WLN_CHAN_NUM)) 
                    {
                            cli_tst_wifi_buffer = 'c';
                            goto EXIT_LOOP;
                    }
                    /* If an incorrect channel is entered, the user is asked to re-enter it.
                    * It can be entered either by hitting c again and then the new channel value 
                    * or by entering the new value directly */
                    else
                    {
                        cli_printf(fd,"\r\n\nBad channel, enter again c(1-%d)\r", WLN_CHAN_NUM);
                            num = 1;
                            continue;
                    }   
                }
                
                break;
                     
            /* If the user chooses to change modulation */
            case 'm':
                var = 'm';
                if(strcmp(input_buffer+1,str) == 0)
                    strcpy(input_buffer+1,"55");
                else
                    strcat(input_buffer+1,"0");
                
                /* Converts the modulation input as string from the user, to a number */
                var_return = cli_get_number(input_buffer+1, (unsigned int *)&cli_tst_wifi_modulation, 1, max_rate);
#ifdef BSP_ARM9
                {   
                    /* Validating the value entered for modulation rate */
                    if((cli_tst_wifi_modulation == 10) || (cli_tst_wifi_modulation == 20) ||
                       (cli_tst_wifi_modulation == 55) || (cli_tst_wifi_modulation == 110) ||
                       (cli_tst_wifi_modulation == 60) || (cli_tst_wifi_modulation == 90) ||
                       (cli_tst_wifi_modulation == 180) || (cli_tst_wifi_modulation == 240) ||
                       (cli_tst_wifi_modulation == 360) || (cli_tst_wifi_modulation == 540) ||
                       (cli_tst_wifi_modulation == 120) || (cli_tst_wifi_modulation == 480))
                    {
                        if(cli_tst_wifi_modulation == 55)
                            cli_tst_wifi_rate_2 = 1; 
                        else
                            cli_tst_wifi_rate_2 = 0;
 
                        cli_tst_wifi_buffer = 'm';
                        goto EXIT_LOOP;
                    }
                    /* If an incorrect modulation is entered, the user is asked to re-enter it.
                     * It can be entered either by hitting m again and then the new modulation value
                     * or by entering the new rate directly */
                    else
                    {
                        cli_printf(fd,"\r\n\nUnsupported transmit rate, enter again m(1/2/5.5/11/6/9/12/18/24/36/48/54)\r");
                        num = 1;
                        continue;
                    }
                }
#else
                {
                    /* Validating the value entered for modualtion rate */
                    if((cli_tst_wifi_modulation == 10) || (cli_tst_wifi_modulation == 20) ||
                       (cli_tst_wifi_modulation == 55) || (cli_tst_wifi_modulation == 110)) 
                    {     
                        if(cli_tst_wifi_modulation == 55)
                            cli_tst_wifi_rate_2 = 1;    
                        else
                            cli_tst_wifi_rate_2 = 0;

                        cli_tst_wifi_buffer = 'm';
                        goto EXIT_LOOP;
                    }
                    /* If an incorrect modulation is entered, the user is asked to re-enter it.
                     * It can be entered either by hitting m again and then the new modulation value
                     * or by entering the new rate directly */
                    else
                    {
                        cli_printf(fd,"\r\n\nUnsupported transmit rate, enter again m(1/2/5.5/11)\r");
                        num = 1;
                        continue;
                    } 
                }
#endif
                break;
                
            default:
                flag = 1;
                continue;
                break;
        } 

        if (test == RADIO_TX_CONTINUOUS_WIRELESS_TEST)
        {
            MacUpdateFccBuffer (transmit_mode, transmit_rate);
        }

        tx_thread_sleep (NS_MILLISECONDS_TO_TICKS (2000));
    }

  EXIT_LOOP:

    switch (test)
    {
    case RADIO_TX_CONTINUOUS_WIRELESS_TEST:
#if AIROHA_TRANSCEIVER
        MacContinuousTransmit (0, transmit_mode, transmit_rate);
        /* delay introduced so that the corresponding register values get updated by the time the test is rerun for the new modulation rate*/
        tx_thread_sleep (NS_MILLISECONDS_TO_TICKS (30));
#else
        MacContinuousTransmit (0, 0, 0);
        tx_thread_sleep (NS_MILLISECONDS_TO_TICKS (30));
#endif
        break;
    case RADIO_RX_SILENT_WIRELESS_TEST:
    {
        MacRadioRXTest (0, &rx_frames);
        cli_printf (fd, "\r\n rx_frames = %u\r\n", rx_frames);
    }
        break;
    case RADIO_TX_PERIODIC_FRAME_TRANSMIT:
#if AIROHA_TRANSCEIVER
        MacRadioTXBeacon (0, transmit_rate, tx_frame_period, tx_frame_length);
#else
        MacRadioTXBeacon (0, 0, 0, 0);
#endif
        break;
    default:
        error_code = 10;
        goto FAIL;
    }

    goto EXIT;

  FAIL:
    cli_printf (fd, "\r\nFailed setup (error_code=%x)\r\n", error_code);
  EXIT:

    /* restore channel and txpower */

    return 0;
}

/**************************************************************
 * wireless_write_rf()
 **************************************************************/
static int wireless_write_rf (int fd)
{
    char input_buffer[FCC_INPUT_BUFFER_SIZE];
    int retval;
    unsigned int address;
    uint32 data;

    while (1)
    {
        while (1)
        {
            /* get radio register address */

            cli_printf (fd, "\r\nEnter register address (e.g. 0x07), 'q' to quit");
            cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);

            retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);

            if (retval < 0)
            {
                goto EXIT;
            }

            if (retval > 0)
            {
                if (input_buffer[0] == 'q')
                {
                    goto EXIT;
                }

                retval = cli_get_number (input_buffer, &address, 0, 0xff);

                if (retval < 0)
                {
                    cli_printf (fd, "\r\nBad address\r\n");
                    continue;
                }

                break;
            }
        }

        while (1)
        {
            /* get address */
            cli_printf (fd, "\r\nEnter value (e.g. 0xaabbcc), 'q' to quit");
            cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);

            retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);

            if (retval < 0)
            {
                goto EXIT;
            }

            if (retval > 0)
            {
                if (input_buffer[0] == 'q')
                {
                    goto EXIT;
                }

                retval = cli_get_number (input_buffer, &data, 0, 0xffffff);

                if (retval < 0)
                {
                    cli_printf (fd, "\r\nBad value\r\n");
                    continue;
                }

                /* valid data, exit loop */
                break;
            }
        }

        /* Send RF data */
        MacWriteRF ((uint8) address, data);
    }

  EXIT:
    return 0;
}

/**************************************************************
 * wireless_read_rf()
 **************************************************************/
static int wireless_read_rf (int fd)
{
    char input_buffer[FCC_INPUT_BUFFER_SIZE];
    unsigned int address;
    uint32 data;
    int retval;

    while (1)
    {
        /* Get address */
        cli_printf (fd, "\r\nEnter register address (e.g. 0x07, 'q' to quit)");
        cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);

        retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);

        if (retval < 0)
        {
            goto EXIT;
        }

        if (retval > 0)
        {
            if (input_buffer[0] == 'q')
            {
                goto EXIT;
            }

            retval = cli_get_number (input_buffer, &address, 0, 0xff);

            if (retval < 0)
            {
                cli_printf (fd, "\r\nBad address\r\n");
                continue;
            }

            MacReadRF (address, &data);

            cli_printf (fd, "\r\nreg(%x) = 0x%06x\r\n", address, data);
        }
    }

  EXIT:
    return 0;
}

/**************************************************************
 * wireless_read_reg32()
 **************************************************************/
static int wireless_read_reg32 (int fd)
{
    char input_buffer[FCC_INPUT_BUFFER_SIZE];
    unsigned int address;
    uint32 data;
    int retval;

    /* get register address */
    while (1)
    {

        /* get address */
        cli_printf (fd, "\r\nEnter register address (e.g. 0x0004, 'q' to quit)");
        cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);

        retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);

        if (retval < 0)
        {
            goto EXIT;
        }

        if (retval > 0)
        {
            if (input_buffer[0] == 'q')
            {
                goto EXIT;
            }

            retval = cli_get_number (input_buffer, &address, 0, 0xffff);

            if (retval < 0)
            {
                cli_printf (fd, "\r\nBad address\r\n");
                continue;
            }

            data = MacReadReg32 ((unsigned int) address);

            cli_printf (fd, "\r\n(0x%02x) = 0x%08x\r\n", address, data);
        }
    }

  EXIT:
    return 0;
}

/**************************************************************
 * wireless_write_reg32()
 **************************************************************/
static int wireless_write_reg32 (int fd)
{
    char input_buffer[FCC_INPUT_BUFFER_SIZE];
    unsigned int address;
    unsigned int data;
    int retval;

    while (1)
    {

        /* get register address */
        while (1)
        {
            /* get address */
            cli_printf (fd, "\r\nEnter register address (e.g. 0x04, 'q' to quit)");
            cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);

            retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);

            if (retval < 0)
            {
                goto EXIT;
            }

            if (retval > 0)
            {
                if (input_buffer[0] == 'q')
                {
                    goto EXIT;
                }

                retval = cli_get_number (input_buffer, &address, 0, 0xff);

                if (retval < 0)
                {
                    cli_printf (fd, "\r\nBad address\r\n");
                    continue;
                }

                break;
            }
        }

        /* get register data */
        while (1)
        {
            /* get address */
            cli_printf (fd, "\r\nEnter data (e.g. 0x12345678, 'q' to quit)");
            cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);

            retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);

            if (retval < 0)
            {
                goto EXIT;
            }

            if (retval > 0)
            {
                if (input_buffer[0] == 'q')
                {
                    goto EXIT;
                }

                retval = cli_get_number (input_buffer, &data, 0, 0xffffffff);

                if (retval < 0)
                {
                    cli_printf (fd, "\r\nBad data\r\n");
                    continue;
                }

                break;
            }
        }

        MacWriteReg32 ((unsigned int) address, (uint32) data);
    }

  EXIT:

    return 0;
}

/**************************************************************
 * wireless_read_mac_address()
 **************************************************************/
static int wireless_read_mac_address (int fd)
{
    cli_printf (fd, "%-20s : %02x:%02x:%02x:%02x:%02x:%02x\r\n", "\r\n Radio mac address", macParams.sta_addr[0],
                macParams.sta_addr[1], macParams.sta_addr[2], macParams.sta_addr[3], macParams.sta_addr[4],
                macParams.sta_addr[5]);
    return 0;
}

/**************************************************************
 * wireless_write_mac_address()
 **************************************************************/
static int wireless_write_mac_address (int fd)
{
    /* TBD */
    cli_printf (fd, "\r\n Operation not supported on this platform \r\n");
    return 0;
}

/**************************************************************
 * wireless_sleep()
 **************************************************************/
static int wireless_sleep (int fd)
{
#ifdef BSP_ARM9
    cli_printf (fd, "\r\n The CPU goes to sleep in 2 seconds... \r\n");
    tx_thread_sleep (NS_MILLISECONDS_TO_TICKS (2000));
    naPdSleep (NAPD_SLEEP_AND_RESUME, NAPD_EXT_IRQ0_TRIGGER /* this trigger would never trigger, almost deep sleep */ );
#else
    cli_printf (fd, "\r\n Operation not supported on this platform \r\n");
#endif
    return 0;
}

/**************************************************************
 * wireless_read_radio_revision()
 **************************************************************/
static int wireless_read_radio_revision (int fd)
{
#ifdef BSP_ARM9
    uint16 data = 0xAAAA;

    /* radio transceiver version and revision stored @ offset zero */
    /* byte0 = radio version ; byte1 = radio revision */

    // get the radio transceiver version and revision from perm storage
    data = (unsigned int) MacReadReg16 (2);

    // display the radio version and revision
    cli_printf (fd, "\r\n FPGA Radio version and revision is 0x%04x\r\n", data);
#else
    /* TBD */
    cli_printf (fd, "\r\n Operation not supported on this platform \r\n");
#endif
    return 0;
}

/**************************************************************
 * wireless_read_reg16()
 **************************************************************/
static int wireless_read_reg16 (int fd)
{
    char input_buffer[FCC_INPUT_BUFFER_SIZE];
    unsigned int address;
    unsigned int data;
    int retval;

    /* get register address */
    while (1)
    {

        /* get address */
        cli_printf (fd, "\r\nEnter register address (e.g. 0x1004, 'q' to quit)");
        cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);

        retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);

        if (retval < 0)
        {
            goto EXIT;
        }

        if (retval > 0)
        {
            if (input_buffer[0] == 'q')
            {
                goto EXIT;
            }

            retval = cli_get_number (input_buffer, &address, 0, 0xffff);

            if (retval < 0)
            {
                cli_printf (fd, "\r\nBad address\r\n");
                continue;
            }

            data = (unsigned int) MacReadReg16 (address);

            cli_printf (fd, "\r\n(0x%04x) = 0x%04x\r\n", address, data);
        }
    }

  EXIT:
    return 0;
}

/**************************************************************
 * wireless_write_reg16()
 **************************************************************/
static int wireless_write_reg16 (int fd)
{
    char input_buffer[FCC_INPUT_BUFFER_SIZE];
    unsigned int address;
    unsigned int data;
    int retval;

    while (1)
    {

        /* get register address */
        while (1)
        {
            /* get address */
            cli_printf (fd, "\r\nEnter register address (e.g. 0x1004, 'q' to quit)");
            cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);

            retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);

            if (retval < 0)
            {
                goto EXIT;
            }

            if (retval > 0)
            {
                if (input_buffer[0] == 'q')
                {
                    goto EXIT;
                }

                retval = cli_get_number (input_buffer, &address, 0, 0xffff);

                if (retval < 0)
                {
                    cli_printf (fd, "\r\nBad address\r\n");
                    continue;
                }

                break;
            }
        }

        /* get register data */
        while (1)
        {
            /* get address */
            cli_printf (fd, "\r\nEnter data (e.g. 0x1004, 'q' to quit)");
            cli_printf (fd, "\r\n%s", RADIO_TST_PROMPT);

            retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);

            if (retval < 0)
            {
                goto EXIT;
            }

            if (retval > 0)
            {
                if (input_buffer[0] == 'q')
                {
                    goto EXIT;
                }

                retval = cli_get_number (input_buffer, &data, 0, 0xffff);

                if (retval < 0)
                {
                    cli_printf (fd, "\r\nBad data\r\n");
                    continue;
                }

                break;
            }
        }

        MacWriteReg16 (address, (uint16) data);
    }

  EXIT:

    return 0;
}


/**************************************************************
 * wireless_set_ps_timings() - powersave timings
 **************************************************************/
void wireless_set_ps_timings(int fd)
{
#ifdef MAC_PS_ENABLED
    char input_buffer[FCC_INPUT_BUFFER_SIZE];
    unsigned int value;
    int retval;
    wln_duty_cycle dutyCycle;
    
    while (1)
    {
        
        wln_get_duty_cycle(&dutyCycle);
        
        /* 802.11 transmit rf channel*/
        cli_printf(fd, "\r\nEnter ON period in mil seconds (%d) ", (int)dutyCycle.ontime);
        cli_printf(fd, "\r\n%s", RADIO_TST_PROMPT);
        
        retval = cli_getline(fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);
        if (retval < 0)
        {
            return;
        }

        if (retval > 0)
        {
            retval = cli_get_number(input_buffer, &value, WLN_PS_MIN_ON_TIME, 50000);
            
            if (retval < 0)
            {
                cli_printf(fd, "\r\nBad value, has to be between 100 and 50000\r\n");
                continue;
            }
            
            dutyCycle.ontime = (uint16)value;            
        }

        break;
    }

    while (1)
    {
        /* 802.11 transmit rf channel*/
        cli_printf(fd, "\r\nEnter OFF period in mil seconds (%d) ", (int)dutyCycle.offtime);
        cli_printf(fd, "\r\n%s", RADIO_TST_PROMPT);
        
        retval = cli_getline(fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);
        if (retval < 0)
        {
            return;
        }

        if (retval > 0)
        {
            retval = cli_get_number(input_buffer, &value, 0, WLN_PS_MAX_OFF_TIME);
            
            if (retval < 0)
            {
                cli_printf(fd, "\r\nBad value, has to be between 0 and 500\r\n");
                continue;
            }
            
            dutyCycle.offtime = (uint16)value;            
        }

        break;
    }
    
    if (customizeSetWirelessDutyCycle(&dutyCycle) == 0)
    {
        cli_printf(fd, "\r\nUpdated in NVRAM, may require reset for the change to take effect!\r\n");    
    }

    wln_set_duty_cycle(&dutyCycle);
    
#else
    cli_printf(fd, "\r\nPowersave mode is not supported!\r\n");    
#endif
}

#ifdef AIROHA_TRANSCEIVER
static void wireless_enable_closedloop_power_control (int fd)
{
    char input_buffer[FCC_INPUT_BUFFER_SIZE];
    unsigned int value;
    int retval;
    
    while (1)
    {     
           
        /* 802.11 transmit rf channel*/
        cli_printf(fd, "\r\nEnter 1 to enable closed-loop power control, 0 to disable (%d) ", (int)enablePowerControl);
        cli_printf(fd, "\r\n%s", RADIO_TST_PROMPT);
        
        retval = cli_getline(fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);
        if (retval < 0)
        {
            return;
        }

        if (retval > 0)
        {
            retval = cli_get_number(input_buffer, &value, 0, 1);
            
            if (retval < 0)
            {
                cli_printf(fd, "\r\nBad value, has to be between 0 or 1\r\n");
                continue;
            }
            
            enablePowerControl = value;            
        }

        break;
    }

    if(enablePowerControl) 
    {
        txPowerInDBM = TRUE;
        cli_printf(fd, "\r\nClosed-loop power control is enabled and you must enter tx power in dbm!\r\n"); 
#if AIROHA_PWR_CALIBRATION
        powerControlForTstWifi(TRUE);
#endif
    }
    else
    {
    	txPowerInDBM = FALSE;
        cli_printf(fd, "\r\nClosed-loop power control is disabled!\r\n"); 
#if AIROHA_PWR_CALIBRATION
        powerControlForTstWifi(FALSE);
#endif
#if 0    /* When closed loop is disable, only enter txpower in index */
            while (1)
            {     
                   
                /* 802.11 transmit rf channel*/
                cli_printf(fd, "\r\nEnter 1 to enter tx power in dbm, 0 to enter tx power in index (%d) ", (int)txPowerInDBM );
                cli_printf(fd, "\r\n%s", RADIO_TST_PROMPT);
                
                retval = cli_getline(fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);
                if (retval < 0)
                {
                    return;
                }
        
                if (retval > 0)
                {
                    retval = cli_get_number(input_buffer, &value, 0, 1);
                    
                    if (retval < 0)
                    {
                        cli_printf(fd, "\r\nBad value, has to be between 0 or 1\r\n");
                        continue;
                    }
                    
                    txPowerInDBM = value;            
                }

                break;
        }
#endif
    }  
    
   // cli_printf(fd, "\r\nenablePowerControl=%d, txPowerInDBM= %d\r\n", (int)enablePowerControl, (int)txPowerInDBM); 
}
#endif


/**************************************************************
 * cli_tst_wifi()
 **************************************************************/
int cli_tst_wifi (int fd, int n, char *args[])
{
    enum radio_test_t test = RADIO_TX_CONTINUOUS_WIRELESS_TEST;
    /* unused parameters */
    /* Tracks the last test entered by the user at the main menu
     * Used in case of quick testing to re-rum the previous test */
    unsigned int menu_select = 0;
     
    (void) n;
    (void) args;
 
    cli_printf (fd, "\r\nTest 802.11 radio transceiver:\r\n\r\n");

    /* Displays the main menu listing all the tests */
    while (1)
    {
        /* cli_tst_wifi_stay_in_loop is 0, when the user passes through the main menu
         * In case of using the quick test sub menu to change a test parameter value,
         * the value of this variable is 1 */
        if(cli_tst_wifi_stay_in_loop == 0) 
        {
            cli_tst_wifi_quick_test = 0; 

            cli_printf(fd, "\r\n1) Wireless Continuous Transmit Test");
            cli_printf(fd, "\r\n2) Start Wireless Continuous Transmit Test");
            cli_printf(fd, "\r\n3) Stop Wireless Continuous Transmit Test");
            cli_printf(fd, "\r\n4) Wireless Silent Test");
            cli_printf(fd, "\r\n5) Wireless Transmit Periodic frame Test");
            cli_printf(fd, "\r\n6) Write RF");
            cli_printf(fd, "\r\n7) Read RF");
            cli_printf(fd, "\r\n8) Write Reg8");
            cli_printf(fd, "\r\n9) Read Reg8");
            cli_printf(fd, "\r\n10) Write Reg16");
            cli_printf(fd, "\r\n11) Read Reg16");
            cli_printf(fd, "\r\n12) Write Reg32");
            cli_printf(fd, "\r\n13) Read Reg32");
            cli_printf(fd, "\r\n14) Start Wireless Periodic Transmit Test");
            cli_printf(fd, "\r\n15) Stop Wireless Periodic Transmit Test");
            cli_printf(fd, "\r\n16) Read Radio Mac Address");
            cli_printf(fd, "\r\n17) Write Radio Mac Address");
            cli_printf(fd, "\r\n18) Read Radio Version-Revision");
            cli_printf(fd, "\r\n19) Re-run last parametric RF test");
            cli_printf(fd, "\r\n20) Put CPU to sleep");
            cli_printf(fd, "\r\n21) Set powersave time");
            cli_printf(fd, "\r\n22) Quit");
#ifdef AIROHA_TRANSCEIVER
            cli_printf(fd, "\r\n23) Enable/Disable closed-loop power control");
#endif

            cli_printf(fd, "\r\n%s", RADIO_TST_PROMPT);

            {
                char input_buffer[FCC_INPUT_BUFFER_SIZE];
                int retval;
                unsigned int value;

                /* get a line of input from the user */
                retval = cli_getline (fd, input_buffer, FCC_INPUT_BUFFER_SIZE, RADIO_TST_PROMPT, 1,0,0);

                if (retval < 0)
                {
                    return 0;
                }

                /* verify the input is valid */
                retval = cli_get_number (input_buffer, &value, 1, 23);
                if (retval < 0)
                {
                    cli_printf (fd, "\r\n Bad value, try again:\r\n");
                }
                else
                {
                    /* Assign to variable test, based on the input by the user at main menu */
                    switch(value)
                    {
                        case 1:
                            test = RADIO_TX_CONTINUOUS_WIRELESS_TEST;
                            break;
                        
                        case 2:
                            test = RADIO_START_CONTINUOUS_TRANSMIT;
                            break;

                        case 3:
                            test = RADIO_STOP_CONTINUOUS_TRANSMIT;
                            break;

                        case 4:
                            test = RADIO_RX_SILENT_WIRELESS_TEST;
                            break;

                        case 5:
                            test = RADIO_TX_PERIODIC_FRAME_TRANSMIT;
                            break;

                        case 6:
                            test = RADIO_WRITE_RF;
                            break;

                        case 7:
                            test = RADIO_READ_RF;
                            break;

                        case 8:
                            test = RADIO_WRITE_REG8;
                            break;

                        case 9:
                            test = RADIO_READ_REG8;
                            break;

                        case 10:
                            test = RADIO_WRITE_REG16;
                            break;

                        case 11:
                            test = RADIO_READ_REG16;
                            break;

                        case 12:
                            test = RADIO_WRITE_REG32;
                            break;

                        case 13:
                            test = RADIO_READ_REG32;
                            break;
                        
                        case 14:
                            test = RADIO_START_TX_PERIODIC_FRAME_TRANSMIT;
                            break;

                        case 15:
                            test = RADIO_STOP_TX_PERIODIC_FRAME_TRANSMIT;
                            break;

                        case 16:
                            test = RADIO_READ_MAC_ADDRESS;
                            break;

                        case 17:
                            test = RADIO_WRITE_MAC_ADDRESS;
                            break;

                        case 18:
                            test = RADIO_READ_VERSION_REVISION;
                            break;

                        case 19:
                            test = RADIO_RERUN_LAST_TEST;
                            break;

                        case 20:
                            test = RADIO_SLEEP;
                            break;

                        case 21:
                            test = POWER_SAVE_MODE;
                            break;
                            
                        case 22:
                            goto EXIT;
                            break;
#if (AIROHA_TRANSCEIVER)                        
                         case 23:
                            test = RADIO_ENABLE_CLOSEDLOOP_POWER_CONTROL;
                            break;
#endif
                       
                        default:
                            assert(0);
                            break;
                    }
                    /* exit menu loop */
                    /* break; */
                    menu_select = test;
                }
            }
        }
        else
            test = menu_select;

        /* Call the appropriate function depending on the test entered by the user */
        switch (test)
        {
        case RADIO_TX_CONTINUOUS_WIRELESS_TEST:
        case RADIO_RX_SILENT_WIRELESS_TEST:
        case RADIO_START_CONTINUOUS_TRANSMIT:
        case RADIO_STOP_CONTINUOUS_TRANSMIT:
        case RADIO_TX_PERIODIC_FRAME_TRANSMIT:
        case RADIO_START_TX_PERIODIC_FRAME_TRANSMIT:
        case RADIO_STOP_TX_PERIODIC_FRAME_TRANSMIT:
        case RADIO_RERUN_LAST_TEST:
            wireless_test (fd, test);
            break;

        case RADIO_WRITE_RF:
            wireless_write_rf (fd);
            break;

        case RADIO_READ_RF:
            wireless_read_rf (fd);
            break;

        case RADIO_WRITE_REG8:
            break;

        case RADIO_READ_REG8:
            break;

        case RADIO_WRITE_REG16:
            wireless_write_reg16 (fd);
            break;

        case RADIO_READ_REG16:
            wireless_read_reg16 (fd);
            break;

        case RADIO_WRITE_REG32:
            wireless_write_reg32 (fd);
            break;

        case RADIO_READ_REG32:
            wireless_read_reg32 (fd);
            break;

        case RADIO_READ_MAC_ADDRESS:
            wireless_read_mac_address (fd);
            break;

        case RADIO_WRITE_MAC_ADDRESS:
            wireless_write_mac_address (fd);
            break;

        case RADIO_READ_VERSION_REVISION:
            wireless_read_radio_revision (fd);
            break;

        case RADIO_SLEEP:
            wireless_sleep (fd);
            break;

        case POWER_SAVE_MODE:
            wireless_set_ps_timings(fd);
            break;
#if (AIROHA_TRANSCEIVER)            
        case RADIO_ENABLE_CLOSEDLOOP_POWER_CONTROL:                	
            wireless_enable_closedloop_power_control (fd);
            break;    
#endif           

        default:
            cli_printf (fd, "\r\n Unknown test error\r\n");
            break;
        }

        if((cli_tst_wifi_quick_test == 0) && ((test == RADIO_TX_CONTINUOUS_WIRELESS_TEST) || (test == RADIO_TX_PERIODIC_FRAME_TRANSMIT)))
            cli_tst_wifi_stay_in_loop = 1;
    } 

 EXIT:
    {   
        cli_tst_wifi_stay_in_loop = 0; 
        return 0;
    }
}
#endif
#endif

