staging: r8188eu: Make firmware buffer persistent
authorStas Sergeev <stsp@users.sourceforge.net>
Fri, 14 Feb 2014 22:54:17 +0000 (16:54 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 15 Feb 2014 20:40:19 +0000 (12:40 -0800)
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 <stsp@users.sourceforge.net>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
drivers/staging/rtl8188eu/include/drv_types.h
drivers/staging/rtl8188eu/include/rtl8188e_hal.h
drivers/staging/rtl8188eu/os_dep/os_intfs.c

index 13c06196073c56bb7f086a2b55a6f67ea82236fe..f9d5558431e0c7558394289215111f0c9d161262 100644 (file)
@@ -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;
 }
 
index a492a1c547aee73375809fe338c8024bc4d0fe9a..936c196699af6b8525ad11f9be1e71a4de0b393b 100644 (file)
@@ -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;
index 161f1e5af9e6ae80ee541d59c6b3e58ba9488528..75e41c4aeb279fd119b8a17424e1af5138970dc4 100644 (file)
        (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 {
index bc9ae1df7bd5940a07a01e7e938dc2dd9abd42bb..f123a930c012c790b1b652b05ae536249d225e0a 100644 (file)
@@ -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;