/************************************************************/
/*															*/
/*	Filename: perToneApps.c										*/
/*															*/
/*  Description:	This file contains bitloading extraction functions		*/
/*															*/
/*	Ikanos Communications 01/2001							*/
/*															*/
/* 
$Revision: 1.1 $
$Date: 2006/10/16 04:34:50 $
*/
/************************************************************/

/* #includes*/
#include <stdio.h>
#include <string.h>


#include "appconfig.h"
#include "apitype.h"
#include "apistruct.h"
#include "host_ver.h"
#include "notchBnd.h"
#include "uiUtil.h"
#include "oampdb.h" /* IXDP425 */
#include "password.h"
#include "apidef.h"
#include "portmap.h"
#include "pprofile.h"
#include "oampdef.h"
#include "autoStart.h"
#include "apposmacro.h"
#include "oampstruct.h"
#include "HostPtmfApi.h"
#include "consoleUtil.h"
#include "bmetl.h"
#include "oampproto.h"
#include "eocapp.h"	
#include "ipos.h"
#include "report.h"

#define UINT8   unsigned char /* IXDP425 */
#define UINT16   unsigned short /* IXDP425 */
#define INT16    short /* IXDP425 */


extern void (*OptionCmdHandler)(void *);
extern int getPortNum (ipos_port_id *pid);
extern void dmaRead (int bmeNum, UINT32 srcAddr, BYTE *, UINT32);
extern BYTE DmaArray[];
extern unsigned int OhmGetMaxNumOfTonePerLineType (unsigned int ulLineType);
void perToneOptHandler(void	*pData);

typedef enum {
        PERF_METER_PER_TONE_INVALID_DATA = 0,
        PERF_METER_PER_TONE_RX_BITS, // 1
        PERF_METER_PER_TONE_SNR,        // 2    
        PERF_METER_PER_TONE_RX_ATTN, // 3
        PERF_METER_PER_TONE_CURRENT_FEQ_FINE,// 4
        PERF_METER_PER_TONE_TX_POWER,// 5
        PERF_METER_PER_TONE_SNR_MARGIN,// 6
        PERF_METER_PER_TONE_TX_BITS,// 7
        PERF_METER_PER_TONE_TX_GI,// 8
        PERF_METER_PER_TONE_RX_GI,// 9
        PERF_METER_PER_TONE_QUIET_LINE_NOISE,// 10
        PERF_METER_PER_TONE_CURRENT_FEQ_COARSE,// 11
        PERF_METER_PER_TONE_FEQ_FINE, // 12

        PERF_METER_PER_TONE_SNR_FE,// 13
        PERF_METER_PER_TONE_QLN_FE,// 14
        PERF_METER_PER_TONE_HLOG_FE,// 15

        PERF_METER_PER_TONE_MULTI_READ,// 16
        PERF_METER_PER_TONE_NEXTMULTI_READ,// 17
        PERF_METER_PER_TONE_BLOCK_READ,// 18

        PERF_METER_PER_TONE_NACK,// 19
        PERF_METER_PER_TONE_END// 20
} tPerfOptCmd;
typedef struct 
{
    UINT8 subOpCode;
    UINT8 perfType;
    UINT16 startTone ;
    UINT16 stopTone ;
} perfOptCmd;

typedef struct {
	tPerfOptCmd	perfType;
	UINT32	len;
	UINT32   addr;
} PERF_OPT;

static perfOptCmd	reqCmd;
static int StartToneIndex, StopToneIndex;

