1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright(c) 2024 Realtek Corporation.*/ 3 4 #include "../wifi.h" 5 #include "../rtl8192d/reg.h" 6 #include "../rtl8192d/def.h" 7 #include "../rtl8192d/fw_common.h" 8 #include "fw.h" 9 10 int rtl92du_download_fw(struct ieee80211_hw *hw) 11 { 12 struct rtl_priv *rtlpriv = rtl_priv(hw); 13 struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 14 enum version_8192d version = rtlhal->version; 15 u8 *pfwheader; 16 u8 *pfwdata; 17 u32 fwsize; 18 int err; 19 20 if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) 21 return 1; 22 23 fwsize = rtlhal->fwsize; 24 pfwheader = rtlhal->pfirmware; 25 pfwdata = rtlhal->pfirmware; 26 rtlhal->fw_version = (u16)GET_FIRMWARE_HDR_VERSION(pfwheader); 27 rtlhal->fw_subversion = (u16)GET_FIRMWARE_HDR_SUB_VER(pfwheader); 28 29 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 30 "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n", 31 rtlhal->fw_version, rtlhal->fw_subversion, 32 GET_FIRMWARE_HDR_SIGNATURE(pfwheader)); 33 34 if (IS_FW_HEADER_EXIST(pfwheader)) { 35 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 36 "Shift 32 bytes for FW header!!\n"); 37 pfwdata = pfwdata + 32; 38 fwsize = fwsize - 32; 39 } 40 41 if (rtl92d_is_fw_downloaded(rtlpriv)) 42 goto exit; 43 44 /* If 8051 is running in RAM code, driver should 45 * inform Fw to reset by itself, or it will cause 46 * download Fw fail. 47 */ 48 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) { 49 rtl92d_firmware_selfreset(hw); 50 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); 51 } 52 53 rtl92d_enable_fw_download(hw, true); 54 rtl92d_write_fw(hw, version, pfwdata, fwsize); 55 rtl92d_enable_fw_download(hw, false); 56 57 err = rtl92d_fw_free_to_go(hw); 58 if (err) 59 pr_err("fw is not ready to run!\n"); 60 exit: 61 err = rtl92d_fw_init(hw); 62 return err; 63 } 64