drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
Extension
.c
Size
72096 bytes
Lines
1902
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

IS_FW_HEADER_EXIST_8821(pfwheader)) {
		rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
			"Firmware Version(%d), Signature(%#x)\n",
			pfwheader->version, pfwheader->signature);

		pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header);
		fwsize = fwsize - sizeof(struct rtlwifi_firmware_header);
	}

	if (rtlhal->mac_func_enable) {
		if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
			rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
			rtl8821ae_firmware_selfreset(hw);
		}
	}
	_rtl8821ae_enable_fw_download(hw, true);
	_rtl8821ae_write_fw(hw, version, pfwdata, fwsize);
	_rtl8821ae_enable_fw_download(hw, false);

	err = _rtl8821ae_fw_free_to_go(hw);
	if (err) {
		rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
			"Firmware is not ready to run!\n");
	} else {
		rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD,
			"Firmware is ready to run!\n");
	}

	return 0;
}

#if (USE_SPECIFIC_FW_TO_SUPPORT_WOWLAN == 1)
void rtl8821ae_set_fw_related_for_wowlan(struct ieee80211_hw *hw,
					 bool used_wowlan_fw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
	/* 1. Before WoWLAN or After WOWLAN we need to re-download Fw. */
	if (rtl8821ae_download_fw(hw, used_wowlan_fw)) {
		rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
			"Re-Download Firmware failed!!\n");
		rtlhal->fw_ready = false;
		return;
	}
	rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
		"Re-Download Firmware Success !!\n");
	rtlhal->fw_ready = true;

	/* 2. Re-Init the variables about Fw related setting. */
	ppsc->fw_current_inpsmode = false;
	rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_8821AE;
	rtlhal->fw_clk_change_in_progress = false;
	rtlhal->allow_sw_to_change_hwclc = false;
	rtlhal->last_hmeboxnum = 0;
}
#endif

static bool _rtl8821ae_check_fw_read_last_h2c(struct ieee80211_hw *hw,
					      u8 boxnum)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	u8 val_hmetfr;
	bool result = false;

	val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
	if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
		result = true;
	return result;
}

static void _rtl8821ae_fill_h2c_command(struct ieee80211_hw *hw,
					u8 element_id, u32 cmd_len,
					u8 *cmdbuffer)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
	u8 boxnum = 0;
	u16 box_reg = 0, box_extreg = 0;
	u8 u1b_tmp = 0;
	bool isfw_read = false;
	u8 buf_index = 0;
	bool bwrite_sucess = false;
	u8 wait_h2c_limmit = 100;
	/*u8 wait_writeh2c_limmit = 100;*/
	u8 boxcontent[4], boxextcontent[4];
	u32 h2c_waitcounter = 0;
	unsigned long flag = 0;
	u8 idx = 0;

Annotation

Implementation Notes