/*****************************************************************************
  $Workfile:   dapi.c  $
******************************************************************************

  FIRMWARE, Copyright (C) 2003
   All rights are reserved.  Reproduction in whole or in part is prohibited
   without the written consent of the copyright owner.

   The information and contents of this file are the proprietary information
   of Ikanos Communication and may not be disclosed or used without the
   formal written approval of Ikanos Communication Inc.

   This Copyright notice may not be removed or modified without prior
   written consent of Ikanos Communications, Inc.

  Purpose

  $Revision: 1.2 $
  $Date: 2006/12/12 10:53:07 $

*****************************************************************************/

/*****************************************************************************
                       I n c l u d e s
*****************************************************************************/
#include <string.h>
#include <stdio.h>
#include "dapi.h"
#include "bmeconfig.h"
#include "bmehwapi.h"

#ifndef USE_VXWORKS /* IXDP425 */
#include <v2pthread.h>
#endif
#ifdef	USE_EVENT_LOG
#include "time.h"
//#include "eventlog.h"
#endif
/*****************************************************************************
                        D e f i n e s
*****************************************************************************/
#define DEBUG_LEVEL                 (0)
#define TEST_LEVEL                  (0)
#if (DEBUG_LEVEL > 0)
#define DEBUG1_PRINTF(x) printf x
#else
#define DEBUG1_PRINTF(x)
#endif

#define IPOS_VERSION			(1)
/*****************************************************************************
                	         T y p e s
*****************************************************************************/
/*****************************************************************************
                           D a t a
*****************************************************************************/

/* Local Protoypes */

eApiRv SendBmeMessage(tBmeStruct *pBme, int PortNum, eCommands Cmd);
void convertDataToEndianFormat (BYTE bDataSize, BYTE *bDataPtr);


/* Local Variables */
//extern BYTE fifoStatus;
//extern BYTE msgRdyPending;
extern void wrDnld (int cnt);
extern int IniVer;
extern int dropFrameEnable;
extern HWAPI_RET_VAL bmeDnldProcedure (tBmeStruct *bmeStruct);extern HWAPI_RET_VAL bmeDnldProcedure (tBmeStruct *bmeStruct);
extern HWAPI_RET_VAL bmeWrMessage(tBmeStruct *bmeStruct, UINT32 destAddr, BYTE *data, int numData);
extern HWAPI_RET_VAL bmeRdMessage(tBmeStruct *bmeStruct, BYTE *message);
/* global variables */
//BYTE bDataReadPending = FALSE; /* used for BmeMemoryRead API to bypass NotifyHost function call */
volatile BYTE bDataAckPending = FALSE;  /* used for BmeMemoryWrite API to bypass NotifyHost function call */
#ifdef USE_BIG_ENDIAN_FORMAT
volatile BYTE HostCpuEndianType = BIG_ENDIAN_FORMAT;
#define MEMCPY(a, b, c, d)	memcpy(a, b, (c * d));
#else
volatile BYTE HostCpuEndianType = LITTLE_ENDIAN_FORMAT;
static void memcpyLittleEndian (BYTE *pData, BYTE *pParms, BYTE bDataSize, BYTE numData);
#define MEMCPY(a, b, c, d)	memcpyLittleEndian ((BYTE *)a, (BYTE *)b, c, d)
#endif
/* extern functions */
//extern void EventLog(const char *output, ...);
extern eBmeRv pollForDwTBitToBeCleared (tBmeStruct *pBme);
static void dapiRetrieveAlerts (U8 *data, struct tPmAlertParms *alertParm);
static void dapiRetrieveSnrAttn (U8 *data, struct tGetNeSnrAttn *snrParm);
static void dapiRetrieveSysConfig (U8 *data, struct tSystemProv *sysProvParms);
static void dapiRetrievePortConfig(U8 *data, struct tPortProfile *portProfile);

/*****************************************************************************
                  P r i v a t e  F u n c t i o n s
*****************************************************************************/
/*****************************************************************************
                  P u b l i c  F u n c t i o n s
*****************************************************************************/
/*************************************************************************
    Function: BmeStart

    Description: This command is used to start normal operation on the BME.
                The BME hardware will perform a power-on reset. The
                Power-on reset includes
                1. Holding the Tensilica processor by sending INACTIVE
                    signal to REL_CPU pin.
                2. Programming the DMA channel & the external memory
                    interface of the BME chip set
                3. Downloading the BME software code from host processor
                    memory to BME SRAM or any external memory.
                4. Releasing the Tensilica processor by sending ACTIVE
                    signal to REL_CPU pin.

Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    BmeState	 				INACTIVE
    BmeDnldVerifyState			DW_T_BIT_UNKNOWN_STATE

    EMIConfig.memType			SRAM / SDRAM / .....
    EMIConfig.sramMemSize		if SRAM
    EMIConfig.sdramMemSize		if SDRAM

    BmeNum						Index to BME number
    BMEbaseAddr					Base address of this BME
    BMEResetLineAddr			Address of Reset Line of BME
    BMECodeDnldAddr   			Address where BME Software has to be downloaded
    BMECodeSize 				Length of BME software code

    Return: See eApiRv
************************************************************************/

eApiRv BmeStart (tBmeStruct *pBme)
{

    eApiRv ApiRv=FAIL;
// printf("Fusiv : bmeStart() state :%x\n",pBme->BmeState);
    /* Abort the Host Resync process, if the BME is being started */
    pBme->hostResync = 0;

    switch (pBme->BmeState)
    {
    case INACTIVE:
    case SW_DNLD_IN_PROGRESS:
      pBme->BmeState = INACTIVE;
#ifndef CPE_30
{
           BYTE bTmpVal;

            /* check for DW_T bit to be zero. */

            /* read the DMA Status Port */
            bTmpVal = bmeRdStatus (pBme);

            /* check the status[1] (DW_T) bit of DMA Status Port to be zero.
           This indicates DPRAM is ready to take the data from the host. */
            /*	if (bTmpVal & DW_T_DMA_WRITE_DONE)
                {
                    EventLog ("b%dp0 ...BmeStart Rv FAIL: BmeState %d, DW_T is 1. FIFO not empty to take data from host"
                                ,pBme->BmeNum,pBme->BmeState);

                    return (FAIL);
                }
                else*/
}
#endif
      pBme->BmeDnldVerifyState = DW_T_BIT_RESET;

            if (bmeDnldProcedure (pBme) != HWAPI_DNLD_SUCCESS)
            {
         pBme->BmeState = INACTIVE;
                /*EventLog ("b%dp0 ...BmeStart Rv FAIL: BmeState %d, DW_T is 1. FIFO not empty to take data from host"
                            ,pBme->BmeNum,pBme->BmeState);
*/
                return(FAIL);
      }

      /* Note : no break here, as we need to fall through this case statement */

    case SW_DNLD_DONE:
      pBme->BmeState = SW_DNLD_VERIFICATION;
      /* Note : no break here, as we need to fall through this case statement */

    case SW_DNLD_VERIFICATION:
#if defined(CPE_30) || defined(CO_30)
        pBme->BmeState = ACTIVE;
        ApiRv = COMPLETE;
#else
            if (pBme->BmeDnldVerifyState == DW_T_BIT_SET)
            {
                /* api to call selftest ? Invoke BME selftest ?*/

                if (pollForDwTBitToBeCleared (pBme) == DMA_DONE)
                {
                    pBme->BmeDnldVerifyState = DW_T_BIT_CLEARED;
                    /* BME is up & running. Change BmeState to ACTIVE */
                    pBme->BmeState = ACTIVE;
                    ApiRv = COMPLETE;

                    /*EventLog ("b%dp0 ...BmeStart COMPLETE: Bme state %d"
                            ,pBme->BmeNum,pBme->BmeState);*/
                } else
                {
                    /*EventLog ("b%dp0 ...BmeStart FAIL: Bme state %d BME software download verification done!"
                            ,pBme->BmeNum,pBme->BmeState);*/

                    ApiRv = FAIL;
                    return(ApiRv);
                }
            } else
            {
                /*EventLog ("b%dp0 ...BmeStart FAIL: Bme state %d BmeDnldVerifyState %d is wrong!"
                            ,pBme->BmeNum,pBme->BmeState,pBme->BmeDnldVerifyState);*/

         ApiRv = FAIL;
                return(ApiRv);
      }
#endif

      break;

    case ACTIVE:
            /*EventLog ("b%dp0 ...BmeStart COMPLETE: BME is already up & running. BME Software download not required now!"
                        ,pBme->BmeNum,pBme->BmeState);*/

      ApiRv = COMPLETE;
      break;

    default:
            //EventLog ("b%dp0 ...BmeStart FAIL: BME is in unknown state! State %d",pBme->BmeNum,pBme->BmeState);
      ApiRv = FAIL;
      break;
   }

    return(ApiRv);

}                                                          /* BmeStart */

/*************************************************************************
    Function: BmeReset

    Description: This command holds Xtensa, sets the hardware reset line
                 on the BME and re-downloads BME software.

Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    BMEbaseAddr					Base address of this BME
    BMEResetLineAddr			Address of Reset Line of BME

    Return: See eApiRv
************************************************************************/
eApiRv BmeReset (tBmeStruct *pBme)
{

    eApiRv ApiRv=FAIL;

    //EventLog ("b%dp0 BmeReset: Bme state 0x%x",pBme->BmeNum,pBme->BmeState);

    pBme->BmeState=INACTIVE;

    ApiRv=BmeStart (pBme);

    //EventLog ("b%dp0 ...BmeReset COMPLETE: Bme state 0x%x",pBme->BmeNum,pBme->BmeState);

    return(ApiRv);

}                                                          /* BmeReset */

