📄 spiutil.c
字号:
NKDbgPrintfW(TEXT ("Helper Firmware download died ......\n")); return -1; } for(j=0;j<((firmwarelen-fwblknow)/2);++j) { dlimage[j] = firmware[index++]; dlimage[j] |= (firmware[index++] << 8); } gspi_write_data_direct(dlimage, CMD_RDWRPORT_REG, SPI_FW_DOWNLOAD_PKTCNT); spi_WriteRegister(HOST_INT_STATUS_REG, 0x0000); spi_WriteRegister(CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr); }*/ ///crlo:test -- /////////////// ////NKDbgPrintfW(TEXT ("\nDownload %d bytes of firmware\n",firmwarelen)); NKDbgPrintfW(TEXT("\nDownload %d bytes of helper firmware\r\n"),firmwarelen); /* Writing 0 to Scr1 is to indicate the end of Firmware dwld */ spi_WriteRegister(SCRATCH_1_REG, FIRMWARE_DNLD_END); spi_WriteRegister(HOST_INT_STATUS_REG, 0x0000); spi_WriteRegister(CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr); ret = 0; return ret;}static int sbi_download_wlan_fw_image(const u8 *firmware, int firmwarelen){ int ret,j, index = 0; u16 dlimage[1024]; u16 len; u32 cnt=0; DWORD dwTick1,dwTick2;// u32 dwTemp; int tmp=0; ////NKDbgPrintfW(TEXT ("WLAN_FW: Downloading firmware of size %d bytes\n", firmwarelen)); //NKDbgPrintfW(TEXT("WLAN_FW: Downloading firmware of size %d bytes\r\n!!"),firmwarelen); /* Wait initially for the first non-zero value */ do { tmp++; NdisStallExecution(10); // stall for 10 us spi_ReadRegister(SCRATCH_1_REG, &len); } while(!len); NKDbgPrintfW(TEXT ("(cnt, len)=(%d, %d)\r\n"), tmp, len); dwTick1 = GetTickCount(); for(;;) { ///memset(dlimage, 0, SPI_FW_DOWNLOAD_PKTCNT); memset(dlimage, 0, sizeof(dlimage)); if(!wait_for_hostintstatus()) { NKDbgPrintfW(TEXT ("Firmware download died ......\r\n")); return -1; } spi_ReadRegister(SCRATCH_1_REG, &len); //NKDbgPrintfW(TEXT ("len = %d\r\n"),len); cnt += len; if(!len) { NKDbgPrintfW(TEXT ("\nFirmware download complete \r\n")); break; } if(len & 1) { //NKDbgPrintfW(TEXT ("CRC Error\n")); len &= ~1; } else { ////NKDbgPrintfW(TEXT (".")); } //yz_change#if 1 for(j=0;j<(len/2);++j) { dlimage[j] = firmware[index++]; dlimage[j] |= (firmware[index++] << 8); }#else memcpy(dlimage, firmware+index, len); index += len;#endif ////NKDbgPrintfW(TEXT ("before download, Tick: %d\n"), GetTickCount()); //gspi_write_data_direct(dlimage, CMD_RDWRPORT_REG, len); gspi_write_data_direct(dlimage, CMD_RDWRPORT_REG, len); ////NKDbgPrintfW(TEXT ("After download, Tick: %d\r\n"), GetTickCount()); spi_WriteRegister(HOST_INT_STATUS_REG, 0x0000); spi_WriteRegister(CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr); } NKDbgPrintfW(TEXT ("Firmware Image of Size %d bytes downloaded, cnt %d\r\n"), firmwarelen, cnt); dwTick2 = GetTickCount(); //NKDbgPrintfW(TEXT ("Downloading performance : Tick1 =%d,Tick2=%d,Diff=%d,Total = %d bits/sec\r\n"), dwTick1,dwTick2,dwTick2-dwTick1,(firmwarelen*1000*8)/(dwTick2-dwTick1)); //NKDbgPrintfW(TEXT("Firmware Image of Size %d bytes downloaded, cnt %d\r\n!!"),firmwarelen,cnt); ret = 0; return ret;}IF_FW_STATUS spi_IsFirmwareLoaded( void* pSpiParam){ u32 scr4; gspi_read_reg32(SCRATCH_4_REG, &scr4); if(scr4 == FIRMWARE_DNLD_OK) { //NKDbgPrintfW(TEXT ("Firmware download successful !!!\n")); return FW_STATUS_INITIALIZED; } return FW_STATUS_UNINITIALIZED;}///////////////////////////////////////////////////////////////////// spi_IsFirmwareLoaded - check if FW has been loaded/initialized// Input: Adapter - Adapter context//// Output:// Returns: return SPI_FW_STATUS// Notes:///////////////////////////////////////////////////////////////////IF_FW_STATUS spi_FirmwareDownload( void *pSpiParam){ UINT blockCount = 0; UINT sizeOfHelper; UINT sizeSend = 0; ULONG firmwareDelay = 0;#define FWDELAY 200 // cycles should give us about 10 seconds#define FWBLOCK_DELAY 5000 // cycles for fw block delay./// #define fmimage fmimage_B0 ULONG loopCount;// Move from Linux int ixStatus; IF_FW_STATUS retStatus = FW_STATUS_UNINITIALIZED; u16 hicr; // disable interrupt before firmware download sbi_disable_host_int();//Download helper file sizeOfHelper = sizeof(helperimage); ////NKDbgPrintfW(TEXT("INIT - Helper, Helper size = %d bytes, packet cnt = %d bytes\n", sizeOfHelper, SPI_FW_DOWNLOAD_PKTCNT )); //NKDbgPrintfW(TEXT("INIT - Helper, Helper size = %d bytes, packet cnt = %d bytes\r\n"),sizeOfHelper, SPI_FW_DOWNLOAD_PKTCNT);// MessageBox(NULL, TEXT("Download Helper Now"), TEXT("SD25"), MB_OK); ixStatus= sbi_prog_firmware_image(helperimage, sizeof(helperimage)); if (ixStatus < 0) { NKDbgPrintfW(TEXT ("Bootloader Helper in invalid state[1]!\n")); goto end; } else { NKDbgPrintfW(TEXT ("Download Helper Img success!\r\n")); } //RETAILMSG(1, (TEXT("Download Helper Img success!\r\n"))); NdisMSleep(FMDN_DELAY); // Download Firmware ixStatus = sbi_download_wlan_fw_image(fmimage,sizeof(fmimage)); if (ixStatus < 0) { NKDbgPrintfW(TEXT ("Bootloader Helper in invalid state[2]!\r\n")); goto end; } else { NKDbgPrintfW(TEXT ("Download Firmware Image success!\r\n")); } //RETAILMSG(1, (TEXT("Download Firmware Image success!\r\n"))); NdisMSleep(FMDN_DELAY*10); // Check Firmware loopCount = PKT_WAIT_TIME; while ( loopCount != 0 ) { if ( spi_IsFirmwareLoaded(NULL) != FW_STATUS_INITIALIZED ) { // FW not ready loopCount--; NdisStallExecution(10); // stall for 10 us } else { // FW ready! //NKDbgPrintfW(TEXT("FW started SUCCESSFULLY\n")); RETAILMSG(1, (TEXT("FW_STATUS_INITIALIZED\r\n"))); retStatus = FW_STATUS_INITIALIZED; break; } }end: sbi_enable_host_int(); #if (USE_DEVIRQ == 0) ///g_fmDnRdy = TRUE; #endif ///USE_DEVIRQ spi_ReadRegister(HOST_INT_STATUS_REG, &hicr); spi_WriteRegister(HOST_INT_STATUS_REG, ~hicr); spi_ReadRegister(HOST_INT_STATUS_REG, &hicr); spi_ReadRegister(HOST_INT_CAUSE_REG, &hicr); if (retStatus == FW_STATUS_INITIALIZED) { NKDbgPrintfW(TEXT("==> FW started SUCCESSFULLY\r\n")); } else { NKDbgPrintfW(TEXT("==> FW downlod failed\r\n")); } return retStatus;}///////////////////////////////////////////////////////////////////// SPIDownloadPkt - download a SPI paket to FW// Input: Adapter - Adapter context// DownloadPkt - Pkt to be downloaded// Output:// Returns: SPI_API_STATUS code// Notes:///////////////////////////////////////////////////////////////////IF_FW_STATUS spi_DownloadPkt(IN void *pSpiParam, IN PSDIO_TX_PKT pDownloadPkt){ IF_FW_STATUS status; // intermediate status u16 writeReg; u8 intType; u16 nb; NdisAcquireSpinLock(&SpiLock); intType = pDownloadPkt->Type ? CIC_CmdDnLdOvr : CIC_TxDnLdOvr; writeReg = (pDownloadPkt->Type) ? CMD_RDWRPORT_REG : DATA_RDWRPORT_REG; nb = pDownloadPkt->Len; //if(nb & 0x0001) //nb += 1; /* If the bytes written is not a multiple of four then make it a multiple of four as the RWPORT is 4 byte aligned from the host *//* if(!(nb % 4)) gspi_write_data_direct((u8 *)(pDownloadPkt->Buf.CmdBuf), writeReg, (nb/2)+1); else gspi_write_data_direct((u8 *)(pDownloadPkt->Buf.CmdBuf), writeReg, (nb/2)+2);*/ ////NKDbgPrintfW(TEXT("%s\n"),TEXT("SPIDownloadPkt")); //if (pDownloadPkt->Buf.TxDataBuf.Wcb.PktLen < 100) {/* if (pDownloadPkt->Type == SPI_DATA_PKT) { //tt //NKDbgPrintfW(TEXT("DndPkt len = %d\n"),pDownloadPkt->Buf.TxDataBuf.Wcb.PktLen); nb += 2; //tt ////NKDbgPrintfW(TEXT("WcbPktLen = %d, nb=%d\n"),pDownloadPkt->Buf.TxDataBuf.Wcb.PktLen, nb); //tt //HexDump (0xffff,"DndPkt:",pDownloadPkt->Buf.TxDataBuf.Pkt,pDownloadPkt->Buf.TxDataBuf.Wcb.PktLen); }*/ //gspi_write_data_direct((u8 *)(pDownloadPkt), writeReg, nb); gspi_write_data_direct((u16 *)(pDownloadPkt->Buf.CmdBuf), writeReg, nb); spi_WriteRegister(CARD_INT_CAUSE_REG, intType); // record the first 32 bytes in case if the buffer needs to be resent //NdisMoveMemory(Adapter->LastFWBuffer, pDownloadPkt, 32); status = 0; NdisReleaseSpinLock(&SpiLock); return status;}#if 0int sbi_card_to_host(u32 type, u8 *payload){ int ret=0; u16 len; u16 intType=0, readReg; NdisAcquireSpinLock(&SpiLock); intType = type ? CIC_CmdUpLdOvr : CIC_RxUpLdOvr; readReg = type ? CMD_RDWRPORT_REG : DATA_RDWRPORT_REG; spi_ReadRegister((type) ? SCRATCH_2_REG : SCRATCH_1_REG, &len); if ( intType == MVMS_DAT ) { //lykao, 052405, begin if ( len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE ) { len=MRVDRV_ETH_RX_PACKET_BUFFER_SIZE; } if ( len < sizeof(RxPD)+14 ) { len = sizeof(RxPD)+14; } } if(len & 0x0001) len += 1; ////NKDbgPrintfW(TEXT("sbi_card_to_host len = %x \n"),len);/* if(!(len % 4)) gspi_read_data_direct(payload, readReg, (len/2)+1); else gspi_read_data_direct(payload, readReg, (len/2)+2);*/ gspi_read_data_direct(payload, readReg, (len)); spi_WriteRegister(CARD_INT_CAUSE_REG, intType); NdisReleaseSpinLock(&SpiLock); return (len);}#endif ///0/****************************************************************************** * * Name: EnableInterrupt() * * * Description: * This routine enables interrupts * * Arguments: * * Return Value: * * Notes: * *****************************************************************************/VOIDspi_EnableInterrupt(IN void *pSpiParam){#if 0 //chenglong UCHAR ucInterrupt;/*#ifdef PWARE_SDIO_INTR_MODIFICATIONS // There seems to be some problem with the doc in interrupt // mask register description. Mask 0 should unmask (enable) // the interrupt & mask 1 should mask (disable) the interrupt // The old code used 1 to enable and 0 to disable the mask; // thus, it might not be working. May be, for that reason // this fn was made a dummy (just returning without doining // anything) ucInterrupt = 0;#else // old code follows return; // write 1 to enable interrupt ucInterrupt = 1;#endif // PWARE_SDIO_INTR_MODIFICATIONS */ // unmask interrupt u16 hicr; spi_WriteRegister(HOST_INT_STATUS_MASK_REG, 0x1f); spi_ReadRegister(HOST_INT_CTRL_REG, &hicr); spi_WriteRegister(HOST_INT_CTRL_REG, hicr & ~(0x01e0));#endif sbi_enable_host_int();}/****************************************************************************** * * Name: DisableInterrupt() * * * Description: * This routine disables interrupts * * Arguments: * DriverObject - Pointer to driver object created by the system. * * Return Value: * * Notes: * *****************************************************************************/VOIDspi_DisableInterrupt( IN void *pSpiParam){#if 0 //chenglong UCHAR ucInterrupt;/*#ifdef PWARE_SDIO_INTR_MODIFICATIONS // There seems to be some problem with the doc in interrupt // mask register description. Mask 0 should unmask (enable) // the interrupt & mask 1 should mask (disable) the interrupt // The old code used 1 to enable and 0 to disable the mask; // thus, it might not be working. May be, for that reason // this fn was made a dummy (just returning without doining // anything) ucInterrupt = 1;#else // old code follows return; // write 0 to disable interrupt ucInterrupt = 0;#endif // PWARE_SDIO_INTR_MODIFICATIONS*/ spi_WriteRegister(HOST_INT_STATUS_MASK_REG, 0x00);#endif sbi_disable_host_int(); return;}IF_API_STATUS spi_GetLengthOfDataBlock( void *pSpiParam, USHORT *pLength ){ spi_ReadRegister(SCRATCH_1_REG, pLength); return IF_SUCCESS;}IF_API_STATUS spi_ExitDeepSleep(void){ /* set Wakeup bit */ return spi_WriteRegister(HOST_INT_CTRL_REG, HIC_DEFAULT_VALUE | HIC_WakeUp);}// 36.p4 : Fix for deepsleep +++IF_API_STATUS spi_ResetDeepSleep(void){ /* clear Wakeup bit */ return spi_WriteRegister(HOST_INT_CTRL_REG, HIC_DEFAULT_VALUE & (~HIC_WakeUp));}// 36.p4 : Fix for deepsleep ---#if PXA270_SPIint gspi_read_intstatue(){ return pxa_read_intstate(ssphc);}#endif ///PXA270_SPI#endif // IF_GSPI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -