diff options
Diffstat (limited to 'drivers/staging/rtl8188eu/hal/fw.c')
-rw-r--r-- | drivers/staging/rtl8188eu/hal/fw.c | 50 |
1 files changed, 23 insertions, 27 deletions
diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 5163bf8d9..8e904bd8e 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -75,16 +75,6 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, usb_write8(adapt, write_address, byte_buffer[i]); } -static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -{ - u32 i; - - for (i = *pfwlen; i < roundup(*pfwlen, 4); i++) - pfwbuf[i] = 0; - - *pfwlen = i; -} - static void _rtl88e_fw_page_write(struct adapter *adapt, u32 page, const u8 *buffer, u32 size) { @@ -103,8 +93,6 @@ static void _rtl88e_write_fw(struct adapter *adapt, u8 *buffer, u32 size) u32 page_no, remain; u32 page, offset; - _rtl88e_fill_dummy(buf_ptr, &size); - page_no = size / FW_8192C_PAGE_SIZE; remain = size % FW_8192C_PAGE_SIZE; @@ -170,14 +158,14 @@ exit: int rtl88eu_download_fw(struct adapter *adapt) { - struct hal_data_8188e *rtlhal = GET_HAL_DATA(adapt); struct dvobj_priv *dvobj = adapter_to_dvobj(adapt); struct device *device = dvobj_to_dev(dvobj); const struct firmware *fw; const char fw_name[] = "/*(DEBLOBBED)*/"; struct rtl92c_firmware_header *pfwheader = NULL; - u8 *pfwdata; - u32 fwsize; + u8 *download_data, *fw_data; + size_t download_size; + unsigned int trailing_zeros_length; if (reject_firmware(&fw, fw_name, device)) { dev_err(device, "Firmware %s not available\n", fw_name); @@ -186,35 +174,43 @@ int rtl88eu_download_fw(struct adapter *adapt) if (fw->size > FW_8188E_SIZE) { dev_err(device, "Firmware size exceed 0x%X. Check it.\n", - FW_8188E_SIZE); + FW_8188E_SIZE); + release_firmware(fw); return -1; } - pfwdata = kzalloc(FW_8188E_SIZE, GFP_KERNEL); - if (!pfwdata) + 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; + } - rtlhal->pfirmware = pfwdata; - memcpy(rtlhal->pfirmware, fw->data, fw->size); - rtlhal->fwsize = fw->size; - release_firmware(fw); + memcpy(fw_data, fw->data, fw->size); + memset(fw_data + fw->size, 0, trailing_zeros_length); - fwsize = rtlhal->fwsize; - pfwheader = (struct rtl92c_firmware_header *)pfwdata; + pfwheader = (struct rtl92c_firmware_header *)fw_data; if (IS_FW_HEADER_EXIST(pfwheader)) { - pfwdata = pfwdata + 32; - fwsize = fwsize - 32; + 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, pfwdata, fwsize); + _rtl88e_write_fw(adapt, download_data, download_size); _rtl88e_enable_fw_download(adapt, false); + kfree(fw_data); return _rtl88e_fw_free_to_go(adapt); } |