/******************************************************
 *  Function:		 getStartStopToneIndices() 
 *  Description:	 get the Start and Stop indices from the user.
 *
 *****************************************************
*/
void getStartStopToneIndices (int max_tones, int *start, int *stop)
{
	char			str[256];
  int menuInput = 0;
do {
  *start = 0;
    printf ("\nEnter start tone index [0-%d]: ", max_tones-1);
    gets (str);
  if ((str[0] == '\n') || (str[0] == '\0'))
    menuInput = *start;
  else
      sscanf (str,"%i",&menuInput); 

    if (menuInput <= 0)
    *start = 0;
  else
    *start = menuInput;
} while ((menuInput<0) || (menuInput > (max_tones-1)));

do {    
  *stop = max_tones-1;
    printf ("Enter stop tone index [0-%d]: ", max_tones-1);
	gets (str);
  if ((str[0] == '\n') || (str[0] == '\0'))
    menuInput = *stop;
  else
	  sscanf (str,"%i",&menuInput); 

	if (menuInput <= 0)
    *stop = 0;
    else if ( (menuInput - *start) >= max_tones)
        *stop = *start + max_tones - 1;
  else
    *stop = menuInput;
} while ((menuInput<0) || (menuInput > (max_tones-1)));
  /* Don't let the stop index less than Start index */
  if (*stop < *start)
    *stop = *start;

  printf("Start = %d, Stop = %d\n", *start, *stop);

  return;
}

/******************************************************
 *  Function:        getSignleToneIndex() 
 *  Description:     get a single sub carrier index from the user.
 *
 *****************************************************
*/
void getSingleToneIndex (int max_tones, unsigned int *toneIndex)
{
    char            str[256];
  int menuInput = 0;
do {
  *toneIndex = 0;
    printf ("\nEnter Tone Index [0-%d]: ", max_tones-1) ;
    gets (str);
  if ((str[0] == '\n') || (str[0] == '\0'))
    menuInput = *toneIndex;
  else
      sscanf (str,"%i",&menuInput); 

    if ((menuInput <= 0) || (menuInput > max_tones))
    *toneIndex = 0;
  else
    *toneIndex = menuInput ;
} while ((menuInput<0) || (menuInput > (max_tones-1)));
  printf("Tone Index = %d\n", *toneIndex) ;

  return;
}


/******************************************************
 *  Function:		 writeBitTable() 
 *  Description:	 print the bitloading table
 *
 *****************************************************
*/


void writeBitTable(short *data, int len)
{
    int     i;
    int     endTone=StopToneIndex;
#if 0       
    FILE    *fp;
    
    if((fp = fopen("/tgtsvr/bitTab.m", "wt"))!=NULL) {
        fprintf(fp, "bitTab = [");
        for(i=0;i<len;i++)  
            fprintf(fp,"\t%d\n", data[i]);
        fprintf(fp, "];");
        fclose(fp); 
    } else
        printf("\ncannot open bitTab.m");
#else
    if (StopToneIndex-StartToneIndex >= len)
        endTone = StartToneIndex+len-1;

    printf("\n    Tone#       # of Bits Loaded");
    printf("\n    ----------------------------");

    for(i=StartToneIndex; i<=endTone; i++) 
        printf("\n    %4d             %6d",i,data[i]);
#endif      
}

/******************************************************
 *  Function:        writeQLNTable() 
 *  Description:     print the QLN table
 *
 *****************************************************
*/


void writeQLNTable(int *data, int len)
{
    int     i;
    printf("\n    Tone#        RAW Quiet Line Noise");
    printf("\n    -------------------------------------------");
    for(i=StartToneIndex;(i<=StopToneIndex) && (i<len);i++) 
        printf("\n     %4d            %8d",i,data[i]);
}


/******************************************************
 *  Function:		 writeSnrTable() 
 *  Description:	 print the SNR table
 *
 *****************************************************
*/


void writeSnrTable(short *data, int len)
{
	int		i;
	printf("\n    Tone#              SNR (in log2 Q.9 format)");
	printf("\n    -------------------------------------------");
	for(i=StartToneIndex;(i<=StopToneIndex) && (i<len);i++)	
		printf("\n     %4d              %6d",i,data[i]);
}
/******************************************************
 *  Function:        writeFeSnrTable() 
 *  Description:     print the Far End SNR table
 *
 *****************************************************
*/
void writeFeSnrTable(U8 *data, int len)
{
    int i ;
    int SnrVal = 0 ;

    printf("\n   SNR Measurement Time = %d (symbols)", *((U16*)data)) ;
    printf("\n   Tone#\tFE_SNR(dB)");
    data = data+2 ; len -= 2 ;
    printf("\n   =====\t==========") ;
    for(i=StartToneIndex;(i<=StopToneIndex) && (i<len);i++) 
    {
        /* As defined in g.992.3 std. section 8.12.3.3 */
        SnrVal = -32 + (data[i]/2) ;
        printf("\n   %d\t\t%d", i, SnrVal) ;
    }    
}

/******************************************************
 *  Function:        writeFeQlnTable() 
 *  Description:     print the Far End QLN table
 *
 *****************************************************
*/
void writeFeQlnTable(U8 *data, int len)
{
    int i ;
    int QlnVal = 0 ;

    printf("\n   QLN Measurement Time = %d (symbols)", *((U16*)data)) ;
    printf("\n   Tone#\tFE_QLN (dBm/Hz)");
    data = data+2 ; len -= 2 ;
    printf("\n   =====\t==============") ;
    
    for(i=StartToneIndex;(i<=StopToneIndex) && (i<len);i++) 
    {
        /* As defined in g.992.3 std. section 8.12.3.2 */
        QlnVal = -23 - (data[i]/2) ;
        printf("\n   %d\t\t%d", i, QlnVal) ;
    }
}

/******************************************************
 *  Function:        writeFeHlogTable() 
 *  Description:     print the Far End HLOG table
 *
 *****************************************************
*/
void writeFeHlogTable(short *data, int len)
{
    int i ;
    int HlogVal = 0 ;

    printf("\n   HLOG Measurement Time = %d (symbols)", data[0]) ;
    printf("\n   Tone#\tFE_HLOG (dB)") ;
    data++ ; len-- ;
    printf("\n   =====\t============") ;
    
    for(i=StartToneIndex;(i<=StopToneIndex) ;i++) 
    {
        /* As defined in g.992.3 std. section 8.12.3.1 */
        HlogVal = 6 - (data[i]/10) ;
        printf("\n   %d\t\t%d", i, HlogVal) ;
    }
}

void writeFeTestParamMultiRead(U8 *data, int len)
{
    short HlogVal = 0 ;
    int QlnVal = 0 ;
    int SnrVal = 0 ;
    unsigned short HlogTime = 0 ;
    unsigned short QlnTime = 0 ;
    unsigned short SnrTime = 0 ;
    int i = 0 ;
    
    data+=2; //TODO- permanent workaround for alignment problem

    if ((len != 10) || (!data))
    {
        printf("\nIncorrect Length/Invalid Pointer:%d", len) ;
        return ; 
    }

    printf("\nSubcarrier/Tone Index=%d", StartToneIndex) ;
    
    HlogTime = *((unsigned short*)data) ; 
    data += 2 ; len -= 2 ;
    HlogVal = 6 - ((*((unsigned short*)data))/10) ;
    printf("\n   HLOG = %d (dB)\t Measurement Time = %d (symbols)", HlogVal, HlogTime) ;
    data += 2 ; len -= 2 ;
    
    QlnTime = *((unsigned short*)data) ; 
    data += 2 ; len -= 2 ;
    QlnVal = -23 - ((*((unsigned char*)data))/2) ;
    printf("\n   QLN  = %d (dBm/Hz)\t Measurement Time = %d (symbols) ", QlnVal, QlnTime) ;
    data++ ; len-- ;
    
    SnrTime = *((unsigned short*)data) ; 
    data += 2 ; len -= 2 ;
    SnrVal = -32  +  ((*((unsigned char*)data))/2) ;
    printf("\n   SNR  = %d (dB)\t Measurement Time = %d (symbols)", SnrVal, SnrTime) ;
    
    return ;
}


