diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index 13c06196073c..f9d5558431e0 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -584,6 +584,45 @@ static s32 _FWFreeToGo(struct adapter *padapter) #define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0) +static int load_firmware(struct rt_firmware *pFirmware, struct device *device) +{ + int rtstatus = _SUCCESS; + const struct firmware *fw; + const char fw_name[] = "rtlwifi/rtl8188eufw.bin"; + + if (request_firmware(&fw, fw_name, device)) { + rtstatus = _FAIL; + goto exit; + } + if (!fw) { + pr_err("Firmware %s not available\n", fw_name); + rtstatus = _FAIL; + goto exit; + } + if (fw->size > FW_8188E_SIZE) { + rtstatus = _FAIL; + RT_TRACE(_module_hal_init_c_, _drv_err_, + ("Firmware size exceed 0x%X. Check it.\n", + FW_8188E_SIZE)); + goto exit; + } + + pFirmware->szFwBuffer = kzalloc(FW_8188E_SIZE, GFP_KERNEL); + if (!pFirmware->szFwBuffer) { + rtstatus = _FAIL; + goto exit; + } + memcpy(pFirmware->szFwBuffer, fw->data, fw->size); + pFirmware->ulFwLength = fw->size; + release_firmware(fw); + + DBG_88E_LEVEL(_drv_info_, + "+%s: !bUsedWoWLANFw, FmrmwareLen:%d+\n", __func__, + pFirmware->ulFwLength); +exit: + return rtstatus; +} + s32 rtl8188e_FirmwareDownload(struct adapter *padapter) { s32 rtStatus = _SUCCESS; @@ -592,51 +631,23 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter) struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); struct device *device = dvobj_to_dev(dvobj); - struct rt_firmware *pFirmware = NULL; - const struct firmware *fw; struct rt_firmware_hdr *pFwHdr = NULL; u8 *pFirmwareBuf; u32 FirmwareLen; - char fw_name[] = "rtlwifi/rtl8188eufw.bin"; static int log_version; RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__)); - pFirmware = (struct rt_firmware *)rtw_zmalloc(sizeof(struct rt_firmware)); - if (!pFirmware) { - rtStatus = _FAIL; + if (!dvobj->firmware.szFwBuffer) + rtStatus = load_firmware(&dvobj->firmware, device); + if (rtStatus == _FAIL) { + dvobj->firmware.szFwBuffer = NULL; goto Exit; } - - if (request_firmware(&fw, fw_name, device)) { - rtStatus = _FAIL; - goto Exit; - } - if (!fw) { - pr_err("Firmware %s not available\n", fw_name); - rtStatus = _FAIL; - goto Exit; - } - if (fw->size > FW_8188E_SIZE) { - rtStatus = _FAIL; - RT_TRACE(_module_hal_init_c_, _drv_err_, ("Firmware size exceed 0x%X. Check it.\n", FW_8188E_SIZE)); - goto Exit; - } - - pFirmware->szFwBuffer = kzalloc(FW_8188E_SIZE, GFP_KERNEL); - if (!pFirmware->szFwBuffer) { - rtStatus = _FAIL; - goto Exit; - } - memcpy(pFirmware->szFwBuffer, fw->data, fw->size); - pFirmware->ulFwLength = fw->size; - pFirmwareBuf = pFirmware->szFwBuffer; - FirmwareLen = pFirmware->ulFwLength; - release_firmware(fw); - - DBG_88E_LEVEL(_drv_info_, "+%s: !bUsedWoWLANFw, FmrmwareLen:%d+\n", __func__, FirmwareLen); + pFirmwareBuf = dvobj->firmware.szFwBuffer; + FirmwareLen = dvobj->firmware.ulFwLength; /* To Check Fw header. Added by tynli. 2009.12.04. */ - pFwHdr = (struct rt_firmware_hdr *)pFirmware->szFwBuffer; + pFwHdr = (struct rt_firmware_hdr *)dvobj->firmware.szFwBuffer; pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version); pHalData->FirmwareSubVersion = pFwHdr->Subversion; @@ -688,10 +699,7 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter) goto Exit; } RT_TRACE(_module_hal_init_c_, _drv_info_, ("Firmware is ready to run!\n")); - kfree(pFirmware->szFwBuffer); Exit: - - kfree(pFirmware); return rtStatus; } diff --git a/drivers/staging/rtl8188eu/include/drv_types.h b/drivers/staging/rtl8188eu/include/drv_types.h index a492a1c547ae..936c196699af 100644 --- a/drivers/staging/rtl8188eu/include/drv_types.h +++ b/drivers/staging/rtl8188eu/include/drv_types.h @@ -159,9 +159,15 @@ struct registry_priv { #define MAX_CONTINUAL_URB_ERR 4 +struct rt_firmware { + u8 *szFwBuffer; + u32 ulFwLength; +}; + struct dvobj_priv { struct adapter *if1; struct adapter *if2; + struct rt_firmware firmware; /* For 92D, DMDP have 2 interface. */ u8 InterfaceNumber; diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h index 161f1e5af9e6..75e41c4aeb27 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h @@ -76,17 +76,6 @@ (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x2300 || \ (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88E0) -enum firmware_source { - FW_SOURCE_IMG_FILE = 0, - FW_SOURCE_HEADER_FILE = 1, /* from header file */ -}; - -struct rt_firmware { - enum firmware_source eFWSource; - u8 *szFwBuffer; - u32 ulFwLength; -}; - /* This structure must be careful with byte-ordering */ struct rt_firmware_hdr { diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index bc9ae1df7bd5..f123a930c012 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -1204,6 +1204,7 @@ int pm_netdev_open(struct net_device *pnetdev, u8 bnormal) int netdev_close(struct net_device *pnetdev) { struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+88eu_drv - drv_close\n")); @@ -1242,6 +1243,9 @@ int netdev_close(struct net_device *pnetdev) rtw_p2p_enable(padapter, P2P_ROLE_DISABLE); #endif /* CONFIG_88EU_P2P */ + kfree(dvobj->firmware.szFwBuffer); + dvobj->firmware.szFwBuffer = NULL; + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-88eu_drv - drv_close\n")); DBG_88E("-88eu_drv - drv_close, bup =%d\n", padapter->bup); return 0;