/*************************************************************************
    Function: SystemProvision

    Description: This command is used to provision system parameters.

    Return: See eApiRv
************************************************************************/
extern eApiRv SystemProvision (tBmeStruct *pBme)
{
		BYTE *pDataSec;
    int size, TotalSize=0;
		WORD iposVer = IPOS_VERSION;

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);
//    PrintSystemProvision (pBme);

    MEMCPY(pDataSec,&(pBme->BmeParms.SysProvParms.VendorIdT1E1),sizeof(WORD), 1);
    TotalSize+=sizeof(WORD);
    pDataSec+=sizeof(WORD);

    size=sizeof(pBme->BmeParms.SysProvParms.VendorIdItu);
    memcpy(pDataSec,&(pBme->BmeParms.SysProvParms.VendorIdItu),size);
    TotalSize+=size;
    pDataSec+=size;

    MEMCPY(pDataSec,&(pBme->BmeParms.SysProvParms.RevisionNum),sizeof(UINT32), 1);
    TotalSize+=sizeof(UINT32);
    pDataSec+=sizeof(UINT32);

    size=sizeof(pBme->BmeParms.SysProvParms.SerialNumber);
    memcpy(pDataSec,&(pBme->BmeParms.SysProvParms.SerialNumber),size);
    TotalSize+=size;
    pDataSec+=size;

    *pDataSec++ = pBme->BmeParms.SysProvParms.AtmOption;
    TotalSize++;

    *pDataSec++ = pBme->BmeParms.SysProvParms.AtmCellSize;
    TotalSize++;

    *pDataSec++ = pBme->BmeParms.SysProvParms.OptionMask;
    TotalSize++;

    *pDataSec++ = pBme->BmeParms.SysProvParms.BandPlan;
    TotalSize++;

    *pDataSec++ = pBme->BmeParms.SysProvParms.NumPort;
    TotalSize++;

    *pDataSec++ = pBme->BmeParms.SysProvParms.psdMaskLevelIndx;
    TotalSize++;

    MEMCPY(pDataSec,&(pBme->BmeParms.SysProvParms.k0), sizeof(UINT32), 3);
    TotalSize+=sizeof(UINT32)*3;
    pDataSec+=sizeof(UINT32)*3;

    MEMCPY(pDataSec,&(pBme->BmeParms.SysProvParms.k1), sizeof(UINT32), 3);
    TotalSize+=sizeof(UINT32)*3;
    pDataSec+=sizeof(UINT32)*3;

		MEMCPY(pDataSec, &(pBme->BmeParms.SysProvParms.custId), sizeof(UINT16), 1);
    TotalSize+=sizeof(UINT16);
    pDataSec+=sizeof(UINT16);

    MEMCPY(pDataSec, &(pBme->BmeParms.SysProvParms.keys), sizeof(UINT16), 3);
    TotalSize+=sizeof(UINT16) * 3;
    pDataSec+=sizeof(UINT16) * 3;

		MEMCPY(pDataSec, &iposVer, sizeof(UINT16), 1);
		TotalSize+=sizeof(UINT16);
		pDataSec+=sizeof(UINT16);

		*pDataSec++ = pBme->BmeParms.SysProvParms.ife2PwrMode;
		TotalSize++;
   
		*pDataSec++ = pBme->BmeParms.SysProvParms.OamOptionMask;
		TotalSize++;

    MEMCPY(pDataSec,&(pBme->BmeParms.SysProvParms.k0_hi), sizeof(UINT32), 3);
    TotalSize+=sizeof(UINT32) * 3;
    pDataSec+=sizeof(UINT32) * 3;

    MEMCPY(pDataSec,&(pBme->BmeParms.SysProvParms.k1_hi), sizeof(UINT32), 3);
    TotalSize+=sizeof(UINT32) * 3;
    pDataSec+=sizeof(UINT32) * 3;

    memcpy(pDataSec, &(pBme->BmeParms.SysProvParms.MaxPsd), DAPI_MAX_PSD_LEN);
    TotalSize+=DAPI_MAX_PSD_LEN;
    pDataSec+=DAPI_MAX_PSD_LEN;

    pBme->TxBmeMsg[_BmeDataLENGTH_] = TotalSize;
		pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];


    return(SendBmeMessage (pBme,0,SYSTEM_PROVISION));
}
void  PrintSystemProvision (tBmeStruct *pBme)
{
    int i;
    printf("SystemProvision(): VendorIdT1E1 %x \n",pBme->BmeParms.SysProvParms.VendorIdT1E1);
    printf("SystemProvision(): VendorIdItu :");
    for (i=0;i<8;i++)
    printf(": %x ",pBme->BmeParms.SysProvParms.VendorIdItu[i]);
    printf("\n");
    printf("SystemProvision(): RevisionNum %x \n",pBme->BmeParms.SysProvParms.RevisionNum);
    printf("SystemProvision(): SerialNumber :");
    for (i=0;i<32;i++)
    printf(": %x ",pBme->BmeParms.SysProvParms.SerialNumber[i]);
    printf("\n");
    printf("SystemProvision(): AtmOption %x \n",pBme->BmeParms.SysProvParms.AtmOption);
     printf("SystemProvision(): AtmCellSize %x \n",pBme->BmeParms.SysProvParms.AtmCellSize);
      printf("SystemProvision(): OptionMask %x \n",pBme->BmeParms.SysProvParms.OptionMask);
      printf("SystemProvision(): BandPlan %x \n",pBme->BmeParms.SysProvParms.BandPlan);
    printf("SystemProvision(): NumPort %x \n",pBme->BmeParms.SysProvParms.NumPort);
    printf("SystemProvision(): psdMaskLevelIndx %x \n",pBme->BmeParms.SysProvParms.psdMaskLevelIndx);
    printf("SystemProvision(): k0 : ");
    for (i=0;i<3;i++)
    printf(": %x ",pBme->BmeParms.SysProvParms.k0[i]);
    printf("\n");
    printf("SystemProvision(): k1 : ");
    for (i=0;i<3;i++)
    printf(":  %x ",pBme->BmeParms.SysProvParms.k1[i]);
    printf("\n");
    printf("SystemProvision(): custId %x \n",pBme->BmeParms.SysProvParms.custId);
    printf("SystemProvision(): keys : ");
    for (i=0;i<3;i++)
    printf(":  %x ",pBme->BmeParms.SysProvParms.keys[i]);
    printf("\n");
    printf("SystemProvision(): ife2PwrMode %x \n",pBme->BmeParms.SysProvParms.ife2PwrMode);
    printf("SystemProvision(): OamOptionMask %x \n",pBme->BmeParms.SysProvParms. OamOptionMask);
    printf("SystemProvision(): k0_hi : ");
    for (i=0;i<3;i++)
    printf(": %x",pBme->BmeParms.SysProvParms.k0_hi[i]);
    printf("\n");
    printf("SystemProvision(): k1_hi : ");
    for (i=0;i<3;i++)
    printf(": %x ",pBme->BmeParms.SysProvParms.k1_hi[i]);
    printf("\n");
}

/*************************************************************************
    Function: PortInstantiate

    Description: This command is used to allocate resources and initiate
                the state machine for the port. The configuration parameters
                will be set to default values until the user changes them.
                The port will end up in an idle state.

    Return: See eApiRv
************************************************************************/

extern eApiRv PortInstantiate (tBmeStruct *pBme, int PortNum)
{

    eApiRv  ApiRv=FAIL;
   BYTE *pDataSec;


    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);
    *pDataSec++=0;
    pBme->TxBmeMsg[_BmeDataLENGTH_]=1;

    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

   /* Send Port provision message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,PORT_START);


    return(ApiRv);
}                                                          /* PortInstantiate */



/*************************************************************************
    Function: PortProvision

    Description: This command is used to provision a xDSL port. This command
                 does not activate the port.

Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------

The following parameters in PortProvParms has to be initialized.

    InterleavedChannel			The range of the value will be 0-63.
    FastChannel 				The range of the value will be 0-63.
    LineType					Automatic / ADSL G.DMT / ADSL G.LITE ... etc.,
    DslMode						No channel / Fast / Interleaved / Slow channels
    RateAdaptationMode			Fixed / Startup
    InterleavedPercentage  		Percentage of data through interleave path
    UpstreamMaxRateFast			Data rate in kbps
    UpstreamMinRateFast			Data rate in kbps
    UpstreamMaxRateSlow  		Data rate in kbps
    UpstreamMinRateSlow   		Data rate in kbps
    UpstreamMaxInterDelay		Data rate in kbps
    DownstreamMaxRateFast   	Data rate in kbps
    DownstreamMinRateFast	   	Data rate in kbps
    DownstreamMaxRateSlow		Data rate in kbps
    DownstreamMinRateSlow		Data rate in kbps
    DownstreamMaxInterDelay
    NumParityFast				Number of parity bytes
    NumParitySlow				Number of parity bytes
    NumCodeWord					Number of symbol per RS code word
    InterleaveDepth
    MaxNoiseMargin				Range 0-31.0dB, steps of 0.1dB
    TargetNoiseMargin			Range 0-31.0dB, steps of 0.1dB
    MinNoiseMargin				Range 0-31.0dB, steps of 0.1dB

    Return: eApiRv
************************************************************************/