void writeFeTestParamBlockRead(U8 *data, int len)
{
    int i ;
    short HlogVal = 0 ;
    int QlnVal = 0 ;
    int SnrVal = 0 ;
    unsigned short Time = 0 ;
    
    if (!data)
    {
        printf("\nInvalid Pointer") ;
        return ; 
    }
    data+=2; //TODO- permanent workaround for alignment problem

    printf("\nSubcarrier/Tone StartIndex=%d, StopIndex=%d", StartToneIndex, StopToneIndex) ;
    
    Time = *((unsigned short*)data) ; 
    printf("\n   HLOG Measurement Time = %d (symbols)", Time) ;
    data += 2 ; len -= 2 ;
    printf("\n   Tone#\tFE_HLOG (dB)") ;
    printf("\n   =====\t============") ;
    for(i=StartToneIndex;(i<=StopToneIndex) ;i++) 
    {
        HlogVal = 6 - ((*((unsigned short*)data))/10) ;
        printf("\n   %d\t\t%d", i, HlogVal) ;
        data += 2 ; len -= 2 ;
    }
        
    Time = *((unsigned short*)data) ; 
    printf("\n   QLN Measurement Time = %d (symbols)", Time) ;
    data += 2 ; len -= 2 ;
    printf("\n   Tone#\tFE_QLN (dBm/Hz)");
    printf("\n   =====\t============") ;
    for(i=StartToneIndex;(i<=StopToneIndex); i++) 
    {
        QlnVal = -23 - ((*((unsigned char*)data))/2) ;
        printf("\n   %d\t\t%d", i, QlnVal) ;
        data++ ; len-- ;
    }

    Time = *((unsigned short*)data) ; 
    printf("\n   QLN Measurement Time = %d (symbols)", Time) ;
    data += 2 ; len -= 2 ;
    printf("\n   Tone#\tFE_SNR (dB)");
    printf("\n   =====\t============") ;
    for(i=StartToneIndex;(i<=StopToneIndex);i++) 
    {
        SnrVal = -32  +  ((*((unsigned char*)data))/2) ;
        printf("\n   %d\t\t%d", i, SnrVal) ;
        data++ ; len-- ;
    }
   
    return ;
}


/******************************************************
 *  Function:        writeCoarseFEQ() 
 *  Description:     print the coarse FEQ table
 *                       packed 2 values per U8
 *
 *****************************************************/

static void
writeCoarseFEQ( U8 *pCoarseFEQ, int length )
{
    int     iter, indxxx, complete = 0, value = 0;

    printf("\n    Tone#              Coarse FEQ");
    printf("\n    ----------------------------");

    iter = StartToneIndex;
    while (complete == 0)
    {
        if (iter<=StopToneIndex)
        {
            indxxx = iter >> 1;
            if (indxxx < length)
            {
                if ((iter & 1) == 0)
                  value = ((pCoarseFEQ[ indxxx ] >> 4) & 0xf);
                else
                  value = (pCoarseFEQ[ indxxx ] & 0xf);

                printf("\n     %d              %d",iter, value );

                iter++;
            }
            else
              complete = 1;
        }
        else
          complete = 1;
    }
}


/******************************************************
 *  Function:		 writeAttnTable() 
 *  Description:	 print the Attn table
 *
 *****************************************************
*/


void writeAttnTable(int *data, int len)
{
	int		i;
	printf("\n    Tone#              Attn * 0.1 dB");
	printf("\n    ---------------------------------");
	for(i=StartToneIndex;(i<=StopToneIndex) && (i<len);i++)	
		printf("\n     %4d             %6d",i,data[i]);
}


/******************************************************
 *  Function:		 writePowerTable() 
 *  Description:	 print the PSD table
 *
 *****************************************************
*/


void writePowerTable(int *data, int len)
{
	int		i;
	printf("\n    Tone#        Tx Psd * 0.1 dBm/Hz     Tx Gain (in linear scale)");
	printf("\n    --------------------------------------------------------------");
	for(i=StartToneIndex;(i<=StopToneIndex) && (i<len);i++)	
		printf("\n     %4d            %6d            %6d",i,(data[i] >> 16) - 1400, (data[i]&0xFFFF));
}



/******************************************************
 *  Function:		 writeFeqTable() 
 *  Description:	 print the Feq table
 *
 *****************************************************
*/


void writeFeqTable(short *data, int len)
{
	int		i;
	printf("\n    Tone#          FEQ (Re + j Im) Complex linear values");
	printf("\n    ----------------------------");
	for(i=StartToneIndex;(i<=StopToneIndex) && (i<len);i++)	
		printf("\n     %4d      %6d %6d",i,data[i*2], data[i*2+1]);
}

