Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 60800abd authored by Stas Sergeev's avatar Stas Sergeev Committed by Greg Kroah-Hartman
Browse files

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: default avatarStas Sergeev <stsp@users.sourceforge.net>
Signed-off-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f87028f4
Loading
Loading
Loading
Loading
+44 −36
Original line number Diff line number Diff line
@@ -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;
}

+6 −0
Original line number Diff line number Diff line
@@ -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;
+0 −11
Original line number Diff line number Diff line
@@ -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 {
+4 −0
Original line number Diff line number Diff line
@@ -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;