📄 cf_util.c
字号:
// Bootloader sets scratch to 0xAA to acknowledge the load of this block
// Busywait till this has happened
firmwareDelay = 0; // reset loop counter
do{
#ifdef POCKETPC_FIX
{
USHORT usTemp;
NdisRawReadPortUshort(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT - 1,
&usTemp);
ucTempUchar = (UCHAR)(usTemp >> 8 );
}
#else
NdisRawReadPortUchar(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT,
&ucTempUchar);
#endif // POCKETPC_FIX
if( ucTempUchar == 0xAA ) break;
NdisStallExecution(10);
firmwareDelay++;
} while ( (ucTempUchar != 0xAA) && (firmwareDelay < FWBLOCK_DELAY) );
if ( firmwareDelay >= FWBLOCK_DELAY )
{
{
wchar_t buf[100];
USHORT usTemp;
NdisRawReadPortUshort(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT - 1,
&usTemp);
ucTempUchar = (UCHAR)(usTemp >> 8 );
#ifdef UNDER_CE
swprintf(buf, TEXT("Downloading FW died on block %d, usTemp = %x, scratch register = %x\n"),
blockCount,usTemp,ucTempUchar);
//MessageBox(NULL, buf, TEXT("MrvDrvND5 IsFwLoaded"), MB_OK);
#endif // UNDER_CE
}
DBGPRINT(DBG_FWDL,("Downloading FW died on block %d\n",blockCount));
#if DBG
// DANGER _asm int 3;
#endif
return NDIS_STATUS_FAILURE;
}
sizeSend += sizeBlock;
}
#ifdef POCKETPC_FIX
// Set scratch register to 0x00 (firmware transfer complete)
NdisRawWritePortUshort( pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT-1, 0x0000);
#else
// Set scratch register to 0x00 (firmware transfer complete)
NdisRawWritePortUchar( pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT, 0x00);
#endif // POCKETPC_FIX
// Marvell's CE workaround for inability to do byte writes. - back up a reg
// and do a word write.
// NOTE: this should probably be changed to r/w modify to perserve the contents
// of 0x3E.
#ifdef UNDER_CE
// Set scratch register to 0x00 (firmware transfer complete)
NdisRawWritePortUshort( pCf -> ulMrvDrvVirtualIoBase +0x3E, 0x0000);
#endif
// Assert the Command Download Over interrupt
NdisRawWritePortUchar(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_STATUS,
CFMACREG_HCR_HS_CmdDnLdOvr);
NdisRawWritePortUshort(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_CARD_INT_CAUSE,
CFMACREG_HCR_CIC_CmdDnLdOvr);
DBGPRINT(DBG_FWDL,("Waiting for FW initialization event\n"));
// Wait for FW initialization finished event
firmwareDelay = 0; // reset loop counter
do {
#ifdef POCKETPC_FIX
{
USHORT usTemp;
NdisRawReadPortUshort(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT - 1,
&usTemp);
ucTempUchar = (UCHAR)(usTemp >> 8 );
}
#else
NdisRawReadPortUchar(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT,
&ucTempUchar);
#endif // POCKETPC_FIX
if( ucTempUchar == 0x5A )
break;
NdisMSleep(50);
firmwareDelay++;
DBGPRINT(DBG_FWDL,("."));
} while ( (ucTempUchar != 0x5A) && (firmwareDelay < FWDELAY ));
DBGPRINT(DBG_FWDL | DBG_RAW,("\n"));
if ( firmwareDelay >= FWDELAY )
{
#ifdef UNDER_CE
{
wchar_t buf[100];
swprintf(buf, TEXT("INIT - CF card failed to start!\n"));
//MessageBox(NULL, buf, TEXT("MrvDrvND5 IsFwLoaded"), MB_OK);
}
#endif // UNDER_CE
DBGPRINT(DBG_FWDL,("INIT - CF card failed to start!\n"));
return NDIS_STATUS_FAILURE;
}
DBGPRINT(DBG_FWDL,("CF started in less than %d ms.\n",firmwareDelay*50));
DBGPRINT(DBG_FWDL,("INIT - Firmware download end\n"));
return NDIS_STATUS_SUCCESS;
}
//************************************************************************************
//* Function: cf_HostBootFirmwareDownload
//* Description: Downloads firmware image to device over compact flash interface.
//* Returns IX_STATUS_SUCCESS if all OK. IX_STATUS_FAILURE if any problems.
//* NOTE: Please notice that the paramter is the mask of interrupts to disable.
//* Routine will only disable the interrupts specified in the mask
//* Date:
//************************************************************************************
IX_STATUS
cf_HostBootFirmwareDownload(
PCF_OBJECT pCf,
IN PMRVDRV_ADAPTER Adapter
)
{
UINT blockCount = 0;
UINT sizeOfFirmware=0;
UINT sizeSend = 0;
UINT sizeBlockInUshort;
UINT cmdIOaddr;
USHORT i, sizeBlock, *pusPtr;
// USHORT usTempUshort;
UCHAR ucTempUchar;
ULONG firmwareDelay = 0;
PHostCmd_DS_GEN ptrHead;
// ULONG intCode;
CmdCtrlNode *pourNode;
DBGPRINT(DBG_FWDL,("INIT - Firmware download start using HOSTBOOT\n"));
sizeOfFirmware = sizeof(fmimage);
pourNode = GetFreeCmdCtrlNode(Adapter); // We need only one
ptrHead = (PHostCmd_DS_GEN) pourNode->BufVirtualAddr;
//
// 05/01/03 - New FW download code - GLA
//
cmdIOaddr = pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_IO_CMD_WRITE_PORT; // output address
while (sizeSend <= sizeOfFirmware)
{
/*
Mode 2, CF
1) Prepare a raw fw packet for download
2) Wait on CARD_STATUS to have bit 2 set.
3) write the packet length to IO_CMD_WR_LENGTH
4) Write the packet byte for byte to IO_CMD_WR_PORT
5) Write bit 2 of HOST_STATUS
6) Write bit 2 of CARD_INTR_CAUSE
7) Wait on bit 2 of the CARD_STATUS
8) Repeat, when done write a LENGTH of 0.
*/
blockCount++;
sizeBlock = 256;
// Move the data from firmware buf to the command header
NdisMoveMemory(ptrHead, &fmimage[sizeSend], sizeBlock);
// Get number of ushorts
sizeBlockInUshort = (sizeBlock + 1) / 2;
pusPtr = (PUSHORT)(ptrHead);
// Write number of bytes to be sent
NdisRawWritePortUshort(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_HCR_IO_CMD_WRITE_LEN,
sizeBlockInUshort*2);
for(i=0; i<sizeBlockInUshort; i++ )
{
NdisRawWritePortUshort(cmdIOaddr,*pusPtr);
pusPtr++;
#ifdef FLUSH_FIFOS
// PDM: After writing every 16th word, flush the fifos.
// we don't want to do it when i=0, but when i=15
if ( ((i+1)&0x000f) == 0 )
{
DBGPRINT(DBG_FWDL,("Flushing FIFOs\n"));
NdisRawWritePortUshort(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_STATUS,
CFMACREG_HCR_HS_FlushDataFifo);
}
#endif // end of FLUSH_FIFOS
}
// PDM: When we're done, flush the FIFOs.
DBGPRINT(DBG_FWDL,("Flushing FIFOs\n"));
NdisRawWritePortUshort(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_STATUS,
CFMACREG_HCR_HS_FlushDataFifo);
DBGPRINT(DBG_FWDL,("Downloaded Block %d of Firmware, blockSize = %d, Total size so far= %d\n",
blockCount, sizeBlockInUshort*2, sizeSend));
// Assert the Command Download Over interrupt
NdisRawWritePortUchar(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_STATUS,
CFMACREG_HCR_HS_CmdDnLdOvr);
NdisRawWritePortUshort(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_CARD_INT_CAUSE,
CFMACREG_HCR_CIC_CmdDnLdOvr);
// 7) Wait on bit 2 of the CARD_STATUS
firmwareDelay = 0; // reset loop counter
do{
NdisRawReadPortUchar(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_CARD_STATUS,
&ucTempUchar);
if( ucTempUchar == CFMACREG_CCR_CS_CmdDnLdRdy )
{
break;
}
NdisStallExecution(10);
firmwareDelay++;
} while ( (ucTempUchar != MRVDRV_FW_DL_RDY_FOR_NEXT_BLOCK ) && (firmwareDelay < FWBLOCK_DELAY) );
if ( firmwareDelay >= FWBLOCK_DELAY )
{
DBGPRINT(DBG_FWDL,("Downloading FW died on block %d\n",blockCount));
return NDIS_STATUS_FAILURE;
}
DBGPRINT(DBG_FWDL,("Ready for next block after less than %d ms\n", firmwareDelay*10));
sizeSend += sizeBlock;
}
//8) Repeat, when done write a LENGTH of 0.
NdisRawWritePortUshort( pCf -> ulMrvDrvVirtualIoBase +
CFMACREG_HCR_IO_CMD_WRITE_LEN, 0x00);
// is flushing IO necessary?
DBGPRINT(DBG_FWDL,("Flushing FIFOs\n"));
NdisRawWritePortUshort(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_STATUS,
CFMACREG_HCR_HS_FlushDataFifo);
// Assert the Command Download Over interrupt
NdisRawWritePortUchar(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_STATUS,
CFMACREG_HCR_HS_CmdDnLdOvr);
NdisRawWritePortUshort(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_CARD_INT_CAUSE,
CFMACREG_HCR_CIC_CmdDnLdOvr);
DBGPRINT(DBG_FWDL,("Waiting for FW initialization event\n"));
// Wait for FW initialization finished event
firmwareDelay = 0; // reset loop counter
do {
#ifdef POCKETPC_FIX
{
USHORT usTemp;
NdisRawReadPortUshort(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT - 1,
&usTemp);
ucTempUchar = (UCHAR)(usTemp >> 8 );
}
#else
NdisRawReadPortUchar(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT,
&ucTempUchar);
#endif // POCKETPC_FIX
if( ucTempUchar == MRVDRV_FW_STATUS_READY )
break;
NdisMSleep(50);
firmwareDelay++;
DBGPRINT(DBG_FWDL,("."));
} while ( (ucTempUchar != 0x5A) && (firmwareDelay < FWDELAY ));
DBGPRINT(DBG_FWDL | DBG_RAW,("\n"));
{
USHORT usTemp;
NdisRawReadPortUshort(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_INT_MASK,
&usTemp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -