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
rtl92du_download_fw(struct ieee80211_hw * hw)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