static int rtl8xxxu_download_firmware(struct rtl8xxxu_priv *priv)
{
int pages, remainder, i, ret;
- u8 val8;
+ u8 val8, sys_func;
u16 val16;
u32 val32;
u8 *fwptr;
/* 8051 enable */
val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
- rtl8xxxu_write16(priv, REG_SYS_FUNC, val16 | SYS_FUNC_CPU_ENABLE);
+ val16 |= SYS_FUNC_CPU_ENABLE;
+ rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
+
+ val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL);
+ if (val8 & MCU_FW_RAM_SEL) {
+ pr_info("do the RAM reset\n");
+ rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00);
+ val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
+ val8 &= ~BIT(3);
+ rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
+ sys_func = rtl8xxxu_read8(priv, REG_SYS_FUNC + 1);
+ sys_func &= ~BIT(2);
+ rtl8xxxu_write8(priv, REG_SYS_FUNC + 1, sys_func);
+ val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
+ val8 |= BIT(3);
+ rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
+ sys_func |= BIT(2);
+ rtl8xxxu_write8(priv, REG_SYS_FUNC + 1, sys_func);
+ }
/* MCU firmware download enable */
val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL);
- rtl8xxxu_write8(priv, REG_MCU_FW_DL, val8 | MCU_FW_DL_ENABLE);
+ val8 |= MCU_FW_DL_ENABLE;
+ rtl8xxxu_write8(priv, REG_MCU_FW_DL, val8);
/* 8051 reset */
val32 = rtl8xxxu_read32(priv, REG_MCU_FW_DL);
- rtl8xxxu_write32(priv, REG_MCU_FW_DL, val32 & ~BIT(19));
+ val32 &= ~BIT(19);
+ rtl8xxxu_write32(priv, REG_MCU_FW_DL, val32);
/* Reset firmware download checksum */
val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL);
- rtl8xxxu_write8(priv, REG_MCU_FW_DL, val8 | MCU_FW_DL_CSUM_REPORT);
+ val8 |= MCU_FW_DL_CSUM_REPORT;
+ rtl8xxxu_write8(priv, REG_MCU_FW_DL, val8);
pages = priv->fw_size / RTL_FW_PAGE_SIZE;
remainder = priv->fw_size % RTL_FW_PAGE_SIZE;
for (i = 0; i < pages; i++) {
val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL + 2) & 0xF8;
- rtl8xxxu_write8(priv, REG_MCU_FW_DL + 2, val8 | i);
+ val8 |= i;
+ rtl8xxxu_write8(priv, REG_MCU_FW_DL + 2, val8);
ret = rtl8xxxu_writeN(priv, REG_FW_START_ADDRESS,
fwptr, RTL_FW_PAGE_SIZE);
if (remainder) {
val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL + 2) & 0xF8;
- rtl8xxxu_write8(priv, REG_MCU_FW_DL + 2, val8 | i);
+ val8 |= i;
+ rtl8xxxu_write8(priv, REG_MCU_FW_DL + 2, val8);
ret = rtl8xxxu_writeN(priv, REG_FW_START_ADDRESS,
fwptr, remainder);
if (ret != remainder) {
fw_abort:
/* MCU firmware download disable */
val16 = rtl8xxxu_read16(priv, REG_MCU_FW_DL);
- rtl8xxxu_write16(priv, REG_MCU_FW_DL,
- val16 & (~MCU_FW_DL_ENABLE & 0xff));
+ val16 &= ~MCU_FW_DL_ENABLE;
+ rtl8xxxu_write16(priv, REG_MCU_FW_DL, val16);
return ret;
}
}
priv->fw_data = kmemdup(fw->data, fw->size, GFP_KERNEL);
+ if (!priv->fw_data) {
+ ret = -ENOMEM;
+ goto exit;
+ }
priv->fw_size = fw->size - sizeof(struct rtl8xxxu_firmware_header);
signature = le16_to_cpu(priv->fw_data->signature);