| // SPDX-License-Identifier: GPL-2.0 |
| /* Copyright(c) 2024 Realtek Corporation.*/ |
| |
| #include "../wifi.h" |
| #include "../rtl8192d/reg.h" |
| #include "../rtl8192d/def.h" |
| #include "../rtl8192d/fw_common.h" |
| #include "fw.h" |
| |
| int rtl92du_download_fw(struct ieee80211_hw *hw) |
| { |
| struct rtl_priv *rtlpriv = rtl_priv(hw); |
| struct rtl_hal *rtlhal = rtl_hal(rtlpriv); |
| enum version_8192d version = rtlhal->version; |
| u8 *pfwheader; |
| u8 *pfwdata; |
| u32 fwsize; |
| int err; |
| |
| if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) |
| return 1; |
| |
| fwsize = rtlhal->fwsize; |
| pfwheader = rtlhal->pfirmware; |
| pfwdata = rtlhal->pfirmware; |
| rtlhal->fw_version = (u16)GET_FIRMWARE_HDR_VERSION(pfwheader); |
| rtlhal->fw_subversion = (u16)GET_FIRMWARE_HDR_SUB_VER(pfwheader); |
| |
| rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, |
| "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n", |
| rtlhal->fw_version, rtlhal->fw_subversion, |
| GET_FIRMWARE_HDR_SIGNATURE(pfwheader)); |
| |
| if (IS_FW_HEADER_EXIST(pfwheader)) { |
| rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, |
| "Shift 32 bytes for FW header!!\n"); |
| pfwdata = pfwdata + 32; |
| fwsize = fwsize - 32; |
| } |
| |
| if (rtl92d_is_fw_downloaded(rtlpriv)) |
| goto exit; |
| |
| /* If 8051 is running in RAM code, driver should |
| * inform Fw to reset by itself, or it will cause |
| * download Fw fail. |
| */ |
| if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) { |
| rtl92d_firmware_selfreset(hw); |
| rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); |
| } |
| |
| rtl92d_enable_fw_download(hw, true); |
| rtl92d_write_fw(hw, version, pfwdata, fwsize); |
| rtl92d_enable_fw_download(hw, false); |
| |
| err = rtl92d_fw_free_to_go(hw); |
| if (err) |
| pr_err("fw is not ready to run!\n"); |
| exit: |
| err = rtl92d_fw_init(hw); |
| return err; |
| } |