extern eApiRv PortProvision (tBmeStruct *pBme, int PortNum)
{
    eApiRv ApiRv=FAIL;
   BYTE *pDataSec, *pDataHead;
    int profilenum=1;

   /*****TEMP TEST CODE *****/
    pBme->Port[PortNum].PortParms.PortStatusBriefParms.Actual=0x1;
   /*****TEMP TEST CODE end*****/

    profilenum=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProfileNum;


   /* Send Port provision message to BME */

   /* Set data section of BME message */
    pDataHead=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.InterleavedChannel;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.FastChannel;
		pDataSec++;

    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.LineType;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.DslMode;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.RateAdaptationMode;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.InterleavedPercentage;
		pDataSec++;

    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.UpstreamMaxRateFast),sizeof(UINT32),1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.UpstreamMinRateFast),sizeof(UINT32),1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.UpstreamMaxRateSlow),sizeof(UINT32),1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.UpstreamMinRateSlow),sizeof(UINT32),1);
    pDataSec+=sizeof(UINT32);
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.UpstreamMaxInterDelay;
    pDataSec++;

    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.DownstreamMaxRateFast),sizeof(UINT32),1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.DownstreamMinRateFast),sizeof(UINT32),1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.DownstreamMaxRateSlow),sizeof(UINT32),1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.DownstreamMinRateSlow),sizeof(UINT32),1);
    pDataSec+=sizeof(UINT32);
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.DownstreamMaxInterDelay;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.NumParityFast;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.NumParitySlow;
		pDataSec++;

    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.UsTargetNoiseMargin),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.DsTargetNoiseMargin),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.MinNoiseMargin),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.BandPlan;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.NumRFIBand;
		pDataSec++;
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.Band1Start),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.Band1Stop),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.Band2Start),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.Band2Stop),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.Band3Start),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.Band3Stop),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.Band4Start),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.Band4Stop),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.Band5Start),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.Band5Stop),sizeof(UINT16),1);
    pDataSec+=sizeof(UINT16);

   /* Attach Activation mode from PortStartReset always IDLE_AFTER_PROV */

    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortStartResetParms.PortStartParm;
		pDataSec++;

//jk-rfi
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.RFIBand1;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.RFIBand2;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.RFIBand3;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.RFIBand4;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.RFIBand5;
		pDataSec++;

    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->BandMod.bandModifier;
		pDataSec++;

    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->OptionParms.PortOption;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->OptionParms.Reserved1;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->OptionParms.Reserved2;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->OptionParms.Reserved3;
		pDataSec++;

    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->IFE_BRD_CFG.pwrMode;
    pDataSec++;

    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->IFE_BRD_CFG.rxPathFilterMode;
    pDataSec++;

    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->IFE_BRD_CFG.txPathFilterMode;
    pDataSec++;

    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.UsMinProtection;
		pDataSec++;
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.DsMinProtection;
		pDataSec++;
#ifdef CPE_40
    *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProvParms.framingmode;
   pDataSec++;
#endif

    pBme->TxBmeMsg[_BmeDataLENGTH_] = (BYTE)(pDataSec - pDataHead);
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];


    ApiRv=SendBmeMessage (pBme,PortNum,PORT_PROVISION);

    return(ApiRv);

}                                                          /* PortProvision */


/*************************************************************************
    Function: PortStart

    Description: This command is used to initiate activation/initialization
                on a port. Based on the start mode parameter, the activation
                sequence will either be initiated from the port or will wait
                for the far-end initiate activation.

Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    PortStartParm				StartMode - Port initiate / Far end initiate


    Return: eApiRv
************************************************************************/
extern eApiRv PortStart (tBmeStruct *pBme, int PortNum)
{
    eApiRv  ApiRv=FAIL;
   BYTE *pDataSec;


    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);
    *pDataSec++=1;
    pBme->TxBmeMsg[_BmeDataLENGTH_]=1;

    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

   /* Send Port provision message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,PORT_START);

    return(ApiRv);
}                                                          /* PortStart */


/*************************************************************************
    Function: UtopiaLb

    Description: This command is used to initiate activation/initialization
                on a port. Based on the start mode parameter, the activation
                sequence will either be initiated from the port or will wait
                for the far-end initiate activation.

Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    PortStartParm				StartMode - Port initiate / Far end initiate


    Return: eApiRv
************************************************************************/
extern eApiRv testLb (tBmeStruct *pBme, int PortNum)
{
    eApiRv  ApiRv=FAIL;
   BYTE *pDataSec;


    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);
    *pDataSec++=pBme->Port[PortNum].PortParms.SetLpbkParms.LoopbackMode ;
    pBme->TxBmeMsg[_BmeDataLENGTH_]=1;

    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

   /* Send Port provision message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,SET_LOOPBACK);

    return(ApiRv);
}                                                          /* testLb */

/*************************************************************************
    Function: PortStop

    Description: To deactivate a port, but to retain provisioning
             record and wait for far-end activation.

            inistop function needs to be called in ipos API before PortStop

    Return: eApiRv
************************************************************************/
extern eApiRv PortStop (tBmeStruct *pBme, int PortNum)
{

    eApiRv ApiRv=FAIL;
   BYTE *pDataSec;

    /*EventLog ("b%dp%d PortStop: Port Actual State %d, PortProfileNum %d"
            ,pBme->BmeNum,PortNum,pBme->Port[PortNum].PortParms.PortStatusBriefParms.Actual,
             pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProfileNum);

    EventLog ("b%dp0 ...INI port  stopped ",pBme->BmeNum);
*/
/*** APP CODE ***/
   // Need to call INI stop before PortStop
    //inistop(pBme->BmeNum,PortNum);
/*** End: APP CODE ***/

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);
    pBme->TxBmeMsg[MAX_BME_HEADER]=0;

/*	pDataSec++;

        size=sizeof(pBme->Port[PortNum].PortParms.pPtrPortProfile->PortStartResetParms);
        pBme->Port[PortNum].PortParms.pPtrPortProfile->PortStartResetParms.PortStartParm=0x0;
        *pDataSec=pBme->Port[PortNum].PortParms.pPtrPortProfile->PortStartResetParms.PortStartParm;

*/
    pBme->TxBmeMsg[_BmeDataLENGTH_]=1;

    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

   /* Send Port Reset with far-end initiate to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,PORT_STOP);


    return(ApiRv);

}                                                          /* PortStop */

/*************************************************************************
    Function: PortDestroy

    Description: To deactivate a port and de-provision the port record.


    Return: eApiRv
************************************************************************/
extern eApiRv PortDestroy (tBmeStruct *pBme, int PortNum)
{

    eApiRv ApiRv=FAIL;
   BYTE *pDataSec;

    /*EventLog ("b%dp%d PortDestroy: Port Actual State %d, PortProfileNum %d"
            ,pBme->BmeNum,PortNum,pBme->Port[PortNum].PortParms.PortStatusBriefParms.Actual,
             pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProfileNum);
*/
    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    *pDataSec = pBme->Port[PortNum].PortParms.pPtrPortProfile->PortStopParms.PortStopParm=1;

    pBme->TxBmeMsg[_BmeDataLENGTH_]=sizeof(BYTE);
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

   /* Send Port stop message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,PORT_STOP);

    return(ApiRv);

}                                                          /* PortDestroy */


/*************************************************************************
    Function: PortReset

    Description: To reset the port and re-activate according to the startup
                 mode.

Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    PortStartParm				StartMode - Port initiate / Far end initiate

    Return: eApiRv
************************************************************************/
extern eApiRv PortReset(tBmeStruct *pBme, int PortNum)
{

    eApiRv ApiRv=FAIL;
   BYTE *pDataSec;

/*	EventLog ("b%dp%d PortReset: Port Actual State %d, PortProfileNum %d, PortStartParm %d"
                ,pBme->BmeNum,PortNum,
                pBme->Port[PortNum].PortParms.PortStatusBriefParms.Actual,
                pBme->Port[PortNum].PortParms.pPtrPortProfile->PortProfileNum,
                pBme->Port[PortNum].PortParms.pPtrPortProfile->PortStartResetParms.PortStartParm);
*/
    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    *pDataSec = pBme->Port[PortNum].PortParms.pPtrPortProfile->PortStopParms.PortStopParm;

    pBme->TxBmeMsg[_BmeDataLENGTH_]=sizeof(BYTE);
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

   /* Send Port reset message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,PORT_RESET);


    return(ApiRv);

}                                                          /* PortReset */


/*************************************************************************
    Function: EocControlSend

    Description: This command is used to send a control message to the far
                    end thru the EOC Channel.

Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    EocOpcode					EOC opcode

    Return: eApiRv
************************************************************************/

extern eApiRv   EocControlSend(tBmeStruct *pBme, int PortNum)
{

    eApiRv ApiRv=FAIL;
   BYTE *pDataSec;

    //EventLog ("b%dp%d EocControlSend",pBme->BmeNum,PortNum);


    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    *pDataSec = pBme->Port[PortNum].PortParms.EocControlParms.EocMode;

    pBme->TxBmeMsg[_BmeDataLENGTH_]=sizeof(BYTE);

    pBme->dataLen=MAX_BME_HEADER+sizeof(BYTE);

   /* Send Eoc Control Message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,EOC_CONTROL_SEND);

    return(ApiRv);

}                                                          /* EocControlSend */


/*************************************************************************
    Function: EocDataReply

    Description: This command is used to send a reply related to a command
                    sent by the far-end.

    Return: eApiRv
************************************************************************/

/*
Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    EocOpcode					EOC opcode
    EocLength					Length of data in bytes
    EocData						EOC data. Not all 128 bytes need to be used
*/

extern eApiRv   EocDataReply(tBmeStruct *pBme, int PortNum)
{

    eApiRv ApiRv=FAIL;
   int size;
   BYTE *pDataSec;

/*	EventLog ("b%dp%d EocDataReply: EocOpcode %d",pBme->BmeNum,PortNum,
        pBme->Port[PortNum].PortParms.EocDataReply.EocOpcode);
*/

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    size=sizeof(pBme->Port[PortNum].PortParms.EocDataReply);

    memcpy(pDataSec,&(pBme->Port[PortNum].PortParms.EocDataReply),size);

    pBme->TxBmeMsg[_BmeDataLENGTH_]=size;

    pBme->dataLen=MAX_BME_HEADER+size;

   /* Send Eoc Data Reply Control Message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,EOC_DATA_REPLY);

    return(ApiRv);

}                                                          /* EocDataReply */

/*************************************************************************
    Function: EocSendDataStream

    Description: This command is used to send a data stream to the far
                    end thru the EOC Channel.

    Return: eApiRv
************************************************************************/
/*
Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    DataStream					This is the data to be sent to the far-end.
                                The maximum length of a message is 250 bytes.
*/

extern eApiRv   EocSendDataStream(tBmeStruct *pBme, int PortNum)    
{

    eApiRv ApiRv=FAIL;
   int size;
   BYTE *pDataSec;

    //EventLog ("b%dp%d EocSendDataStream: EocOpcode %d",pBme->BmeNum,PortNum);

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    size=pBme->Port[PortNum].PortParms.EocSendDataStrParms.EocLength;

    memcpy(pDataSec,&(pBme->Port[PortNum].PortParms.EocSendDataStrParms.DataStream),size);

    pBme->TxBmeMsg[_BmeDataLENGTH_]=size;

    pBme->dataLen=MAX_BME_HEADER+size;

   /* Send Eoc Send Data Stream Control Message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,EOC_SEND_DATA_STREAM);

    return(ApiRv);

}                                                          /* EocSendDataStream */

/*************************************************************************
    Function: EocGetData

    Description: This command is used to retrieve the value of the data
                    register from the far-end thru the EOC channel.

    Return: eApiRv
************************************************************************/

/*
Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    EocOpcode					EOC opcode
*/

extern eApiRv   EocGetData(tBmeStruct *pBme, int PortNum)
{

    eApiRv ApiRv=FAIL;
   int size;
   BYTE *pDataSec;

    printf ("b%dp%d EocGetData: EocOpcode %d",pBme->BmeNum,PortNum
                ,pBme->Port[PortNum].PortParms.EocGetDataParms.EocOpcode);

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    size=sizeof(pBme->Port[PortNum].PortParms.EocGetDataParms);

    memcpy(pDataSec,&(pBme->Port[PortNum].PortParms.EocGetDataParms),size);

    pBme->TxBmeMsg[_BmeDataLENGTH_]=size;

    pBme->dataLen=MAX_BME_HEADER+size;

   /* Send Eoc Get Data Control Message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,EOC_GET_DATA);

    return(ApiRv);

}                                                          /* EocGetData */

/*************************************************************************
    Function: EocSetData

    Description: This command is used to set the value of the data
                    register on the far-end thru the EOC channel.

    Return: eApiRv
************************************************************************/

extern eApiRv   EocSetData(tBmeStruct *pBme, int PortNum)
{

    eApiRv ApiRv=FAIL;
   int size;
   BYTE *pDataSec;

/*	EventLog ("b%dp%d EocSetData: EocOpcode %d",pBme->BmeNum,PortNum,
        pBme->Port[PortNum].PortParms.EocSetDataParms.EocOpcode);
*/

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    size=sizeof(pBme->Port[PortNum].PortParms.EocSetDataParms);

    memcpy(pDataSec,&(pBme->Port[PortNum].PortParms.EocSetDataParms),size);

    pBme->TxBmeMsg[_BmeDataLENGTH_]=size;

    pBme->dataLen=MAX_BME_HEADER+size;

   /* Send Eoc Data Reply Control Message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,EOC_SET_DATA);

    return(ApiRv);

}                                                          /* EocSetData */

/*************************************************************************
    Function: BitSwapReq

    Description: This command is used to send a dummy bit swap request

    Return: eApiRv
************************************************************************/

extern eApiRv   BitSwapReq (tBmeStruct *pBme, int PortNum)
{

    eApiRv ApiRv=FAIL;
   int size;
   BYTE *pDataSec;

/*	EventLog ("b%dp%d BitSwapReq: BitSwapOpcode %d",pBme->BmeNum,PortNum,
        pBme->Port[PortNum].PortParms.BitSwapReqParms.BitSwapOpcode);
*/

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    size=sizeof(pBme->Port[PortNum].PortParms.BitSwapReqParms);

    memcpy(pDataSec,&(pBme->Port[PortNum].PortParms.BitSwapReqParms),size);

    pBme->TxBmeMsg[_BmeDataLENGTH_]=size;

    pBme->dataLen=MAX_BME_HEADER+size;

   /* Send Bit swap Request Message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,BIT_SWAP_REQ);

    return(ApiRv);

}         /* BitSwapReq */

/*************************************************************************
    Function: EocProtocolSet
    Description: This command is used to set the control parameters for the Internal
		             Eoc Protocol.
    Return: eApiRv
************************************************************************/

extern eApiRv   EocProtocolSet(tBmeStruct *pBme, int PortNum)
{
    eApiRv ApiRv=FAIL;
    int size;
    BYTE *pDataSec;

/*	  printf ("b%dp%d EocProtocolSet: EocOpcode %d",pBme->BmeNum,PortNum,
        pBme->Port[PortNum].PortParms.EocSetDataParms.EocOpcode); */

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);
    size=sizeof(pBme->Port[PortNum].PortParms.EocSetDataParms);
    memcpy(pDataSec,&(pBme->Port[PortNum].PortParms.EocSetDataParms),size);
    pBme->TxBmeMsg[_BmeDataLENGTH_]=size;
    pBme->dataLen=MAX_BME_HEADER+size;

    /* Send Eoc Protocol control message to the BME. */
    ApiRv=SendBmeMessage (pBme,PortNum,EOC_PROTOCOL_SET);

    return(ApiRv);

} /* EocProtocolSet */

/*************************************************************************
    Function: EocProtocolGet
    Description: This command is used to retrieve the control parameters 
		             values from the BME.
    Return: eApiRv
************************************************************************/
extern eApiRv   EocProtocolGet(tBmeStruct *pBme, int PortNum)
{
    eApiRv ApiRv=FAIL;
    int size;
    BYTE *pDataSec;

/*    printf ("b%dp%d EocProtocolGet: EocOpcode %d",pBme->BmeNum,PortNum
                ,pBme->Port[PortNum].PortParms.EocGetDataParms.EocOpcode); */
    
    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);
    size=sizeof(pBme->Port[PortNum].PortParms.EocGetDataParms);
    memcpy(pDataSec,&(pBme->Port[PortNum].PortParms.EocGetDataParms),size);
    pBme->TxBmeMsg[_BmeDataLENGTH_]=size;
    pBme->dataLen=MAX_BME_HEADER+size;

    /* Send Eoc Get Data Control Message to BME */
    ApiRv=SendBmeMessage (pBme,PortNum,EOC_PROTOCOL_GET);

    return(ApiRv);
} /* EocProtocolGet */

/* Status Request commands */

/*************************************************************************
    Function: SystemStatus

    Description: This command is used to retrieve the status of the BME
                system. It returns the brief status report for each port
                in the system.

    Return: eApiRv
************************************************************************/
extern eApiRv   SystemStatus (tBmeStruct *pBme)
{

    //EventLog ("b%dp0 SystemStatus",pBme->BmeNum);

    return(SendBmeMessage (pBme,0x00/*System*/,SYSTEM_STATUS));


}                                                          /* SystemStatus */

/*************************************************************************
    Function: HostHotResetStatus 
    
    Description: This command is used to request the status of BME and all the ports
		             under that BME.

    Return: eApiRv
************************************************************************/
extern eApiRv HostHotReset(tBmeStruct *pBme, int portNum)
{

    printf ("b%dp%d HostHotreset",pBme->BmeNum,portNum);  

    return(SendBmeMessage (pBme,portNum,HOST_HOT_RESET));

} /* PortStatusBrief */
/*************************************************************************
    Function: PortStatusBrief

    Description: This command is used to request a brief status report from
                the specified port. This report indicates whether the port
                is enabled, activated and whether the link is up or not.

    Return: eApiRv
************************************************************************/

/*
Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    Enable_1_8					Port 1 - 8
    Enable_9_16					Port 9 - 16
    Enable_17_24				Port 17 - 24
    Enable_25_32				Port 25 - 32
    Activate_1_8				Port 1 - 8
    Activate_9_16				Port 9 - 16
    Activate_17_24				Port 17 - 24
    Activate_25_32				Port 25 - 32
    LinkUp_1_8					Port 1 - 8
    LinkUp_9_16					Port 9 - 16
    LinkUp_17_24				Port 17 - 24
    LinkUp_25_32				Port 25 - 32
*/

extern eApiRv   PortStatusBrief(tBmeStruct *pBme, int PortNum)
{

    //EventLog ("b%dp%d PortStatusBrief",pBme->BmeNum,PortNum);

    return(SendBmeMessage (pBme,PortNum,PORT_STATUS_BRIEF));

}                                                          /* PortStatusBrief */


/*************************************************************************
    Function: GetCounters

    Description: This command will retrieve the counts for various
                performance parameters.

    Return: eApiRv
************************************************************************/

/*
Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    NeFEC_S						Near-end forward error correction slow count
    NeFEC_F						Near-end forward error correction fast count
    NeCRC_S						Near-end cyclic redundancy check slow count
    NeCRC_F						Near-end cyclic redundancy check fast count
    FeFEC_S						Far-end forward error correction slow count
    FeFEC_F						Far-end forward error correction fast count
    FeCRC_S						Far-end block error slow count
    FeCRC_F						Far-end block error fast count
    NeLOS						Near end loss of signal count
    NeSEF						Near end severely errored frame count
    FeFLOS						Far-end loss of signal count
    FeFRDI						Far-end remote defect indication count
    NeNCD_S						Near-end no cell delineation slow count
    NeNCD_F						Near-end no cell delineation fast count
    NeOCD_S						Near-end out of cell delineation slow count
    NeOCD_F						Near-end out of cell delineation fast count
    NeHEC_S						Near-end header error control slow count
    NeHEC_F						Near-end header error control fast count
    FeNCD_S						Far-end no cell delineation slow count
    FeNCD_F						Far-end no cell delineation fast count
    FeOCD_S						Far-end out of cell delineation slow count
    FeOCD_F						Far-end out of cell delineation fast count
    FeHEC_S						Far-end header error control slow count
    FeHEC_F						Far-end header error control fast count
    NeLCD_S						Near-end loss of cell delineation slow count
    NeLCD_F						Far-end loss of cell delineation fast count
    FeLCD_S						Far-end loss of cell delineation slow count
    FeLCD_F						Far-end loss of cell delineation fast count
    FeLPR						Far-end loss of power count
*/

extern eApiRv   GetCounters(tBmeStruct *pBme, int PortNum)
{

    //EventLog ("b%dp%d GetCounters",pBme->BmeNum,PortNum);

    return(SendBmeMessage (pBme,PortNum,GET_COUNTERS));


}                                                          /* GetCounters */

/*************************************************************************
    Function: GetPMCounters
    
    Description: This command will retrieve the counts for various 
                performance parameters. 

    Return: eApiRv
************************************************************************/


extern eApiRv  GetPMCounters(tBmeStruct *pBme, int PortNum)
{

    return(SendBmeMessage (pBme,PortNum,GET_PM_COUNTERS));


} /* GetPMCounters */


/*************************************************************************
    Function: PmConfig
    
    Description: This command is used to configure the Performance
                 Management parameters.

    Return: eApiRv
************************************************************************/

extern eApiRv  PmConfig (tBmeStruct *pBme, int PortNum)
{
  BYTE *pDataSec = &(pBme->TxBmeMsg[MAX_BME_HEADER]);
  int size = sizeof (pBme->Port[PortNum].PortParms.PmConfigParms);

  MEMCPY(pDataSec, &(pBme->Port[PortNum].PortParms.PmConfigParms), sizeof(UINT16), (size / sizeof(UINT16)));

  pBme->TxBmeMsg[_BmeDataLENGTH_] = size;

  pBme->dataLen = MAX_BME_HEADER + pBme->TxBmeMsg[_BmeDataLENGTH_];

  return(SendBmeMessage (pBme, PortNum, PM_CONFIG_PARAMS));

} /* PmConfig */



/*************************************************************************
    Function: PmSendTimer
    
    Description: This command is used to send a PM timer message to the BME.
                 The PM timer indicates the end of a period of PM Parameter
                 accumulation.

    Return: eApiRv
************************************************************************/

extern eApiRv  PmSendTimer (tBmeStruct *pBme)
{

    return(SendBmeMessage (pBme, 0, PM_SEND_TIMER));


} /* PmSendTimer */



/*************************************************************************
    Function: PmTriggerFailures
    
    Description: This command is used to Trigger PM failures on the BME.
                 This is used for testing the PM failure alert and status
                 reporting fuctionalities.

    Return: eApiRv
************************************************************************/

extern eApiRv  PmTriggerFailures (tBmeStruct *pBme, int PortNum)
{

    BYTE *pDataSec = &(pBme->TxBmeMsg[MAX_BME_HEADER]);

    int size = sizeof(pBme->Port[PortNum].PortParms.PmTriggerParms);

    MEMCPY(pDataSec, &(pBme->Port[PortNum].PortParms.PmTriggerParms), sizeof(UINT16), (size / sizeof(UINT16)));

    pBme->TxBmeMsg[_BmeDataLENGTH_] = size;

    pBme->dataLen = MAX_BME_HEADER + pBme->TxBmeMsg[_BmeDataLENGTH_];

    return(SendBmeMessage (pBme, PortNum, PM_TRIGGER_FAILURES));


} /* PmTriggerFailures */



/*************************************************************************
    Function: PeriodicReportsEnable

    Description: This command is used to enable/disable the periodic reports
                sent by the BME. The reports will be autonomously sent to
                the user. The reports will be placed in the same BME
                structure passed into this command.

    Return: eApiRv
************************************************************************/

/*
Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    ReportsEnable				No report, stops status request / alarm counters / system status
    AlarmCountFreq				Frequency of alarm counter report in ms
    SystemStatusFreq			Frequency of system status report in ms
*/

extern eApiRv   PeriodicReportsEnable   (tBmeStruct *pBme, int PortNum)
{

    eApiRv ApiRv=FAIL;
    int TotalSize=0;
   BYTE *pDataSec = &(pBme->TxBmeMsg[MAX_BME_HEADER]);

    *pDataSec++ = pBme->Port[PortNum].PortParms.PerReportParms.ReportsEnable;
    TotalSize++;

    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.PerReportParms.AlarmCountFreq),sizeof(UINT16), 1);
    TotalSize+=sizeof(UINT16);
    pDataSec+=sizeof(UINT16);

    MEMCPY(pDataSec,&(pBme->Port[PortNum].PortParms.PerReportParms.SystemStatusFreq),sizeof(UINT16), 1);
    TotalSize+=sizeof(UINT16);
    pDataSec+=sizeof(UINT16);

    pBme->TxBmeMsg[_BmeDataLENGTH_]=TotalSize;

    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

   /* Send Eoc Send Data Stream Control Message to BME */
    ApiRv=SendBmeMessage (pBme,0,PERIODIC_REPORTS_ENABLE);

    return(ApiRv);

}                                                          /* PeriodicReportsEnable */


/*************************************************************************
    Function: UpdatedReportsEnabled

    Description: This command is used to request a report to be generated
                when there is a change in one of the values in the report.
                If enabled, the PORT_STATUS_BRIEF report will be sent to
                the user when there is a change in the state of the port.
                The report will be placed in the same BME structure passed
                into this command.

    Return: eApiRv
************************************************************************/
/*
Note:
----
Before calling this api, the following parameters have to be initialized in pBme.

    Var							Value / Description
    ---							-------------------
    ReportsEnable				No report, stops status request / Port Status Report (brief)

*/

extern eApiRv   UpdatedReportsEnabled(tBmeStruct *pBme, int PortNum)
{
    BYTE *pDataSec = &(pBme->TxBmeMsg[MAX_BME_HEADER]);
    BYTE *pDataBase = pDataSec;

    //EventLog ("b%dp%d UpdatedReportsEnabled",pBme->BmeNum,PortNum);

    *(pDataSec++) = pBme->Port[PortNum].PortParms.UpdatedReportParms.ReportsEnable;
    pBme->TxBmeMsg[_BmeDataLENGTH_]=(pDataSec - pDataBase);
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];


    return(SendBmeMessage (pBme,PortNum,UPDATED_REPORTS_ENABLE));

}                                                          /* UpdatedReportsEnabled */

/*************************************************************************
    Function: UpdateCounter

    Description: This command is used to update a counter in the BME.
                The index and new value are passed as a separate data struct
                (tUpdateCounterReq) idedependent of tBmeStruct

    Return: eApiRv
************************************************************************/
/*
Note:
----
No parameters have to be initialized in pBme, outside of those required to
communicate with the BME.

*/

int
UpdateCounter( tBmeStruct *pBme, int portNum, tUpdateCounterReq *pUpdateCounterReq )
{
    BYTE *pDataSec = &(pBme->TxBmeMsg[MAX_BME_HEADER]);
    BYTE *pDataBase = pDataSec;
    int   size=0;

    size=sizeof( pUpdateCounterReq->index );
#ifdef USE_BIG_ENDIAN_FORMAT
    memcpy(pDataSec, &(pUpdateCounterReq->index), size );
#else
    memcpyLittleEndian( pDataSec, &(pUpdateCounterReq->index), size );
#endif
    pDataSec += size;

    size=sizeof( pUpdateCounterReq->value );
#ifdef USE_BIG_ENDIAN_FORMAT
    memcpy(pDataSec, &(pUpdateCounterReq->value), size );
#else
    memcpyLittleEndian( pDataSec, &(pUpdateCounterReq->value), size );
#endif
    pDataSec += size;

    pBme->TxBmeMsg[_BmeDataLENGTH_]=(pDataSec - pDataBase);
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

    return( SendBmeMessage( pBme, portNum, UPDATE_COUNTER ) );
}

/*************************************************************************
    Function: PortStatusExtended

    Description: This command will retrieve the counts for various
                performance parameters.

    Return: eApiRv
************************************************************************/
extern eApiRv   PortStatusExtended(tBmeStruct *pBme, int PortNum)
{

    //EventLog ("b%dp%d PortStatusExtended",pBme->BmeNum,PortNum);
    pBme->TxBmeMsg[_BmeDataLENGTH_]=0;
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

    return(SendBmeMessage (pBme,PortNum,PORT_STATUS_EXTENDED));

}                                                          /* PortStatusExtended */


/*************************************************************************
    Function: DeviceVersions

    Description: This command is used to retrieve the software and hardware
                devices on the BME.

    Return: eApiRv
************************************************************************/
extern eApiRv   DeviceVersions (tBmeStruct *pBme, int PortNum)
{

    //EventLog ("b%dp%d DeviceVersions",pBme->BmeNum,PortNum);
    pBme->TxBmeMsg[_BmeDataLENGTH_]=0;
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

#ifdef BUP_DIAGS
	return(IN_PROGRESS);
#endif
    return(SendBmeMessage (pBme,PortNum,DEVICE_VERSIONS));

}                                                          /* DeviceVersions */



/*************************************************************************
    Function: GetSelftestResults

    Description: This command is used to retrieve the selftest results
                from the BME. The selftest is run during the startup of
                the BME software and will test the integrity of the BME
                memory.

    Return: eApiRv
************************************************************************/
extern eApiRv   GetSelftestResults(tBmeStruct *pBme, int PortNum)
{

    //EventLog ("b%dp%d GetSelftestResults",pBme->BmeNum,PortNum);

    pBme->TxBmeMsg[_BmeDataLENGTH_]=0;
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

    return(SendBmeMessage (pBme,PortNum,GET_COUNTERS));

}                                                          /* GetSelftestResults */


/*************************************************************************
    Function: Clear ALL BME Counters

    Description: This command clears all the performance counters at near end

    Return: eApiRv
************************************************************************/
extern eApiRv   ClrNeCntrs(tBmeStruct *pBme, int PortNum)
{

    //EventLog ("b%dp%d Clear BME Counters",pBme->BmeNum,PortNum);

    pBme->TxBmeMsg[_BmeDataLENGTH_]=0;
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

    return(SendBmeMessage (pBme,PortNum,CLEAR_ALL_COUNTERS));

}                                                          /* Clear ALL BME Counters */

/*************************************************************************
    Function: GetNeSnrAttn

    Description: This command retrieves near end SNR margin and attenuation.

    Return: eApiRv
************************************************************************/
extern eApiRv   GetNeSnrAttn(tBmeStruct *pBme, int PortNum)
{

    //EventLog ("b%dp%d GetNeSnrAttn",pBme->BmeNum,PortNum);

    pBme->TxBmeMsg[_BmeDataLENGTH_]=0;
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

    return(SendBmeMessage (pBme,PortNum,GET_NE_SNR_ATTN));

}                                                          /* GetNeSnrAttn */

extern eApiRv   GetOpCmdStatus(tBmeStruct *pBme, int PortNum)
{
   int size;
   BYTE *pDataSec;

   size = pBme->BmeParms.OptionalCmd.length;
    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);
    memcpy(pDataSec,  (BYTE *)pBme->BmeParms.OptionalCmd.buf, size);
    pBme->TxBmeMsg[_BmeDataLENGTH_]=size;
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

   // printf(" GetOpCmdStatus - MsgSize = %d, buf = 0x%x\n", size, pBme->BmeParms.OptionalCmd.buf);
    return(SendBmeMessage (pBme,PortNum,GET_OPCMD_STATUS));
}


/*************************************************************************
   Function: SendSignals

   Description: This command is used to send test signal from far end.
   Return: eApiRv
************************************************************************/
extern eApiRv   SendSignals(tBmeStruct *pBme, int PortNum)
{
    BYTE *pDataSec;

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

	 /* pack test signal */
	 *pDataSec = pBme->Port[PortNum].PortParms.SendSigParms.SigType;
	 pDataSec++;
	 *pDataSec = pBme->Port[PortNum].PortParms.SendSigParms.NumTones;
	 pDataSec++;

	 MEMCPY (pDataSec, &(pBme->Port[PortNum].PortParms.SendSigParms.Tone1), sizeof(UINT16), 1);
	 pDataSec += sizeof(UINT16);
	 MEMCPY (pDataSec, &(pBme->Port[PortNum].PortParms.SendSigParms.Tone2), sizeof(UINT16), 1);
	 pDataSec += sizeof(UINT16);
	 MEMCPY (pDataSec, &(pBme->Port[PortNum].PortParms.SendSigParms.Tone3), sizeof(UINT16), 1);
	 pDataSec += sizeof(UINT16);
	 MEMCPY (pDataSec, &(pBme->Port[PortNum].PortParms.SendSigParms.SweepInterval), sizeof(UINT16), 1);
	 pDataSec += sizeof(UINT16);

	pBme->TxBmeMsg[_BmeDataLENGTH_]=10;
	pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

   return(SendBmeMessage (pBme,PortNum,SEND_SIGNALS));

} /* SendSignals */



/*************************************************************************
   Function: DetectSignals

   Description: This command is used to send detect signal from far end.
   Return: eApiRv
************************************************************************/
extern eApiRv   DetectSignals(tBmeStruct *pBme, int PortNum)
{
    BYTE *pDataSec;

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

	 /* pack test signal */
	 *pDataSec = pBme->Port[PortNum].PortParms.SendSigParms.SigType;
	 pDataSec++;
	 *pDataSec = pBme->Port[PortNum].PortParms.SendSigParms.NumTones;
	 pDataSec++;

	 MEMCPY (pDataSec, (char *)&(pBme->Port[PortNum].PortParms.SendSigParms.Tone1), sizeof(UINT16), 1);
	 pDataSec += sizeof(UINT16);
	 MEMCPY (pDataSec, (char *)&(pBme->Port[PortNum].PortParms.SendSigParms.Tone2), sizeof(UINT16), 1);
	 pDataSec += sizeof(UINT16);
	 MEMCPY (pDataSec, (char *)&(pBme->Port[PortNum].PortParms.SendSigParms.Tone3), sizeof(UINT16), 1);
	 pDataSec += sizeof(UINT16);
	 MEMCPY (pDataSec, (char *)&(pBme->Port[PortNum].PortParms.SendSigParms.SweepInterval), sizeof(UINT16), 1);
	 pDataSec += sizeof(UINT16);

	pBme->TxBmeMsg[_BmeDataLENGTH_]=10;
	pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

    return(SendBmeMessage (pBme,PortNum,DETECT_SIGNALS));

} /* DetectSignals */


/*************************************************************************
    Function: SetLoopback

    Description: This command is used to set loopback in BME.
    Return: eApiRv
************************************************************************/
extern eApiRv   SetLoopback (tBmeStruct *pBme, int PortNum)
{
   BYTE *pDataSec;

    //EventLog ("b%dp%d Set loopback",pBme->BmeNum,PortNum);

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    *pDataSec = pBme->Port[PortNum].PortParms.SetLpbkParms.LoopbackMode;

    pBme->TxBmeMsg[_BmeDataLENGTH_]=sizeof(BYTE);

    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

    return(SendBmeMessage (pBme,PortNum,SET_LOOPBACK));

}                                                          /* DeviceVersions */

/*************************************************************************
    Function: Debug Mon

    Description: This command is used to send debug message to BME

    Return: eApiRv
************************************************************************/

eApiRv SendDebugMon (tBmeStruct *pBme, int PortNum)
{
   BYTE *pDataSec;

    pDataSec=&(pBme->TxBmeMsg[MAX_BME_HEADER]);

    MEMCPY(pDataSec,&(pBme->BmeParms.DebugParms.Parm1),sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(pDataSec,&(pBme->BmeParms.DebugParms.Parm2),sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(pDataSec,&(pBme->BmeParms.DebugParms.Parm3),sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(pDataSec,&(pBme->BmeParms.DebugParms.Parm4),sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(pDataSec,&(pBme->BmeParms.DebugParms.Parm5),sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);

   pBme->TxBmeMsg[_BmeDataLENGTH_] = 20;
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_];

    return(SendBmeMessage (pBme,PortNum,DEBUG_MON));
}


/*************************************************************************
    Function: SendBmeMessage

    Description: This function formats a message based on the HPI protocol
                 and calls lower level hwi api to transmit message to BME.

    Return: See eApiRv
************************************************************************/
eApiRv SendBmeMessage(tBmeStruct *pBme,int PortNum,eCommands Cmd)
{
    //EventLog("b%dp%d SendBmeMessage: Cmd: %i",pBme->BmeNum,PortNum,Cmd);

    /* BME Message header:
        Must set 1) your destination address in your BME structure
                 2) TxBmeMsg buffer
                 3) dataLen */


#ifdef BUP_DIAGS
	if ((Cmd != 0xff) && (Cmd != 0xfe))
		return(IN_PROGRESS);
#endif

#ifdef	NOTI
    pBme->TxBmeMsg[_BmeMsgSRC_] =0x1;
#endif

    pBme->TxBmeMsg[_BmeMsgDEST_]    =PortNum;

    pBme->TxBmeMsg[_BmeMsgOPCODE_]=(BYTE)Cmd;

    pBme->TxBmeMsg[_BmeMsgACK_] =0x01;
    pBme->TxBmeMsg[_BmeMsgCTAG_]    =0x01;

    pBme->destAddr=DPRAM_BASE_ADDR; /* Set flag to indicate DPRAM destination */
    pBme->dataPtr=&(pBme->TxBmeMsg[0]);
    pBme->dataLen=MAX_BME_HEADER+pBme->TxBmeMsg[_BmeDataLENGTH_]; /* Should be already set @ API level, but just in case it isn't, redefine here*/

   pBme->fifoStatus = FIFO_WRITE_IN_PROGRESS;
    pBme->FifoFlag=0;


// *** Move all below to dma1Controller

   /* Write message to BME DPRAM */
    if (bmeWrMessage (pBme,pBme->dpramBaseRxAddr,&(pBme->TxBmeMsg[0]),pBme->dataLen)==HWAPI_WRITE_SUCCESS)
        return(IN_PROGRESS);
   else
   {
       printf("Fusiv bmeWrMessage() : is failed\n");

        return(FAIL);
   }

}; /* SendBmeMessage */


extern HWAPI_RET_VAL ReceiveBmeMessage(tBmeStruct *pBme)
{

    HWAPI_RET_VAL   HwiApiRv=HWAPI_FAILED;
   
#ifndef CPE_30
   #ifndef CO_30
   UINT32 data;
   #endif
    if (pBme->fifoStatus == FIFO_READ)
    {
        pBme->srcAddr=DPRAM_BASE_ADDR;  /* Set flag to indicate DPRAM source */
        pBme->dataPtr=&(pBme->RxBmeMsg[0]);
        HwiApiRv=DoRdCmd (pBme);
#else
   pBme->srcAddr = DPRAM_BASE_ADDR;                     /* Set flag to indicate DPRAM source */
   pBme->dataPtr = &(pBme->RxBmeMsg[0]);
   pBme->dataLen = 0xff;
   HwiApiRv = bmeRdMessage(pBme,pBme->dataPtr);
#endif
// *** END: Move all above to dma1Controller

        if (HwiApiRv==HWAPI_READ_SUCCESS)
        {

            /*	EventLog ("b%dp%d ...ReceiveBmeMessage Read Success: Msg: 0x%x Ack: 0x%x srcAddr: 0x%x"
                        ,pBme->BmeNum,pBme->RxBmeMsg[_BmeMsgSRC_],pBme->RxBmeMsg[_BmeMsgOPCODE_]
                        ,pBme->RxBmeMsg[_BmeMsgACK_],pBme->srcAddr);*/



      /* Assemble Status API command parameters */
            if (pBme->RxBmeMsg[_BmeMsgACK_]==ACK_SUCCESS)
            {
                switch (pBme->RxBmeMsg[_BmeMsgOPCODE_])
                {
                    /* NOTE: Only ok to memcpy entire struct from msg if struct are all BYTE elements.
                       Anything else need to memcpy one elemtne at a time */

          case PORT_STATUS_BRIEF:
                        memcpy (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PortStatusBriefParms,
                                &pBme->RxBmeMsg[_BmeDataStart_],pBme->RxBmeMsg[_BmeDataLENGTH_]);
            break;

          case SYSTEM_STATUS:
                        memcpy (&pBme->BmeParms.SystemStatusParms,
                                &pBme->RxBmeMsg[_BmeDataStart_],pBme->RxBmeMsg[_BmeDataLENGTH_]);
            break;

          case PORT_INSTANTIATE:
          case PORT_START:
          case PORT_STATUS_EXTENDED:
                        MEMCPY (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PortStatusExtParms,
                                &pBme->RxBmeMsg[_BmeDataStart_],sizeof(UINT32), 6);
                        memcpy (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PortStatusExtParms.FastDsNumParityBytes),
                                &pBme->RxBmeMsg[_BmeDataStart_ + 24],4);
                        MEMCPY (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PortStatusExtParms.DsDelay),
                                &pBme->RxBmeMsg[_BmeDataStart_ + 28],sizeof(UINT16), 11);
                        memcpy (pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PortStatusExtParms.NeItuVendorId,
                                &pBme->RxBmeMsg[_BmeDataStart_ + 50],16);
                        MEMCPY (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PortStatusExtParms.FeTransmitPower),
                                &pBme->RxBmeMsg[_BmeDataStart_ + 66],sizeof(UINT16), 6);

		   /* copy complete thru SlowDsFFTProtection; next field is FastDsCodeWordSize */

                        memcpy (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PortStatusExtParms.FastDsCodeWordSize),
                                &pBme->RxBmeMsg[_BmeDataStart_ + 78], 11 );

                        memcpy (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PortStatusExtParms.LineType),
                                &pBme->RxBmeMsg[_BmeDataStart_ + 89], 4);

            break;

          case DEVICE_VERSIONS:
                        memcpy (&pBme->Port[/*(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]*/0].PortParms.DeviceVerParms,
                                &pBme->RxBmeMsg[_BmeDataStart_],pBme->RxBmeMsg[_BmeDataLENGTH_]);
                        pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.DeviceVerParms.VersionLen=pBme->RxBmeMsg[_BmeDataLENGTH_];
            break;

          case GET_COUNTERS:
              MEMCPY (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.GetCounterParms,
                  &pBme->RxBmeMsg[_BmeDataStart_],sizeof(UINT32), 2);
              MEMCPY (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.GetCounterParms.NeCRC_S),
                  &pBme->RxBmeMsg[_BmeDataStart_ + 8],sizeof(WORD), 2);
              pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.GetCounterParms.NeLOS=pBme->RxBmeMsg[_BmeDataStart_ + 16];
              MEMCPY (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.GetCounterParms.NeSEF),
                  &pBme->RxBmeMsg[_BmeDataStart_ + 17],sizeof(WORD), 2);
              memcpy (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.GetCounterParms.NeNCD_S),
                  &pBme->RxBmeMsg[_BmeDataStart_ + 21],15);
              MEMCPY (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.GetCounterParms.NeFECUnCrr_S),
                  &pBme->RxBmeMsg[_BmeDataStart_ + 36],sizeof(UINT32), 10);
              MEMCPY (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.GetCounterParms.FeFEC_S),
                  &pBme->RxBmeMsg[_BmeDataStart_ + 76],sizeof(WORD), 14); // 13 U16 //14 U16 sixPT flag

//              printf("\n %u H1 %d\n", tickGet(), (pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.GetCounterParms.sixPtLineHold));
              break;


          case GET_PM_COUNTERS:

          /* Copy data into PmCounterParms structure. Split memcpy to care of
             any potential byte-stuffing by the compiler. */
          memcpy (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PmCounterParms,
                  &pBme->RxBmeMsg[_BmeDataStart_], 2); // 2 U8

          memcpy (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PmCounterParms.NeFailures,
                  &pBme->RxBmeMsg[_BmeDataStart_ + 2], 68); // 6+28 sU16

          memcpy (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PmCounterParms.NeFEC_S),
                                &pBme->RxBmeMsg[_BmeDataStart_ + 70], 96);  // 24 U32 

          memcpy (&(pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PmCounterParms.sixPtLineHold),
                                &pBme->RxBmeMsg[_BmeDataStart_ + 166], 6);  // 3 U16  

//              printf("\n %u H2 %d\n", tickGet(), (pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PmCounterParms.sixPtLineHold));

              break;

          case GET_PM_ALERT:
              dapiRetrieveAlerts (&pBme->RxBmeMsg[_BmeDataStart_],
                  &pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.PmAlertParms);
              break;

          case GET_SELFTEST_RESULTS:
                        memcpy (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.SelftestResultsParms,
                                &pBme->RxBmeMsg[_BmeDataStart_],pBme->RxBmeMsg[_BmeDataLENGTH_]);
            break;

          case EOC_GET_DATA:
                        memcpy (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.EocGetDataParms.RtnEocOpcode,
                                &pBme->RxBmeMsg[_BmeDataStart_],1);
                        memcpy (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.EocGetDataParms.EocRegisterData,
                                &pBme->RxBmeMsg[_BmeDataStart_+1],128);
            break;

          case EOC_DATA_RECEIVE:
                        memcpy (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.EocDataRecvParms,
                                &pBme->RxBmeMsg[_BmeDataStart_],pBme->RxBmeMsg[_BmeDataLENGTH_]);
            break;

          case GET_NE_SNR_ATTN:
						dapiRetrieveSnrAttn (&pBme->RxBmeMsg[_BmeDataStart_],
																 &pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.NeSnrAttn);
            break;
          case GET_OPCMD_STATUS:
            // printf("gotten optional command, len = %d", pBme->RxBmeMsg[_BmeDataLENGTH_]);
                        memcpy(&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.opCmdResults,
                               &pBme->RxBmeMsg[_BmeDataStart_],pBme->RxBmeMsg[_BmeDataLENGTH_]);
            break;
          case DETECT_SIGNALS:
                        memcpy (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.DetectSigParms.DetectSigType,
                                &pBme->RxBmeMsg[_BmeDataStart_],pBme->RxBmeMsg[_BmeDataLENGTH_]);
		break;

                        /* Autonomous EOC commands*/
          case EOC_RELAY_DATA_STREAM:
                        pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.EocRelayDataStrParms.len =
               pBme->RxBmeMsg[_BmeDataLENGTH_];
                        memcpy (pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.EocRelayDataStrParms.DataStream,
                                &pBme->RxBmeMsg[_BmeDataStart_],pBme->RxBmeMsg[_BmeDataLENGTH_]);
            break;

          case EOC_MSG_RECEIVE:
                        memcpy (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.EocMsgRecvParms,
                                &pBme->RxBmeMsg[_BmeDataStart_],pBme->RxBmeMsg[_BmeDataLENGTH_]);
            break;

          case SET_LOOPBACK:
                        memcpy (&pBme->Port[(UINT)pBme->RxBmeMsg[_BmeMsgSRC_]].PortParms.SetLpbkParms,
                                &pBme->RxBmeMsg[_BmeDataStart_],pBme->RxBmeMsg[_BmeDataLENGTH_]);
          break;

          case HPI_HOST_RETRIEVE_BME_CONFIG:
                        dapiRetrieveSysConfig (&pBme->RxBmeMsg[_BmeDataLENGTH_], &pBme->BmeParms.bmeRxSysProvParms);
          break;

          case HPI_HOST_RETRIEVE_PORT_CONFIG:
                        dapiRetrievePortConfig (&pBme->RxBmeMsg[_BmeDataLENGTH_], 
                                      &pBme->Port[pBme->RxBmeMsg[_BmeDataStart_]].PortParms.bmeRxPortProfile);
          break;

          default:

            break;
         };

            } /* if (pBme->RxBmeMsg[_BmeMsgACK_]==ACK_SUCCESS) */