/******************************************************
 *  Function:        writeGiTable() 
 *  Description:     print the SNR table
 *
 *****************************************************
*/


void writeGiTable(short *data, int len)
{
    int     i;
    printf("\n    Tone#              Gi (in log2 3.9 format)");
    printf("\n    -------------------------------------------");
    for(i=StartToneIndex;(i<=StopToneIndex) && (i<len);i++) 
        printf("\n     %4d             %6d",i,data[i]);
}


/******************************************************
 *  Function:		 perToneMenu()
 *  Description:	 Menu for Rx and Tx Per Bit Loading apis
 *
 *****************************************************
*/
void perToneMenu()
{
    char            TlStr[64];
    char            str[256];
    ipos_port_id    pid;
    int         menuInput;
    ShowtimeParams *pSTp = NULL ;
    unsigned int ulMaxTone = 0 ;
    
   /* set the appropriate callback handler */
	OptionCmdHandler = perToneOptHandler;

    reqCmd.subOpCode = 1;
    TlStr[0] = '\0';
    printf ("\n   1) Get Rx Per Tone BitLoading Info Near End");
    printf ("\n   2) Get Rx Per Tone SNR Info Near End");
    printf ("\n   3) Get Rx Per Tone Attenuation Near End");
    printf ("\n   4) Get Rx Per Tone Current FEQ fine Coeffs Near End");
    printf ("\n   5) Get Tx Per Tone Tx Power Near End");
    printf ("\n   6) Get Rx Per Tone Noise Margin Near End");
    printf ("\n   7) Get Tx Per Tone BitLoading Info Near End");
    printf ("\n   8) Get Tx Per Tone Gi Near End");
    printf ("\n   9) Get Rx Per Tone Gi Near End");
    printf ("\n  10) Get Per Tone Quiet Line Noise");
    printf ("\n  11) Get Per Tone Coarse FEQ");

    printf ("\n   12) Get Far End Per Tone SNR Info ");
    printf ("\n   13) Get Far End Per Tone QLN Info");
    printf ("\n   14) Get Far End Per Tone HLOG Info");
	
    printf ("\n   15) Get Far End Test Param Multi-Read");
    printf ("\n   16) Get Far End Next Test Param Multi-Read");
    printf ("\n   17) Get Far End Test Param Block Read");

    printf ("\n\nEnter input: ");
    gets (str);
    sscanf (str,"%i",&menuInput); 
    if (menuInput >PERF_METER_PER_TONE_INVALID_DATA && menuInput< PERF_METER_PER_TONE_END)
    {
        if (getPortNum(&pid) > 0)
        {
            pSTp = getShowtimeParamsRef(pid) ;

                if (menuInput>=1 && menuInput <= 11) 
                {   // for vdsl1/adsl1
                
                    getStartStopToneIndices (4096, &StartToneIndex, &StopToneIndex);
                }    
                else 
                {
                    if ((oampGetPortState(pid) != uSHOWTIME))
                    {
                        printf("\n b%dp%d is not in showtime", pid.bmeNum, pid.portNum) ;
                        return ;
                    }
                    
                    if (((pSTp->LineType & VDSL2_TYPE_SUPPORTED) || 
                            (pSTp->LineType & ADSL2_TYPE_SUPPORTED)))
                    { // for vdsl2/adsl2/2+

                        
                        if (!(ulMaxTone = OhmGetMaxNumOfTonePerLineType(pSTp->LineType)))
                            return ; //un-recognised vdsl2/adsl2/2+ line-type
                    } 
                    else 
                    {
                        //options between 12 and 17 is supported only for adsl2/2+
                        printf("\n Command support ONLY for VDSL2/ADSL2/2+") ;
                        return ;
                    }
                }

                      switch (menuInput)
                      {

                        case 1: reqCmd.perfType = PERF_METER_PER_TONE_RX_BITS; break;
                        case 2: reqCmd.perfType = PERF_METER_PER_TONE_SNR; break;
                        case 3: reqCmd.perfType = PERF_METER_PER_TONE_RX_ATTN; break;
                        case 4: reqCmd.perfType = PERF_METER_PER_TONE_CURRENT_FEQ_FINE; break;
                        case 5: reqCmd.perfType = PERF_METER_PER_TONE_TX_POWER; break;
                        case 6: reqCmd.perfType = PERF_METER_PER_TONE_SNR_MARGIN; break;
                        case 7: reqCmd.perfType = PERF_METER_PER_TONE_TX_BITS; break;
                        case 8: reqCmd.perfType = PERF_METER_PER_TONE_TX_GI; break;
                        case 9: reqCmd.perfType = PERF_METER_PER_TONE_RX_GI; break;
                        case 10: reqCmd.perfType = PERF_METER_PER_TONE_QUIET_LINE_NOISE; break;
                        case 11: reqCmd.perfType = PERF_METER_PER_TONE_CURRENT_FEQ_COARSE; break;

                            case 12:
                                if (pSTp->LineType & ADSL2_TYPE_SUPPORTED) {
                                getStartStopToneIndices (ulMaxTone, 
                                                                    &StartToneIndex, &StopToneIndex) ;
                                reqCmd.perfType = PERF_METER_PER_TONE_SNR_FE; 
                                } else {
                                    printf("\n Command support ONLY for ADSL2/2+") ;
                                    return ;
                                }
                                break;
                                    
                            case 13: 
                                if (pSTp->LineType & ADSL2_TYPE_SUPPORTED) {
                                getStartStopToneIndices (ulMaxTone,
                                                                    &StartToneIndex, &StopToneIndex) ;
                                reqCmd.perfType = PERF_METER_PER_TONE_QLN_FE; 
                                } else {
                                    printf("\n Command support ONLY for ADSL2/2+") ;
                                    return ;
                                }
                                break;

                            case 14:
                                if (pSTp->LineType & ADSL2_TYPE_SUPPORTED) {
                                getStartStopToneIndices (ulMaxTone, 
                                                                    &StartToneIndex, &StopToneIndex) ;
                                reqCmd.perfType = PERF_METER_PER_TONE_HLOG_FE; 
                                } else {
                                    printf("\n Command support ONLY for ADSL2/2+") ;
                                    return ;
                                }
                                break;

                            case 15: //multi-read
                                getSingleToneIndex (ulMaxTone, &StartToneIndex) ;
                                StopToneIndex = 0 ;
                                reqCmd.perfType = PERF_METER_PER_TONE_MULTI_READ ; 
                                break ;

                            case 16: //multi-next
                                StartToneIndex++ ; 
                                StopToneIndex = 0 ;
                                reqCmd.perfType = PERF_METER_PER_TONE_NEXTMULTI_READ ; 
                                break ;

                            case 17: //block-read
                                getStartStopToneIndices (ulMaxTone, &StartToneIndex, &StopToneIndex) ;
                                reqCmd.perfType = PERF_METER_PER_TONE_BLOCK_READ; 
                                break ;
                            
                            default: 
                                reqCmd.perfType = PERF_METER_PER_TONE_INVALID_DATA; 
                                break ;
                      }

                if ((pSTp->LineType & ADSL2_TYPE_SUPPORTED) || (pSTp->LineType & VDSL2_TYPE_SUPPORTED)) 
                {
                        reqCmd.startTone = StartToneIndex ;
                        reqCmd.stopTone = StopToneIndex ;
                } 
                else 
                {
                    reqCmd.startTone = reqCmd.stopTone = 0 ; 
                }
                
                if (reqCmd.perfType == PERF_METER_PER_TONE_INVALID_DATA) 
                {
                    printf("\nInvalid Optional Command::%d\n",menuInput);
                    return;
                }
                sprintf (TlStr,"optionalCmd:0:%i:%i:%i:%i;", 
                            pid.bmeNum, pid.portNum, (UINT32)(&reqCmd), sizeof(perfOptCmd)) ;
        }
    } else {
    printf("\nInvalid Optional Command:%d\n", menuInput);
    return;
  }

    if (strlen(TlStr))
         ReceiveTLCommand (TlStr);
                    
    return;
}




