From: Stas Sergeev Date: Fri, 14 Feb 2014 22:54:17 +0000 (-0600) Subject: staging: r8188eu: Make firmware buffer persistent X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=60800abdc147ba034204408cc4745d66e1ffbb8e;p=linux-beck.git staging: r8188eu: Make firmware buffer persistent The present code reloads the firmware file from the disk every time the interface re-inits. Change to hold the firmware in memory, and only download to the device. Signed-off-by: Stas Sergeev Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- 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,59 +584,70 @@ static s32 _FWFreeToGo(struct adapter *padapter) #define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0) -s32 rtl8188e_FirmwareDownload(struct adapter *padapter) +static int load_firmware(struct rt_firmware *pFirmware, struct device *device) { - s32 rtStatus = _SUCCESS; - u8 writeFW_retry = 0; - u32 fwdl_start_time; - 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; + int rtstatus = _SUCCESS; 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; - goto Exit; - } + const char fw_name[] = "rtlwifi/rtl8188eufw.bin"; if (request_firmware(&fw, fw_name, device)) { - rtStatus = _FAIL; - goto Exit; + rtstatus = _FAIL; + goto exit; } if (!fw) { pr_err("Firmware %s not available\n", fw_name); - rtStatus = _FAIL; - goto Exit; + 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; + 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; + 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); + 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; + u8 writeFW_retry = 0; + u32 fwdl_start_time; + 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_hdr *pFwHdr = NULL; + u8 *pFirmwareBuf; + u32 FirmwareLen; + static int log_version; + + RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__)); + if (!dvobj->firmware.szFwBuffer) + rtStatus = load_firmware(&dvobj->firmware, device); + if (rtStatus == _FAIL) { + dvobj->firmware.szFwBuffer = NULL; + goto Exit; + } + 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;