//				}

      /* Need to clear DW_H and MR_H bits? */
#ifndef CPE_30
            bmeClrStatus (pBme, CLR_DW_H_DMA_WRITE_DONE);
            bmeClrStatus (pBme, CLR_MSG_RDY_IN_BME_DPRAM);
#ifndef CO_30
            data = 0x00000000;
            bmePioWrite (pBme, DMA_CCR(0, DMA_CH_15), (BYTE *)&data);
#endif
#endif

#ifndef _BME_TEST_CODE_

            /*testcode*/
            //*((BYTE *)pBme->BMEbaseAddr+(DMA_STATUS_PORT<<2))=0x00;
            clearDmaStatus();
            pBme->fifoStatus=FIFO_EMPTY;
            pBme->msgRdyPending=FALSE;
            /* testcode*/
#endif          /* _BME_TEST_CODE_ */
#ifndef CPE_30

        } /*if (HwiApiRv==HWAPI_READ_SUCCESS)*/

#endif
   }                                                       /* if (fifoStatus == FIFO_READ) */

    return(HwiApiRv);

}                                                          /* ReceiveBmeMessage */


void convertDataToEndianFormat (BYTE bDataSize, BYTE *bDataPtr)
{

   BYTE bTmpData;
   int index;

    switch (HostCpuEndianType)
    {
    case LITTLE_ENDIAN_FORMAT:

      /* flipping the bytes */
            for (index = 0; index < (bDataSize/2); index++)
            {
                bTmpData = *(bDataPtr+index);
                *(bDataPtr+index)= *(bDataPtr+bDataSize-(index+1));
                *(bDataPtr+bDataSize-(index+1)) = bTmpData;
      }

      break;

    case BIG_ENDIAN_FORMAT:
      /* do nothing. copy as it is & return */
      break;

    default:
            printf ("\nUnknown Endian Format. Error!!!!");
      break;
   }

   return;
}