/******************************************************
 *  Function:		 retrieveOptCmdResult()
 *  Description:	 Retrieve results of Optional Cmd
 *
 *****************************************************
*/
  
static void retrieveOptCmdResult(int bmeNum, UINT32 addr, UINT32 length, tPerfOptCmd perfType)
{

    if(perfType>PERF_METER_PER_TONE_INVALID_DATA && perfType<PERF_METER_PER_TONE_END)
    {
        if (length > 0)
        dmaRead (bmeNum, addr, DmaArray, length);
      
    switch(perfType) 
    {
      case PERF_METER_PER_TONE_RX_BITS:
      case PERF_METER_PER_TONE_TX_BITS:
        writeBitTable((short *)DmaArray, length>>1);
        break;
      case PERF_METER_PER_TONE_SNR_MARGIN:
      case PERF_METER_PER_TONE_SNR:
        writeSnrTable((short *)DmaArray, length>>1);
        break;
      case PERF_METER_PER_TONE_CURRENT_FEQ_FINE:
        writeFeqTable((short *)DmaArray, length>>2);
        break;
      case PERF_METER_PER_TONE_RX_ATTN:
        writeAttnTable((int *)DmaArray, length>>2);
        break;
      case PERF_METER_PER_TONE_TX_POWER:
        writePowerTable((int *)DmaArray, length>>2);
        break;
      case PERF_METER_PER_TONE_TX_GI:
      case PERF_METER_PER_TONE_RX_GI:
        writeGiTable((short *)DmaArray, length>>1);
        break;
      case PERF_METER_PER_TONE_QUIET_LINE_NOISE:
        writeQLNTable((int *)DmaArray, length>>2);
        break;

      case PERF_METER_PER_TONE_CURRENT_FEQ_COARSE:
        writeCoarseFEQ( (U8 *) DmaArray, length );
        break;

      case PERF_METER_PER_TONE_SNR_FE:
        writeFeSnrTable(DmaArray, length);
        break;
        
      case PERF_METER_PER_TONE_QLN_FE:
        writeFeQlnTable(DmaArray, length);
        break;
        
      case PERF_METER_PER_TONE_HLOG_FE:
        writeFeHlogTable((short *)DmaArray, length>>1);
        break;

          case PERF_METER_PER_TONE_MULTI_READ: //fall-thru
          case PERF_METER_PER_TONE_NEXTMULTI_READ:
            writeFeTestParamMultiRead(DmaArray, length);
            break;

          case PERF_METER_PER_TONE_BLOCK_READ:
            writeFeTestParamBlockRead(DmaArray, length);
            break;

          case  PERF_METER_PER_TONE_NACK:
                printf("\n Rxed TESTPARAM -NACK") ;
            break ;
            
          default:
                printf("\nunknown perftype %d", perfType);
            break;
        }   
    } else
        printf("\nunknown perftype %d", perfType);

	return;
}


/******************************************************
 *  Function:		 perToneOptHandler()
 *  Description:	 call back function to act on the 
 *                 result of the Optional Cmd
 *
 *****************************************************
*/

void perToneOptHandler(void	*pData)
{
	oamp_cb_msg			*pMsg = (oamp_cb_msg *)pData;
	ipos_port_id		pid;
	U32					cntRpt;
	U8					cmdTag;
	int					errCode;
  	ipos_opCmd_status 	*perf;
	PERF_OPT			*perfMeter;
		
	pid		=pMsg->portId;
	cntRpt	=pMsg->cntRpt;
	cmdTag	=pMsg->uid;
	errCode =pMsg->status;
	perf = (ipos_opCmd_status *) pMsg->par;	
//    if(perf->tag == 1) 
	{
		perfMeter = (PERF_OPT *)(perf->buf);
		printf("type = %d, len = %d, addr 0x%x", 
			perfMeter->perfType, perfMeter->len, perfMeter->addr);	

		iposTaskDelay(2);
		retrieveOptCmdResult(pid.bmeNum, perfMeter->addr, perfMeter->len, 
			perfMeter->perfType);


	}
}
