/*****************************************************************************
  $Workfile:   fileDnld2.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.1 $
  $Date: 2006/10/16 04:34:51 $

*****************************************************************************/
#define DEBUG_LEVEL                 (0)
#define TEST_LEVEL                  (1)
#if (DEBUG_LEVEL > 0)
#define DEBUG1_PRINTF(x) printf x
#else
#define DEBUG1_PRINTF(x)
#endif

#if (TEST_LEVEL > 0)
/*****************************************************************************
                       I n c l u d e s
*****************************************************************************/
#include <stdio.h>
#include "dapi.h"
#include "bmehwapi.h"
#include "ipos.h"
#include "oampdef.h"
#include "appconfig.h"
#include "oampstruct.h"
#include <bmehwapi.h>
#include "apilocal.h"
#include "bsp.h"
#include "eventlog.h"
#ifndef USE_VXWORKS
#include "v2pthread.h"
#endif
/*****************************************************************************
					 	         T y p e s
*****************************************************************************/
/*****************************************************************************
						      D e f i n e s
*****************************************************************************/
#define STATIC	static

//#undef  USE_TARGET_SERVER
//#define USE_FTP

#undef	USE_FTP
#define	USE_TARGET_SERVER


#ifdef  USE_TARGET_SERVER
#define XTENSA_BIN_FILE    "/tgtsvr/release.bin"
#endif

#ifdef USE_FTP
#include <ftpLib.h>
#define XTENSA_BIN_FILE    "vxWorks.bin"
#define SERVER_ADDR        "10.1.112.247"
#define USER               "cpe30fw"
#define PWD                "cpe30fw"
#define DIR                ""
#endif

/*****************************************************************************
					            D a t a
*****************************************************************************/
extern BYTE HostCpuEndianType;
extern tBmeStruct BmeStruct[];
extern oamp_bme oampBme[IPOS_MAX_BME + 1];
extern ipos_api_bme apiBme[IPOS_MAX_BME + 1];
static unsigned char BmeResetVecCode[BME_RESET_VEC_CODE_SIZE] = {
0x60, 0x00, 0x04, 0x00, 0xff, 0x01, 0x00, 0xff /* 0x70 */ , 0x10, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00};

extern void bmeRelCpu (tBmeStruct *pBme,unsigned char enable);
extern char getSysInfo (char *sysInfo);
extern void init_sdram_32clk ();
extern void init_sdram_16clk ();
extern void tpw (int BmeNum, unsigned long addr, unsigned long data);
extern int jagWriteBlock(U32 id, U32 dst,U32 src,int nBytes);
extern int jagReadBlock(U32 id, U32 dst,U32 src,int nBytes);
extern void setProdMode (unsigned char enable);
extern eoamp_bme_state oampBmeStateUpdate(int bmeNum,eoamp_event   event);
extern void HostFpgaWrite(BYTE boffset,BYTE bdata);
extern HWAPI_RET_VAL bmeDnldProcedure (tBmeStruct *bmeStruct);extern HWAPI_RET_VAL bmeDnldProcedure (tBmeStruct *bmeStruct);
/*****************************************************************************
				      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
*****************************************************************************/
/*******  Local Data            ***************************************/

/******************************************************************************
   Name 	   : bmeDnldProcedure
   Purpose  : To download software code to BME chip

   Parameters :
   no		Name		Type			Description
   --		----		----			-----------
   1. bmeStruct      tBmeStruct*	BME structure address

   Return	   :
   Type				Description
   ----				-----------
   HWAPI_RET_VAL		if dnld is successful, HWAPI_DNLD_SUCCESS
                  if error, HWAPI_DNLD_FAILURE, HWAPI_DNLD_TIMEOUT


******************************************************************************/
/****************************************************************************/
/*                                                                          */
/* Function.. : wrDnld			                          			        */
/*                                                   	                    */
/* Purpose... : function to write/download code to BME memory thru DMA FIFO */
/*				interface in a loop											*/
/*																			*/
/* Parameters : 															*/
/* No		Name		Type				Description						*/
/* --       ----        ----        		-----------						*/
/*	1.		cnt			int		number of times to download code		 	*/
/*                                                                          */
/* Returns... : N/A                                                         */
/*                                                                          */
/* Notes..... : 												            */
/*                                                                          */
/****************************************************************************/
#ifdef CPE_40


