Release 4.11 drivers/staging/rtl8188eu/hal/fw.c
/******************************************************************************
*
* Copyright(c) 2009-2013 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "fw.h"
#include "drv_types.h"
#include "usb_ops_linux.h"
#include "rtl8188e_spec.h"
#include "rtl8188e_hal.h"
#include <linux/firmware.h>
#include <linux/kmemleak.h>
static void _rtl88e_enable_fw_download(struct adapter *adapt, bool enable)
{
u8 tmp;
if (enable) {
tmp = usb_read8(adapt, REG_MCUFWDL);
usb_write8(adapt, REG_MCUFWDL, tmp | 0x01);
tmp = usb_read8(adapt, REG_MCUFWDL + 2);
usb_write8(adapt, REG_MCUFWDL + 2, tmp & 0xf7);
} else {
tmp = usb_read8(adapt, REG_MCUFWDL);
usb_write8(adapt, REG_MCUFWDL, tmp & 0xfe);
usb_write8(adapt, REG_MCUFWDL + 1, 0x00);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Navin Patidar | 101 | 100.00% | 1 | 100.00% |
Total | 101 | 100.00% | 1 | 100.00% |
static void _rtl88e_fw_block_write(struct adapter *adapt,
const u8 *buffer, u32 size)
{
u32 blk_sz = sizeof(u32);
const u8 *byte_buffer;
const u32 *dword_buffer = (u32 *)buffer;
u32 i, write_address, blk_cnt, remain;
blk_cnt = size / blk_sz;
remain = size % blk_sz;
write_address = FW_8192C_START_ADDRESS;
for (i = 0; i < blk_cnt; i++, write_address += blk_sz)
usb_write32(adapt, write_address, dword_buffer[i]);
byte_buffer = buffer + blk_cnt * blk_sz;
for (i = 0; i < remain; i++, write_address++)
usb_write8(adapt, write_address, byte_buffer[i]);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Navin Patidar | 102 | 76.69% | 1 | 9.09% |
Ivan Safonov | 31 | 23.31% | 10 | 90.91% |
Total | 133 | 100.00% | 11 | 100.00% |
static void _rtl88e_fw_page_write(struct adapter *adapt,
u32 page, const u8 *buffer, u32 size)
{
u8 value8;
u8 u8page = (u8)(page & 0x07);
value8 = (usb_read8(adapt, REG_MCUFWDL + 2) & 0xF8) | u8page;
usb_write8(adapt, (REG_MCUFWDL + 2), value8);
_rtl88e_fw_block_write(adapt, buffer, size);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Navin Patidar | 76 | 100.00% | 1 | 100.00% |
Total | 76 | 100.00% | 1 | 100.00% |
static void _rtl88e_write_fw(struct adapter *adapt, u8 *buffer, u32 size)
{
u8 *buf_ptr = buffer;
u32 page_no, remain;
u32 page, offset;
page_no = size / FW_8192C_PAGE_SIZE;
remain = size % FW_8192C_PAGE_SIZE;
for (page = 0; page < page_no; page++) {
offset = page * FW_8192C_PAGE_SIZE;
_rtl88e_fw_page_write(adapt, page, (buf_ptr + offset),
FW_8192C_PAGE_SIZE);
}
if (remain) {
offset = page_no * FW_8192C_PAGE_SIZE;
page = page_no;
_rtl88e_fw_page_write(adapt, page, (buf_ptr + offset), remain);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Navin Patidar | 113 | 100.00% | 1 | 100.00% |
Total | 113 | 100.00% | 1 | 100.00% |
static void rtl88e_firmware_selfreset(struct adapter *adapt)
{
u8 u1b_tmp;
u1b_tmp = usb_read8(adapt, REG_SYS_FUNC_EN+1);
usb_write8(adapt, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2))));
usb_write8(adapt, REG_SYS_FUNC_EN+1, (u1b_tmp | BIT(2)));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Navin Patidar | 64 | 100.00% | 1 | 100.00% |
Total | 64 | 100.00% | 1 | 100.00% |
static int _rtl88e_fw_free_to_go(struct adapter *adapt)
{
int err = -EIO;
u32 counter = 0;
u32 value32;
do {
value32 = usb_read32(adapt, REG_MCUFWDL);
if (value32 & FWDL_ChkSum_rpt)
break;
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
if (counter >= POLLING_READY_TIMEOUT_COUNT)
goto exit;
value32 = usb_read32(adapt, REG_MCUFWDL);
value32 |= MCUFWDL_RDY;
value32 &= ~WINTINI_RDY;
usb_write32(adapt, REG_MCUFWDL, value32);
rtl88e_firmware_selfreset(adapt);
counter = 0;
do {
value32 = usb_read32(adapt, REG_MCUFWDL);
if (value32 & WINTINI_RDY) {
err = 0;
goto exit;
}
udelay(FW_8192C_POLLING_DELAY);
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
exit:
return err;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Navin Patidar | 142 | 100.00% | 1 | 100.00% |
Total | 142 | 100.00% | 1 | 100.00% |
int rtl88eu_download_fw(struct adapter *adapt)
{
struct dvobj_priv *dvobj = adapter_to_dvobj(adapt);
struct device *device = dvobj_to_dev(dvobj);
const struct firmware *fw;
const char fw_name[] = "rtlwifi/rtl8188eufw.bin";
struct rtl92c_firmware_header *pfwheader = NULL;
u8 *download_data, *fw_data;
size_t download_size;
unsigned int trailing_zeros_length;
if (request_firmware(&fw, fw_name, device)) {
dev_err(device, "Firmware %s not available\n", fw_name);
return -ENOENT;
}
if (fw->size > FW_8188E_SIZE) {
dev_err(device, "Firmware size exceed 0x%X. Check it.\n",
FW_8188E_SIZE);
release_firmware(fw);
return -1;
}
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;
}
memcpy(fw_data, fw->data, fw->size);
memset(fw_data + fw->size, 0, trailing_zeros_length);
pfwheader = (struct rtl92c_firmware_header *)fw_data;
if (IS_FW_HEADER_EXIST(pfwheader)) {
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, download_data, download_size);
_rtl88e_enable_fw_download(adapt, false);
kfree(fw_data);
return _rtl88e_fw_free_to_go(adapt);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Navin Patidar | 228 | 71.47% | 1 | 16.67% |
Ivan Safonov | 89 | 27.90% | 3 | 50.00% |
Amitoj Kaur Chawla | 1 | 0.31% | 1 | 16.67% |
Stephen Rothwell | 1 | 0.31% | 1 | 16.67% |
Total | 319 | 100.00% | 6 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Navin Patidar | 847 | 87.32% | 1 | 5.88% |
Ivan Safonov | 120 | 12.37% | 13 | 76.47% |
Stephen Rothwell | 1 | 0.10% | 1 | 5.88% |
Kyle Kuffermann | 1 | 0.10% | 1 | 5.88% |
Amitoj Kaur Chawla | 1 | 0.10% | 1 | 5.88% |
Total | 970 | 100.00% | 17 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.