int rtl88eu_download_fw(struct adapter *adapt) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapt); struct device *device = dvobj_to_dev(dvobj); const struct firmware *fw; const char fw_name[] = "rtlwifi/rtl8188eufw.bin"; struct rtl92c_firmware_header *pfwheader = NULL; u8 *download_data, *fw_data; size_t download_size; unsigned int trailing_zeros_length; if (request_firmware(&fw, fw_name, device)) { dev_err(device, "Firmware %s not available\n", fw_name); return -ENOENT; } if (fw->size > FW_8188E_SIZE) { dev_err(device, "Firmware size exceed 0x%X. Check it.\n", FW_8188E_SIZE); release_firmware(fw); return -1; } trailing_zeros_length = (4 - fw->size % 4) % 4; fw_data = kmalloc(fw->size + trailing_zeros_length, GFP_KERNEL); if (!fw_data) { release_firmware(fw); return -ENOMEM; } memcpy(fw_data, fw->data, fw->size); memset(fw_data + fw->size, 0, trailing_zeros_length); pfwheader = (struct rtl92c_firmware_header *)fw_data; if (IS_FW_HEADER_EXIST(pfwheader)) { download_data = fw_data + 32; download_size = fw->size + trailing_zeros_length - 32; } else { download_data = fw_data; download_size = fw->size + trailing_zeros_length; } release_firmware(fw); if (usb_read8(adapt, REG_MCUFWDL) & RAM_DL_SEL) { usb_write8(adapt, REG_MCUFWDL, 0); rtl88e_firmware_selfreset(adapt); } _rtl88e_enable_fw_download(adapt, true); usb_write8(adapt, REG_MCUFWDL, usb_read8(adapt, REG_MCUFWDL) | FWDL_ChkSum_rpt); _rtl88e_write_fw(adapt, download_data, download_size); _rtl88e_enable_fw_download(adapt, false); kfree(fw_data); return _rtl88e_fw_free_to_go(adapt); }
// // Description: // Download 8192C firmware code. // // int FirmwareDownload92C( IN PADAPTER Adapter ) { int rtStatus = _SUCCESS; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); char R92CFwImageFileName_TSMC[] ={RTL8192C_FW_TSMC_IMG}; char R92CFwImageFileName_UMC[] ={RTL8192C_FW_UMC_IMG}; char R8723FwImageFileName_UMC[] ={RTL8723_FW_UMC_IMG}; char * FwImage; u32 FwImageLen; char* pFwImageFileName; //vivi, merge 92c and 92s into one driver, 20090817 //vivi modify this temply, consider it later!!!!!!!! //PRT_FIRMWARE pFirmware = GET_FIRMWARE_819X(Adapter); //PRT_FIRMWARE_92C pFirmware = GET_FIRMWARE_8192C(Adapter); PRT_FIRMWARE_92C pFirmware = NULL; PRT_8192C_FIRMWARE_HDR pFwHdr = NULL; u8 *pFirmwareBuf; u32 FirmwareLen; pFirmware = (PRT_FIRMWARE_92C)_rtw_malloc(sizeof(RT_FIRMWARE_92C)); if(!pFirmware) { rtStatus = _FAIL; goto Exit; } //RT_TRACE(COMP_INIT, DBG_LOUD, (" ===> FirmwareDownload91C() fw:%s\n", pFwImageFileName)); #ifdef CONFIG_EMBEDDED_FWIMG pFirmware->eFWSource = FW_SOURCE_HEADER_FILE; #else pFirmware->eFWSource = FW_SOURCE_IMG_FILE; #endif if(IS_NORMAL_CHIP(pHalData->VersionID)) { if(IS_VENDOR_UMC_A_CUT(pHalData->VersionID) && !IS_92C_SERIAL(pHalData->VersionID))// UMC , 8188 { pFwImageFileName = R92CFwImageFileName_UMC; FwImage = Rtl819XFwUMCImageArray; FwImageLen = UMCImgArrayLength; DBG_871X(" ===> FirmwareDownload91C() fw:Rtl819XFwImageArray_UMC\n"); } else { pFwImageFileName = R92CFwImageFileName_TSMC; FwImage = Rtl819XFwTSMCImageArray; FwImageLen = TSMCImgArrayLength; DBG_871X(" ===> FirmwareDownload91C() fw:Rtl819XFwImageArray_TSMC\n"); } } else { #if 0 pFwImageFileName = TestChipFwFile; FwImage = Rtl8192CTestFwImg; FwImageLen = Rtl8192CTestFwImgLen; RT_TRACE(COMP_INIT, DBG_LOUD, (" ===> FirmwareDownload91C() fw:Rtl8192CTestFwImg\n")); #endif } switch(pFirmware->eFWSource) { case FW_SOURCE_IMG_FILE: //TODO:load fw bin file break; case FW_SOURCE_HEADER_FILE: if(TSMCImgArrayLength > FW_8192C_SIZE){ rtStatus = _FAIL; //RT_TRACE(COMP_INIT, DBG_SERIOUS, ("Firmware size exceed 0x%X. Check it.\n", FW_8192C_SIZE) ); DBG_871X("Firmware size exceed 0x%X. Check it.\n", FW_8192C_SIZE); goto Exit; } _rtw_memcpy(pFirmware->szFwBuffer, FwImage, FwImageLen); pFirmware->ulFwLength = FwImageLen; break; } pFirmwareBuf = pFirmware->szFwBuffer; FirmwareLen = pFirmware->ulFwLength; // To Check Fw header. pFwHdr = (PRT_8192C_FIRMWARE_HDR)pFirmware->szFwBuffer; pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version); pHalData->FirmwareSubVersion = le16_to_cpu(pFwHdr->Subversion); //RT_TRACE(COMP_INIT, DBG_LOUD, (" FirmwareVersion(%#x), Signature(%#x)\n", // Adapter->MgntInfo.FirmwareVersion, pFwHdr->Signature)); DBG_8192C("fw_ver=v%d, fw_subver=%d, sig=0x%x\n", pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, le16_to_cpu(pFwHdr->Signature)&0xFFF0); if(IS_FW_HEADER_EXIST(pFwHdr)) { //RT_TRACE(COMP_INIT, DBG_LOUD,("Shift 32 bytes for FW header!!\n")); pFirmwareBuf = pFirmwareBuf + 32; FirmwareLen = FirmwareLen -32; } // Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, // or it will cause download Fw fail. 2010.02.01. by tynli. if(rtw_read8(Adapter, REG_MCUFWDL)&BIT7) //8051 RAM code { DBG_8192C("8051 in Ram......prepare to reset by itself\n"); _FirmwareSelfReset(Adapter); rtw_write8(Adapter, REG_MCUFWDL, 0x00); } _FWDownloadEnable(Adapter, _TRUE); _WriteFW(Adapter, pFirmwareBuf, FirmwareLen); _FWDownloadEnable(Adapter, _FALSE); rtStatus = _FWFreeToGo(Adapter); if(_SUCCESS != rtStatus){ //RT_TRACE(COMP_INIT, DBG_SERIOUS, ("DL Firmware failed!\n") ); goto Exit; } //RT_TRACE(COMP_INIT, DBG_LOUD, (" Firmware is ready to run!\n")); Exit: if(pFirmware) _rtw_mfree((u8*)pFirmware, sizeof(RT_FIRMWARE_92C)); //RT_TRACE(COMP_INIT, DBG_LOUD, (" <=== FirmwareDownload91C()\n")); return rtStatus; }