void flDnld(int clkRate, int iMode, int nucleus, int open) // 0,1,1
{

// doing this cos were outta eme
#ifndef BUP_DIAGS

#ifdef USE_TARGET_SERVER
   FILE *fp;
#endif
   unsigned int numread;
   unsigned int i = 0,
    codeDnldAddr,
    iCounter1 = 0,
    iCounter2 = 0;
    int j;
   static unsigned char buf[MAX_DATA_LENGTH + 1];
   static unsigned char buf1[MAX_DATA_LENGTH + 1];

   tBmeStruct *bme = &BmeStruct[1];
#ifdef USE_FTP
   int       ctrlSock;
   int       dataSock;
#endif

#ifdef	BME_CPE_20
   sysInfo sInfo;
#endif


	if (nucleus)
		printf("Downloading Nucleus Code\n");
	else
		printf("Downloading Vxworks Code\n");

   HostCpuEndianType = 2;
   bme->BMEbaseAddr = 0x08000000;
   bme->BmeState = INACTIVE;
   bme->BmeNum = 1;

//   printf("\nStart Download from File");
   EventLog("b%dp0 flDnld", bme->BmeNum);

#ifdef	BME_CPE_20
   /* 1. release cpu - ReleaseBmeCpu - Inactive state */
   if (clkRate > 0) {
      bmeRelCpu(bme, FALSE);                               /* hold BME cpu */
      taskDelay(10);
   }
   getSysInfo((char *) &sInfo);
	if (iMode) { // EMOE
		switch(sInfo.memInfo) {
       case IPOS_BME_MEM_SDRAM32:
         init_sdram_32clk();
         break;
       case IPOS_BME_MEM_SDRAM16:
         init_sdram_16clk();

         break;
       default:
         init_sdram_16clk();

   //	init_sdram_16clkby2 ();
      }
   }
   InitSdramCPE4 (open);
   printf("\nEMI initialized");


/* 2. Initialize & program DMA channel 15 */
   InitDmaChannel15(bme);
   printf("\nBME initialized");
#else
   /* 1. release cpu - ReleaseBmeCpu - Inactive state */
   if (clkRate > 0) {
      bmeRelCpu(bme, FALSE);                               /* hold BME cpu */
      bmeHWReset();                                        /* resetBmeHardware */
      taskDelay(10);
      setclk(bme /* BmeNum */ , clkRate);                  /* set Bme clock rate */
      fpgaHWReset();                                       // reset FPGA
   }
   /* 2. Initialize & program DMA channel 15 */
   InitDmaChannel15(bme);
   printf("\nBME initialized");

   /* 3. Initialize & program the EMI interface */
   bmeInitEMIConfig(bme);
   printf("\nEMI initialized");
#endif

#ifdef USE_TARGET_SERVER
   // get initial contents for reset vectors
   /* Open Bme code binary file */
   if ((fp = fopen(XTENSA_BIN_FILE, "rb")) == NULL) {
      printf("\nUnable to open Xtensa file %s", XTENSA_BIN_FILE);
      return;
   }
   numread = fread(buf, sizeof(char), MAX_DATA_LENGTH + 1, fp);
   if (numread <= 0) {
      printf("Error reading file %s\n",XTENSA_BIN_FILE);
      return ;
   }

   fclose (fp);
   /* Open Bme code binary file */
   if ((fp = fopen(XTENSA_BIN_FILE, "rb")) == NULL) {
      printf("\nUnable to open Xtensa file %s\n", XTENSA_BIN_FILE);
      return;
   }
#endif /* USE_TARGET_SERVER */
#ifdef USE_FTP
   if (ftpXfer (SERVER_ADDR, USER, PWD, "",
        "RETR %s",DIR, XTENSA_BIN_FILE,
        &ctrlSock, &dataSock) == ERROR) {
      return;
   }

   if ((numread = read (dataSock, buf, sizeof (buf))) <= 0) {
      printf("Error reading file %s\n",XTENSA_BIN_FILE);
      return ;
   }
   close (dataSock);
   ftpCommand (ctrlSock, "QUIT", 0, 0, 0, 0, 0, 0);
   close (ctrlSock);
   if (ftpXfer (SERVER_ADDR, USER, PWD, "",
        "RETR %s",DIR, XTENSA_BIN_FILE,
        &ctrlSock, &dataSock) == ERROR) {
      return;
   }
#endif
   tpw( 1, 0xE00A600C, 0x80000000 ); // EMOE: Map SDRAM into boot area...

   /* 4. transfer BME code from file to BME memory */
   bme->BmeState = SW_DNLD_IN_PROGRESS;
   /* Download BME reset vector */
   /* Set jump address in reset vector */
   BmeResetVecCode[4] = buf[8];
   BmeResetVecCode[5] = buf[9];
   BmeResetVecCode[6] = buf[10];
   BmeResetVecCode[7] = buf[11];

	if (nucleus == 1)
	{
		BmeResetVecCode[4] = 0x40;
		BmeResetVecCode[5] = 1;
		BmeResetVecCode[6] = 0;
		BmeResetVecCode[7] = 0x60;
		printf("Downloading VIPER NUCLEUS\n");
	}


   printf("\n BmeResetVecCode %x %x %x %x", BmeResetVecCode[4],
          BmeResetVecCode[5], BmeResetVecCode[6], BmeResetVecCode[7]);


   /* set the BME code size & download address - for BME reset vector code */
   bme->BMECodeSize = BME_RESET_VEC_CODE_SIZE;             /* 16 */
   bme->BMECodeDnldAddr = BME_RESET_VEC_CODE_DNLD_ADDR;
   bme->dataPtr = &BmeResetVecCode[0];


//   jagWriteBlock(bme->BmeNum,BME_RESET_VEC_CODE_DNLD_ADDR,(U32)bme->dataPtr,BME_RESET_VEC_CODE_SIZE);
//   if (bmeSoftwareDnld(bme) != HWAPI_DNLD_SUCCESS) {
//      fclose(fp);
//      printf("\nError downloading BME vector!");
//      return;
//   } else
//      printf("\nReset vector code downloaded successfully");

   /* Download BME code */
   printf("\nDownloading BME software");
   j = 0;
   codeDnldAddr = BME_CODE_DNLD_ADDR;

	if (nucleus == 1)
	{
		codeDnldAddr = 0x40010060;
	}



#if defined(CPE_30) || defined(CPE_40)
   bme->destAddr = codeDnldAddr;
#ifdef USE_TARGET_SERVER
   while ((numread = fread(buf, sizeof(char), MAX_DATA_LENGTH + 1, fp)) > 0) {
#endif
#ifdef USE_FTP
   while ((numread = read (dataSock, buf, sizeof (buf))) > 0) {
#endif
      // give some download progress
      if (j++ == 0x3F) {
         printf(".");
         j=0;
      }
      bme->dataLen = numread;
      bme->dataPtr = buf;
//      jagWriteBlock(bme->BmeNum,bme->destAddr,(U32)buf,numread);
//      if (bmeSoftwareDnld(bme) != HWAPI_DNLD_SUCCESS) {
//         printf("Error downloading file\n");
//      }
#if 0
      // check for data
      jagReadBlock(bme->BmeNum,buf1,bme->destAddr,numread);
      for (i=0;i<numread;i++) {
         if (buf1[i] != buf[i]) {
            EventLog("b%dp0 ...bmeSoftwareDnld: Error writing code into memory 0x%lx!", bme->BmeNum, codeDnldAddr);
            printf("\nDownload error at %x - expect %x, actual %x\n",
                                                      bme->destAddr + i,
                                                      buf[i],buf1[i]);
            goto bail;
         }
      }
#endif
      bme->destAddr += numread;
   }
   if (bme->destAddr == codeDnldAddr) {
      printf("\nError downloading file\n");
      return;
   }

   bme->destAddr = codeDnldAddr;
#else
   do {
      if ((i++ & 0x3F) == 0)
         printf(".");
      /* transmit data to BME memory */
      bme->destAddr = codeDnldAddr;
      bme->dataLen = numread;
      bme->dataPtr = buf;
      if (DoTxCmd(bme) != HWAPI_WRITE_SUCCESS) {
         iCounter1++;
         if (iCounter1 < MAX_WAIT_COUNT)                   /* wait for success for 16 times */
            continue;
         else {
            fclose(fp);
            EventLog("b%dp0 ...bmeSoftwareDnld: Error writing code into memory 0x%lx!", bme->BmeNum, codeDnldAddr);
            bme->dataPtr = &bme->BmeMsg[0];
            return;
         }
      } else {
         iCounter1 = 0;

         while (1) {
            /* wait for DW_H status bit to be set to indicate DMA Write is done */
            if (bmePollDmaStatus(bme) == DMA_DONE) {
               iCounter2 = 0;
               break;
            } else {
               /* keep a counter or timer. If timer value times out the max wait time, break from the loop & report a failure to the
                * api. */
               iCounter2++;
               if (iCounter2 < MAX_WAIT_COUNT)             /* wait for 16/256 times */
                  iposDelay();
               else {
                  fclose(fp);
                  EventLog("b%dp0 ...bmeSoftwareDnld: Error dma not done while downloading BME code!", bme->BmeNum);
                  bme->dataPtr = &bme->BmeMsg[0];
                  return;
               }
            }
         }

         /* if DW_T bit is set by DMA controller, change the BmeDnldVerifyState from DW_T_BIT_RESET to DW_T_BIT_SET */
         if (bme->BmeDnldVerifyState == DW_T_BIT_RESET) {
            /* check the status[1] (DW_T) bit of DMA Status Port to be one. This indicates data is transferred from the fifo to BME
             * memory. */
            if (bmeRdStatus(bme) & DW_T_DMA_WRITE_DONE)
               bme->BmeDnldVerifyState = DW_T_BIT_SET;
         }
         /* This code reads back each block of written data & checks for written data validity. It compares each read byte with each
          * write byte & gives an error, if both are not matching */

         if (bmeVerifyWriteCode(bme, codeDnldAddr, numread, buf) !=
             HWAPI_CODE_CHKSUM_SUCCESS) {
            fclose(fp);
            EventLog("b%d,p0 ...bmeSoftwareDnld: Error while reading data.\n",
                     bme->BmeNum);
            return;
         }
      }

      codeDnldAddr += numread;                             /* increment the code download addr */
   } while ((numread = fread(buf, sizeof(char), MAX_DATA_LENGTH + 1, fp)) > 0);
#endif
   EventLog("Bme software code downloaded successfully");
   printf("\n************************************");
   printf("\nDownload completed successfully!");
   printf("\n************************************\n");

bail:
#ifdef USE_TARGET_SERVER
   fclose(fp);
#endif
#ifdef USE_FTP
   close (dataSock);
   ftpCommand (ctrlSock, "QUIT", 0, 0, 0, 0, 0, 0);
   close (ctrlSock);
#endif


   /* change the BmeState from SW_DNLD_IN_PROGRESS to SW_DNLD_DONE */
   bme->BmeState = SW_DNLD_DONE;
   bme->dataPtr = &bme->BmeMsg[0];

   /* 5. set production mode to development */
   setProdMode(iMode);

   /* 6. release cpu - ReleaseBmeCpu - active state */
   bmeRelCpu(bme, TRUE);                                   /* release BME cpu */

#ifdef EMUL
	printf("\nStart the target board. When done, press 'return'. \n");
	gets (buf);
#endif
//	oampBmeStateUpdate(1, eBME_START);

//	iposStateUpdate(&apiBme[1], IPOS_BME_STARTED);

/*	iniwrite (0x1,0x15);
   iniwrite (0x7,0x1);
   iniwrite (0x3,0x80);
*/

#ifdef	BME_CPE_20
   HostFpgaWrite(0x07, 0x01);
#endif

   return;

#endif // bup_diags

}


#else
void flDnld(int clkRate, int iMode)
{

// doing this cos were outta eme
#ifndef BUP_DIAGS

#ifdef USE_TARGET_SERVER
   FILE *fp;
#endif
   unsigned int numread;
   unsigned int i = 0,
    codeDnldAddr;
    //iCounter1 = 0,
    //iCounter2 = 0;
    int j;
   static unsigned char buf[MAX_DATA_LENGTH + 1];
   static unsigned char buf1[MAX_DATA_LENGTH + 1];

   tBmeStruct *bme = &BmeStruct[1];
#ifdef USE_FTP
   int       ctrlSock;
   int       dataSock;
#endif

#ifdef	BME_CPE_20
   sysInfo sInfo;
#endif
   HostCpuEndianType = 2;
   bme->BMEbaseAddr = 0x08000000;
   bme->BmeState = INACTIVE;
   bme->BmeNum = 1;

//   printf("\nStart Download from File");
   EventLog("b%dp0 flDnld", bme->BmeNum);

#ifdef	BME_CPE_20
   /* 1. release cpu - ReleaseBmeCpu - Inactive state */
   if (clkRate > 0) {
      bmeRelCpu(bme, FALSE);                               /* hold BME cpu */
      taskDelay(10);
   }
   getSysInfo((char *) &sInfo);
	if (iMode) { // EMOE
		switch(sInfo.memInfo) {
       case IPOS_BME_MEM_SDRAM32:
         init_sdram_32clk();
         break;
       case IPOS_BME_MEM_SDRAM16:
         init_sdram_16clk();
         break;
       default:
         init_sdram_16clk();

   //	init_sdram_16clkby2 ();
      }
   }
   printf("\nEMI initialized");

/* 2. Initialize & program DMA channel 15 */
   InitDmaChannel15(bme);
   printf("\nBME initialized");
#else
   /* 1. release cpu - ReleaseBmeCpu - Inactive state */
   if (clkRate > 0) {
      bmeRelCpu(bme, FALSE);                               /* hold BME cpu */
      bmeHWReset();                                        /* resetBmeHardware */
      taskDelay(10);
      setclk(bme /* BmeNum */ , clkRate);                  /* set Bme clock rate */
      fpgaHWReset();                                       // reset FPGA
   }
   /* 2. Initialize & program DMA channel 15 */
   InitDmaChannel15(bme);
   printf("\nBME initialized");

   /* 3. Initialize & program the EMI interface */
   bmeInitEMIConfig(bme);
   printf("\nEMI initialized");
#endif

#ifdef USE_TARGET_SERVER
   // get initial contents for reset vectors
   /* Open Bme code binary file */
   if ((fp = fopen(XTENSA_BIN_FILE, "rb")) == NULL) {
      printf("\nUnable to open Xtensa file %s", XTENSA_BIN_FILE);
      return;
   }
   numread = fread(buf, sizeof(char), MAX_DATA_LENGTH + 1, fp);
   if (numread <= 0) {
      printf("Error reading file %s\n",XTENSA_BIN_FILE);
      return ;
   }

   fclose (fp);
   /* Open Bme code binary file */
   if ((fp = fopen(XTENSA_BIN_FILE, "rb")) == NULL) {
      printf("\nUnable to open Xtensa file %s\n", XTENSA_BIN_FILE);
      return;
   }
#endif /* USE_TARGET_SERVER */
#ifdef USE_FTP
   if (ftpXfer (SERVER_ADDR, USER, PWD, "",
        "RETR %s",DIR, XTENSA_BIN_FILE,
        &ctrlSock, &dataSock) == ERROR) {
      return;
   }

   if ((numread = read (dataSock, buf, sizeof (buf))) <= 0) {
      printf("Error reading file %s\n",XTENSA_BIN_FILE);
      return ;
   }
   close (dataSock);
   ftpCommand (ctrlSock, "QUIT", 0, 0, 0, 0, 0, 0);
   close (ctrlSock);
   if (ftpXfer (SERVER_ADDR, USER, PWD, "",
        "RETR %s",DIR, XTENSA_BIN_FILE,
        &ctrlSock, &dataSock) == ERROR) {
      return;
   }
#endif
   tpw( 1, 0xE00A600C, 0x80000000 ); // EMOE: Map SDRAM into boot area...

   /* 4. transfer BME code from file to BME memory */
   bme->BmeState = SW_DNLD_IN_PROGRESS;
   /* Download BME reset vector */
   /* Set jump address in reset vector */
   BmeResetVecCode[4] = buf[8];
   BmeResetVecCode[5] = buf[9];
   BmeResetVecCode[6] = buf[10];
   BmeResetVecCode[7] = buf[11];

   printf("\n BmeResetVecCode %x %x %x %x", BmeResetVecCode[4],
          BmeResetVecCode[5], BmeResetVecCode[6], BmeResetVecCode[7]);


   /* set the BME code size & download address - for BME reset vector code */
   bme->BMECodeSize = BME_RESET_VEC_CODE_SIZE;             /* 16 */
   bme->BMECodeDnldAddr = BME_RESET_VEC_CODE_DNLD_ADDR;
   bme->dataPtr = &BmeResetVecCode[0];


//   jagWriteBlock(bme->BmeNum,BME_RESET_VEC_CODE_DNLD_ADDR,(U32)bme->dataPtr,BME_RESET_VEC_CODE_SIZE);
//   if (bmeSoftwareDnld(bme) != HWAPI_DNLD_SUCCESS) {
//      fclose(fp);
//      printf("\nError downloading BME vector!");
//      return;
//   } else
//      printf("\nReset vector code downloaded successfully");

   /* Download BME code */
   printf("\nDownloading BME software");
   j = 0;
   codeDnldAddr = BME_CODE_DNLD_ADDR;
#ifdef CPE_30
   bme->destAddr = codeDnldAddr;
#ifdef USE_TARGET_SERVER
   while ((numread = fread(buf, sizeof(char), MAX_DATA_LENGTH + 1, fp)) > 0) {
#endif
#ifdef USE_FTP
   while ((numread = read (dataSock, buf, sizeof (buf))) > 0) {
#endif
      // give some download progress
      if (j++ == 0x3F) {
         printf(".");
         j=0;
      }
      bme->dataLen = numread;
      bme->dataPtr = buf;
//      jagWriteBlock(bme->BmeNum,bme->destAddr,(U32)buf,numread);
//      if (bmeSoftwareDnld(bme) != HWAPI_DNLD_SUCCESS) {
//         printf("Error downloading file\n");
//      }
#if 1
      // check for data
      jagReadBlock(bme->BmeNum,(U32)buf1,bme->destAddr,numread);
      for (i=0;i<numread;i++) {
         if (buf1[i] != buf[i]) {
            EventLog("b%dp0 ...bmeSoftwareDnld: Error writing code into memory 0x%lx!", bme->BmeNum, codeDnldAddr);
            printf("\nDownload error at %lx - expect %x, actual %x\n",
                                                      bme->destAddr + i,
                                                      buf[i],buf1[i]);
            goto bail;
         }
      }
#endif
      bme->destAddr += numread;
   }
   if (bme->destAddr == codeDnldAddr) {
      printf("\nError downloading file\n");
      return;
   }

   bme->destAddr = codeDnldAddr;
#else
   {
	  int iCounter1 = 0, iCounter2 = 0
   do {
      if ((i++ & 0x3F) == 0)
         printf(".");
      /* transmit data to BME memory */
      bme->destAddr = codeDnldAddr;
      bme->dataLen = numread;
      bme->dataPtr = buf;
      if (DoTxCmd(bme) != HWAPI_WRITE_SUCCESS) {
         iCounter1++;
         if (iCounter1 < MAX_WAIT_COUNT)                   /* wait for success for 16 times */
            continue;
         else {
            fclose(fp);
            EventLog("b%dp0 ...bmeSoftwareDnld: Error writing code into memory 0x%lx!", bme->BmeNum, codeDnldAddr);
            bme->dataPtr = &bme->BmeMsg[0];
            return;
         }
      } else {
         iCounter1 = 0;

         while (1) {
            /* wait for DW_H status bit to be set to indicate DMA Write is done */
            if (bmePollDmaStatus(bme) == DMA_DONE) {
               iCounter2 = 0;
               break;
            } else {
               /* keep a counter or timer. If timer value times out the max wait time, break from the loop & report a failure to the
                * api. */
               iCounter2++;
               if (iCounter2 < MAX_WAIT_COUNT)             /* wait for 16/256 times */
                  iposDelay();
               else {
                  fclose(fp);
                  EventLog("b%dp0 ...bmeSoftwareDnld: Error dma not done while downloading BME code!", bme->BmeNum);
                  bme->dataPtr = &bme->BmeMsg[0];
                  return;
               }
            }
         }

         /* if DW_T bit is set by DMA controller, change the BmeDnldVerifyState from DW_T_BIT_RESET to DW_T_BIT_SET */
         if (bme->BmeDnldVerifyState == DW_T_BIT_RESET) {
            /* check the status[1] (DW_T) bit of DMA Status Port to be one. This indicates data is transferred from the fifo to BME
             * memory. */
            if (bmeRdStatus(bme) & DW_T_DMA_WRITE_DONE)
               bme->BmeDnldVerifyState = DW_T_BIT_SET;
         }
         /* This code reads back each block of written data & checks for written data validity. It compares each read byte with each
          * write byte & gives an error, if both are not matching */

         if (bmeVerifyWriteCode(bme, codeDnldAddr, numread, buf) !=
             HWAPI_CODE_CHKSUM_SUCCESS) {
            fclose(fp);
            EventLog("b%d,p0 ...bmeSoftwareDnld: Error while reading data.\n",
                     bme->BmeNum);
            return;
         }
      }

      codeDnldAddr += numread;                             /* increment the code download addr */
   } while ((numread = fread(buf, sizeof(char), MAX_DATA_LENGTH + 1, fp)) > 0);
   }
#endif
   EventLog("Bme software code downloaded successfully");
   printf("\n************************************");
   printf("\nDownload completed successfully!");
   printf("\n************************************\n");

bail:
#ifdef USE_TARGET_SERVER
   fclose(fp);
#endif
#ifdef USE_FTP
   close (dataSock);
   ftpCommand (ctrlSock, "QUIT", 0, 0, 0, 0, 0, 0);
   close (ctrlSock);
#endif


   /* change the BmeState from SW_DNLD_IN_PROGRESS to SW_DNLD_DONE */
   bme->BmeState = SW_DNLD_DONE;
   bme->dataPtr = &bme->BmeMsg[0];

   /* 5. set production mode to development */
   setProdMode(iMode);

   /* 6. release cpu - ReleaseBmeCpu - active state */
   bmeRelCpu(bme, TRUE);                                   /* release BME cpu */

#ifdef EMUL
	printf("\nStart the target board. When done, press 'return'. \n");
	gets (buf);
#endif
   oampBmeStateUpdate(1, eBME_START);

   iposStateUpdate(&apiBme[1], IPOS_BME_STARTED);

/*	iniwrite (0x1,0x15);
   iniwrite (0x7,0x1);
   iniwrite (0x3,0x80);
*/

#ifdef	BME_CPE_20
   HostFpgaWrite(0x07, 0x01);
#endif

   return;

#endif // bup_diags

}

#endif // CPE_40

// Function to Download a new FW in BME
// Uses the Host download function

#include <ioLib.h>
extern BYTE BMECodeArray[];
#define MAX_FW_CODE_SIZE	(1024*1024)

void putfw(int bmeNum)
{
   int fp;
   int fileLen;

   /* Open Bme code binary file */
   if ((fp = open("/tgtsvr/vxWorks.bin", 0x202, 0777)) == -1) {
      printf("\nUnable to open \"/tgtsvr/vxWorks.bin\"");
      return;
   }
   printf("\nReading...");

   fileLen = read(fp, BMECodeArray, MAX_FW_CODE_SIZE);
   printf("\nRead %d", fileLen);

   close(fp);

   if (!bmeNum)
      bmeNum = 1;

   BmeStruct[bmeNum].BMECodeSize = fileLen;

   BmeStruct[bmeNum].BmeState = INACTIVE;
   bmeDnldProcedure(&BmeStruct[bmeNum]);

   oampBmeStateUpdate(bmeNum, eBME_START);

   iposStateUpdate(&apiBme[bmeNum], IPOS_BME_STARTED);

   printf("\nDone");
}

#endif /* TEST_LEVEL > 0 */