#ifndef USE_BIG_ENDIAN_FORMAT
static void memcpyLittleEndian (BYTE *pData, BYTE *pParms, BYTE bDataSize, BYTE numData)
{
  int index;

	do
	{
    for (index = 1; index <= bDataSize; index++)
    {
        *(pData++)= *(pParms + bDataSize - index);
		}
		pParms += bDataSize;
	} while (--numData > 0);
	return;
}
#endif


static void dapiRetrieveAlerts (U8 *data, struct tPmAlertParms *alertParm)
{
	MEMCPY(&(alertParm->NeFailures), data, sizeof(UINT16), 1);
	data += sizeof(UINT16);
	MEMCPY(&(alertParm->FeFailures), data, sizeof(UINT16), 1);
	data += sizeof(UINT16);
	MEMCPY(&(alertParm->NeTCA1), data, sizeof(UINT16), 1);
	data += sizeof(UINT16);
	MEMCPY(&(alertParm->FeTCA1), data, sizeof(UINT16), 1);
	data += sizeof(UINT16);
	MEMCPY(&(alertParm->NeTCA2), data, sizeof(UINT16), 1);
	data += sizeof(UINT16);
	MEMCPY(&(alertParm->FeTCA2), data, sizeof(UINT16), 1);
}

static void dapiRetrieveSnrAttn (U8 *data, struct tGetNeSnrAttn *snrParm)
{
	MEMCPY(&(snrParm->SnrMargin), data, sizeof(LONG), 1);
	data += sizeof(LONG);
	MEMCPY(&(snrParm->Attn), data, sizeof(LONG), 1);
	data += sizeof(LONG);
	MEMCPY(&(snrParm->AvgSnrMargin), data, sizeof(LONG), 1);
	data += sizeof(LONG);
	MEMCPY(&(snrParm->AvgSnr), data, sizeof(LONG), 1);
}

/*******************************************************************
 Name       : iPos Retrieve System Configuration
 Description: Retrieves the System Configuration from the HOST_RETRIEVE_BME_CONFIG
              message sent from BME, into the tSystemProv structure.
*********************************************************************/

static void dapiRetrieveSysConfig (U8 *data, struct tSystemProv *sysProvParms)
{
  char *parm = data;
  int bme_provisioned, size, msglen;
  
  memset (sysProvParms, 0xee, sizeof(struct tSystemProv));

  msglen = *parm ++;
  bme_provisioned = *parm++;

  if (bme_provisioned) {
    /* Only if BME is provisioned, we proceed further and update the
     * system configuration. */

    MEMCPY(&(sysProvParms->VendorIdT1E1),parm,sizeof(UINT16), 1);
    parm+=sizeof(UINT16);

    size=sizeof(sysProvParms->VendorIdItu);
    memcpy(sysProvParms->VendorIdItu,parm,size);
    parm+=size;

    MEMCPY(&(sysProvParms->RevisionNum),parm,sizeof(UINT32), 1);
    parm+=sizeof(UINT32);

    size=sizeof(sysProvParms->SerialNumber);
    memcpy(sysProvParms->SerialNumber,parm,size);
    parm+=size;

    sysProvParms->AtmOption = *parm++;

    sysProvParms->AtmCellSize = *parm++;

    sysProvParms->OptionMask = *parm++;

    sysProvParms->BandPlan = *parm++;

    sysProvParms->NumPort = *parm++;

    sysProvParms->psdMaskLevelIndx = *parm++;

    MEMCPY(sysProvParms->k0, parm,sizeof(UINT32), 3);
    parm+= 3*sizeof(UINT32);

    MEMCPY(sysProvParms->k1, parm,sizeof(UINT32), 3);
    parm+= 3*sizeof(UINT32);
	
    MEMCPY(&(sysProvParms->custId), parm,sizeof(UINT16), 1);
    parm+= sizeof(UINT16);

    MEMCPY(sysProvParms->keys, parm,sizeof(UINT16), 3);
    parm+= 3*sizeof(UINT16);

    MEMCPY(&(sysProvParms->iposVer), parm,sizeof(UINT16), 1);
    parm+=sizeof(UINT16);

    sysProvParms->ife2PwrMode = *parm++;
   
    sysProvParms->OamOptionMask = *parm++;
    
    MEMCPY(sysProvParms->k0_hi, parm,sizeof(UINT32), 3);
    parm+= 3*sizeof(UINT32);

    MEMCPY(sysProvParms->k1_hi, parm,sizeof(UINT32), 3);
    parm+= 3*sizeof(UINT32);
	
    memcpy(&(sysProvParms->MaxPsd), parm, DAPI_MAX_PSD_LEN);
    parm+= DAPI_MAX_PSD_LEN;
	
  }

}


/*******************************************************************
 Name       : iposRetrieve Port Configuration
 Description: Retrieves the Port Configuration from the HOST_RETRIEVE_PORT_CONFIG
              message sent from BME, into a local variable of type tPortProv.
*********************************************************************/

static void dapiRetrievePortConfig(U8 *data, struct tPortProfile *portProfile)
{
   char *pDataSec = data;
   int port, msglen;

   msglen = *pDataSec++;
   port = *pDataSec++;

    portProfile->PortProvParms.InterleavedChannel = *pDataSec++;
    portProfile->PortProvParms.FastChannel = *pDataSec++;
    portProfile->PortProvParms.LineType = *pDataSec++;
    portProfile->PortProvParms.DslMode = 5;
    pDataSec++;
    portProfile->PortProvParms.RateAdaptationMode = *pDataSec++;
    portProfile->PortProvParms.InterleavedPercentage = *pDataSec++;

    MEMCPY((char *)&(portProfile->PortProvParms.UpstreamMaxRateFast),pDataSec,sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    MEMCPY((char *)&(portProfile->PortProvParms.UpstreamMinRateFast),pDataSec,sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    MEMCPY((char *)&(portProfile->PortProvParms.UpstreamMaxRateSlow),pDataSec,sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    MEMCPY((char *)&(portProfile->PortProvParms.UpstreamMinRateSlow),pDataSec,sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    portProfile->PortProvParms.UpstreamMaxInterDelay = *pDataSec++;

    MEMCPY(&(portProfile->PortProvParms.DownstreamMaxRateFast),pDataSec,sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(&(portProfile->PortProvParms.DownstreamMinRateFast),pDataSec,sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(&(portProfile->PortProvParms.DownstreamMaxRateSlow),pDataSec,sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    MEMCPY(&(portProfile->PortProvParms.DownstreamMinRateSlow),pDataSec,sizeof(UINT32), 1);
    pDataSec+=sizeof(UINT32);
    portProfile->PortProvParms.DownstreamMaxInterDelay = *pDataSec++;
    portProfile->PortProvParms.NumParityFast = *pDataSec++;
    portProfile->PortProvParms.NumParitySlow = *pDataSec++;

    MEMCPY(&(portProfile->PortProvParms.UsTargetNoiseMargin),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(&(portProfile->PortProvParms.DsTargetNoiseMargin),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(&(portProfile->PortProvParms.MinNoiseMargin),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);

    portProfile->PortProvParms.BandPlan = *pDataSec++;

    portProfile->PortProvParms.NumRFIBand = *pDataSec++;

    MEMCPY(&(portProfile->PortProvParms.Band1Start),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(&(portProfile->PortProvParms.Band1Stop),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(&(portProfile->PortProvParms.Band2Start),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(&(portProfile->PortProvParms.Band2Stop),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(&(portProfile->PortProvParms.Band3Start),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(&(portProfile->PortProvParms.Band3Stop),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(&(portProfile->PortProvParms.Band4Start),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(&(portProfile->PortProvParms.Band4Stop),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(&(portProfile->PortProvParms.Band5Start),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);
    MEMCPY(&(portProfile->PortProvParms.Band5Stop),pDataSec,sizeof(UINT16), 1);
    pDataSec+=sizeof(UINT16);   

    pDataSec++; /* Skip Activate Mode */

    portProfile->PortProvParms.RFIBand1 = *pDataSec++;

    portProfile->PortProvParms.RFIBand2 = *pDataSec++;

    portProfile->PortProvParms.RFIBand3 = *pDataSec++;

    portProfile->PortProvParms.RFIBand4 = *pDataSec++;

    portProfile->PortProvParms.RFIBand5 = *pDataSec++;

    portProfile->BandMod.bandModifier = *pDataSec++;

    portProfile->OptionParms.PortOption = *pDataSec++;
//    portProfile->OptionParms.Reserved1 = *pDataSec++;
//    portProfile->OptionParms.Reserved2 = *pDataSec++;
//    portProfile->OptionParms.Reserved3 = *pDataSec++;

    portProfile->IFE_BRD_CFG.pwrMode = *pDataSec++;

    portProfile->IFE_BRD_CFG.rxPathFilterMode = *pDataSec++;

    portProfile->IFE_BRD_CFG.txPathFilterMode = *pDataSec;
    
}
