162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/* Copyright(c) 2009-2012  Realtek Corporation.*/
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include "../wifi.h"
562306a36Sopenharmony_ci#include "../pci.h"
662306a36Sopenharmony_ci#include "../base.h"
762306a36Sopenharmony_ci#include "../efuse.h"
862306a36Sopenharmony_ci#include "reg.h"
962306a36Sopenharmony_ci#include "def.h"
1062306a36Sopenharmony_ci#include "fw.h"
1162306a36Sopenharmony_ci#include "sw.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cistatic bool _rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv)
1462306a36Sopenharmony_ci{
1562306a36Sopenharmony_ci	return (rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) ?
1662306a36Sopenharmony_ci		true : false;
1762306a36Sopenharmony_ci}
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistatic void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
2262306a36Sopenharmony_ci	u8 tmp;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	if (enable) {
2562306a36Sopenharmony_ci		tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
2662306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
2762306a36Sopenharmony_ci		tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
2862306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
2962306a36Sopenharmony_ci		tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
3062306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
3162306a36Sopenharmony_ci	} else {
3262306a36Sopenharmony_ci		tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
3362306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
3462306a36Sopenharmony_ci		/* Reserved for fw extension.
3562306a36Sopenharmony_ci		 * 0x81[7] is used for mac0 status ,
3662306a36Sopenharmony_ci		 * so don't write this reg here
3762306a36Sopenharmony_ci		 * rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);*/
3862306a36Sopenharmony_ci	}
3962306a36Sopenharmony_ci}
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistatic void _rtl92d_write_fw(struct ieee80211_hw *hw,
4262306a36Sopenharmony_ci			     enum version_8192d version, u8 *buffer, u32 size)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
4562306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
4662306a36Sopenharmony_ci	u8 *bufferptr = buffer;
4762306a36Sopenharmony_ci	u32 pagenums, remainsize;
4862306a36Sopenharmony_ci	u32 page, offset;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
5162306a36Sopenharmony_ci	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
5262306a36Sopenharmony_ci		rtl_fill_dummy(bufferptr, &size);
5362306a36Sopenharmony_ci	pagenums = size / FW_8192D_PAGE_SIZE;
5462306a36Sopenharmony_ci	remainsize = size % FW_8192D_PAGE_SIZE;
5562306a36Sopenharmony_ci	if (pagenums > 8)
5662306a36Sopenharmony_ci		pr_err("Page numbers should not greater then 8\n");
5762306a36Sopenharmony_ci	for (page = 0; page < pagenums; page++) {
5862306a36Sopenharmony_ci		offset = page * FW_8192D_PAGE_SIZE;
5962306a36Sopenharmony_ci		rtl_fw_page_write(hw, page, (bufferptr + offset),
6062306a36Sopenharmony_ci				  FW_8192D_PAGE_SIZE);
6162306a36Sopenharmony_ci	}
6262306a36Sopenharmony_ci	if (remainsize) {
6362306a36Sopenharmony_ci		offset = pagenums * FW_8192D_PAGE_SIZE;
6462306a36Sopenharmony_ci		page = pagenums;
6562306a36Sopenharmony_ci		rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
6662306a36Sopenharmony_ci	}
6762306a36Sopenharmony_ci}
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistatic int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
7062306a36Sopenharmony_ci{
7162306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
7262306a36Sopenharmony_ci	u32 counter = 0;
7362306a36Sopenharmony_ci	u32 value32;
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	do {
7662306a36Sopenharmony_ci		value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
7762306a36Sopenharmony_ci	} while ((counter++ < FW_8192D_POLLING_TIMEOUT_COUNT) &&
7862306a36Sopenharmony_ci		 (!(value32 & FWDL_CHKSUM_RPT)));
7962306a36Sopenharmony_ci	if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) {
8062306a36Sopenharmony_ci		pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n",
8162306a36Sopenharmony_ci		       value32);
8262306a36Sopenharmony_ci		return -EIO;
8362306a36Sopenharmony_ci	}
8462306a36Sopenharmony_ci	value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
8562306a36Sopenharmony_ci	value32 |= MCUFWDL_RDY;
8662306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
8762306a36Sopenharmony_ci	return 0;
8862306a36Sopenharmony_ci}
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_civoid rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
9162306a36Sopenharmony_ci{
9262306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
9362306a36Sopenharmony_ci	u8 u1b_tmp;
9462306a36Sopenharmony_ci	u8 delay = 100;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	/* Set (REG_HMETFR + 3) to  0x20 is reset 8051 */
9762306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
9862306a36Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
9962306a36Sopenharmony_ci	while (u1b_tmp & BIT(2)) {
10062306a36Sopenharmony_ci		delay--;
10162306a36Sopenharmony_ci		if (delay == 0)
10262306a36Sopenharmony_ci			break;
10362306a36Sopenharmony_ci		udelay(50);
10462306a36Sopenharmony_ci		u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
10562306a36Sopenharmony_ci	}
10662306a36Sopenharmony_ci	WARN_ONCE((delay <= 0), "rtl8192de: 8051 reset failed!\n");
10762306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
10862306a36Sopenharmony_ci		"=====> 8051 reset success (%d)\n", delay);
10962306a36Sopenharmony_ci}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cistatic int _rtl92d_fw_init(struct ieee80211_hw *hw)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
11462306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
11562306a36Sopenharmony_ci	u32 counter;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n");
11862306a36Sopenharmony_ci	/* polling for FW ready */
11962306a36Sopenharmony_ci	counter = 0;
12062306a36Sopenharmony_ci	do {
12162306a36Sopenharmony_ci		if (rtlhal->interfaceindex == 0) {
12262306a36Sopenharmony_ci			if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
12362306a36Sopenharmony_ci			    MAC0_READY) {
12462306a36Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
12562306a36Sopenharmony_ci					"Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
12662306a36Sopenharmony_ci					rtl_read_byte(rtlpriv,
12762306a36Sopenharmony_ci						      FW_MAC0_READY));
12862306a36Sopenharmony_ci				return 0;
12962306a36Sopenharmony_ci			}
13062306a36Sopenharmony_ci			udelay(5);
13162306a36Sopenharmony_ci		} else {
13262306a36Sopenharmony_ci			if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
13362306a36Sopenharmony_ci			    MAC1_READY) {
13462306a36Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
13562306a36Sopenharmony_ci					"Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
13662306a36Sopenharmony_ci					rtl_read_byte(rtlpriv,
13762306a36Sopenharmony_ci						      FW_MAC1_READY));
13862306a36Sopenharmony_ci				return 0;
13962306a36Sopenharmony_ci			}
14062306a36Sopenharmony_ci			udelay(5);
14162306a36Sopenharmony_ci		}
14262306a36Sopenharmony_ci	} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	if (rtlhal->interfaceindex == 0) {
14562306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
14662306a36Sopenharmony_ci			"Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n",
14762306a36Sopenharmony_ci			rtl_read_byte(rtlpriv, FW_MAC0_READY));
14862306a36Sopenharmony_ci	} else {
14962306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
15062306a36Sopenharmony_ci			"Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n",
15162306a36Sopenharmony_ci			rtl_read_byte(rtlpriv, FW_MAC1_READY));
15262306a36Sopenharmony_ci	}
15362306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
15462306a36Sopenharmony_ci		"Polling FW ready fail!! REG_MCUFWDL:0x%08x\n",
15562306a36Sopenharmony_ci		rtl_read_dword(rtlpriv, REG_MCUFWDL));
15662306a36Sopenharmony_ci	return -1;
15762306a36Sopenharmony_ci}
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ciint rtl92d_download_fw(struct ieee80211_hw *hw)
16062306a36Sopenharmony_ci{
16162306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
16262306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
16362306a36Sopenharmony_ci	u8 *pfwheader;
16462306a36Sopenharmony_ci	u8 *pfwdata;
16562306a36Sopenharmony_ci	u32 fwsize;
16662306a36Sopenharmony_ci	int err;
16762306a36Sopenharmony_ci	enum version_8192d version = rtlhal->version;
16862306a36Sopenharmony_ci	u8 value;
16962306a36Sopenharmony_ci	u32 count;
17062306a36Sopenharmony_ci	bool fw_downloaded = false, fwdl_in_process = false;
17162306a36Sopenharmony_ci	unsigned long flags;
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
17462306a36Sopenharmony_ci		return 1;
17562306a36Sopenharmony_ci	fwsize = rtlhal->fwsize;
17662306a36Sopenharmony_ci	pfwheader = rtlhal->pfirmware;
17762306a36Sopenharmony_ci	pfwdata = rtlhal->pfirmware;
17862306a36Sopenharmony_ci	rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
17962306a36Sopenharmony_ci	rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
18062306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
18162306a36Sopenharmony_ci		"FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n",
18262306a36Sopenharmony_ci		rtlhal->fw_version, rtlhal->fw_subversion,
18362306a36Sopenharmony_ci		GET_FIRMWARE_HDR_SIGNATURE(pfwheader));
18462306a36Sopenharmony_ci	if (IS_FW_HEADER_EXIST(pfwheader)) {
18562306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
18662306a36Sopenharmony_ci			"Shift 32 bytes for FW header!!\n");
18762306a36Sopenharmony_ci		pfwdata = pfwdata + 32;
18862306a36Sopenharmony_ci		fwsize = fwsize - 32;
18962306a36Sopenharmony_ci	}
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
19262306a36Sopenharmony_ci	fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
19362306a36Sopenharmony_ci	if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
19462306a36Sopenharmony_ci		fwdl_in_process = true;
19562306a36Sopenharmony_ci	else
19662306a36Sopenharmony_ci		fwdl_in_process = false;
19762306a36Sopenharmony_ci	if (fw_downloaded) {
19862306a36Sopenharmony_ci		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
19962306a36Sopenharmony_ci		goto exit;
20062306a36Sopenharmony_ci	} else if (fwdl_in_process) {
20162306a36Sopenharmony_ci		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
20262306a36Sopenharmony_ci		for (count = 0; count < 5000; count++) {
20362306a36Sopenharmony_ci			udelay(500);
20462306a36Sopenharmony_ci			spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
20562306a36Sopenharmony_ci			fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
20662306a36Sopenharmony_ci			if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
20762306a36Sopenharmony_ci				fwdl_in_process = true;
20862306a36Sopenharmony_ci			else
20962306a36Sopenharmony_ci				fwdl_in_process = false;
21062306a36Sopenharmony_ci			spin_unlock_irqrestore(&globalmutex_for_fwdownload,
21162306a36Sopenharmony_ci					       flags);
21262306a36Sopenharmony_ci			if (fw_downloaded)
21362306a36Sopenharmony_ci				goto exit;
21462306a36Sopenharmony_ci			else if (!fwdl_in_process)
21562306a36Sopenharmony_ci				break;
21662306a36Sopenharmony_ci			else
21762306a36Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
21862306a36Sopenharmony_ci					"Wait for another mac download fw\n");
21962306a36Sopenharmony_ci		}
22062306a36Sopenharmony_ci		spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
22162306a36Sopenharmony_ci		value = rtl_read_byte(rtlpriv, 0x1f);
22262306a36Sopenharmony_ci		value |= BIT(5);
22362306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x1f, value);
22462306a36Sopenharmony_ci		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
22562306a36Sopenharmony_ci	} else {
22662306a36Sopenharmony_ci		value = rtl_read_byte(rtlpriv, 0x1f);
22762306a36Sopenharmony_ci		value |= BIT(5);
22862306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x1f, value);
22962306a36Sopenharmony_ci		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
23062306a36Sopenharmony_ci	}
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	/* If 8051 is running in RAM code, driver should
23362306a36Sopenharmony_ci	 * inform Fw to reset by itself, or it will cause
23462306a36Sopenharmony_ci	 * download Fw fail.*/
23562306a36Sopenharmony_ci	/* 8051 RAM code */
23662306a36Sopenharmony_ci	if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
23762306a36Sopenharmony_ci		rtl92d_firmware_selfreset(hw);
23862306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
23962306a36Sopenharmony_ci	}
24062306a36Sopenharmony_ci	_rtl92d_enable_fw_download(hw, true);
24162306a36Sopenharmony_ci	_rtl92d_write_fw(hw, version, pfwdata, fwsize);
24262306a36Sopenharmony_ci	_rtl92d_enable_fw_download(hw, false);
24362306a36Sopenharmony_ci	spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
24462306a36Sopenharmony_ci	err = _rtl92d_fw_free_to_go(hw);
24562306a36Sopenharmony_ci	/* download fw over,clear 0x1f[5] */
24662306a36Sopenharmony_ci	value = rtl_read_byte(rtlpriv, 0x1f);
24762306a36Sopenharmony_ci	value &= (~BIT(5));
24862306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, 0x1f, value);
24962306a36Sopenharmony_ci	spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
25062306a36Sopenharmony_ci	if (err)
25162306a36Sopenharmony_ci		pr_err("fw is not ready to run!\n");
25262306a36Sopenharmony_ciexit:
25362306a36Sopenharmony_ci	err = _rtl92d_fw_init(hw);
25462306a36Sopenharmony_ci	return err;
25562306a36Sopenharmony_ci}
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_cistatic bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
25862306a36Sopenharmony_ci{
25962306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
26062306a36Sopenharmony_ci	u8 val_hmetfr;
26162306a36Sopenharmony_ci	bool result = false;
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
26462306a36Sopenharmony_ci	if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
26562306a36Sopenharmony_ci		result = true;
26662306a36Sopenharmony_ci	return result;
26762306a36Sopenharmony_ci}
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_cistatic void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
27062306a36Sopenharmony_ci			      u8 element_id, u32 cmd_len, u8 *cmdbuffer)
27162306a36Sopenharmony_ci{
27262306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
27362306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
27462306a36Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
27562306a36Sopenharmony_ci	u8 boxnum;
27662306a36Sopenharmony_ci	u16 box_reg = 0, box_extreg = 0;
27762306a36Sopenharmony_ci	u8 u1b_tmp;
27862306a36Sopenharmony_ci	bool isfw_read = false;
27962306a36Sopenharmony_ci	u8 buf_index = 0;
28062306a36Sopenharmony_ci	bool bwrite_success = false;
28162306a36Sopenharmony_ci	u8 wait_h2c_limmit = 100;
28262306a36Sopenharmony_ci	u8 wait_writeh2c_limmit = 100;
28362306a36Sopenharmony_ci	u8 boxcontent[4], boxextcontent[2];
28462306a36Sopenharmony_ci	u32 h2c_waitcounter = 0;
28562306a36Sopenharmony_ci	unsigned long flag;
28662306a36Sopenharmony_ci	u8 idx;
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
28962306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
29062306a36Sopenharmony_ci			"Return as RF is off!!!\n");
29162306a36Sopenharmony_ci		return;
29262306a36Sopenharmony_ci	}
29362306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
29462306a36Sopenharmony_ci	while (true) {
29562306a36Sopenharmony_ci		spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
29662306a36Sopenharmony_ci		if (rtlhal->h2c_setinprogress) {
29762306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
29862306a36Sopenharmony_ci				"H2C set in progress! Wait to set..element_id(%d)\n",
29962306a36Sopenharmony_ci				element_id);
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci			while (rtlhal->h2c_setinprogress) {
30262306a36Sopenharmony_ci				spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
30362306a36Sopenharmony_ci						       flag);
30462306a36Sopenharmony_ci				h2c_waitcounter++;
30562306a36Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
30662306a36Sopenharmony_ci					"Wait 100 us (%d times)...\n",
30762306a36Sopenharmony_ci					h2c_waitcounter);
30862306a36Sopenharmony_ci				udelay(100);
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci				if (h2c_waitcounter > 1000)
31162306a36Sopenharmony_ci					return;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci				spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
31462306a36Sopenharmony_ci						  flag);
31562306a36Sopenharmony_ci			}
31662306a36Sopenharmony_ci			spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
31762306a36Sopenharmony_ci		} else {
31862306a36Sopenharmony_ci			rtlhal->h2c_setinprogress = true;
31962306a36Sopenharmony_ci			spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
32062306a36Sopenharmony_ci			break;
32162306a36Sopenharmony_ci		}
32262306a36Sopenharmony_ci	}
32362306a36Sopenharmony_ci	while (!bwrite_success) {
32462306a36Sopenharmony_ci		wait_writeh2c_limmit--;
32562306a36Sopenharmony_ci		if (wait_writeh2c_limmit == 0) {
32662306a36Sopenharmony_ci			pr_err("Write H2C fail because no trigger for FW INT!\n");
32762306a36Sopenharmony_ci			break;
32862306a36Sopenharmony_ci		}
32962306a36Sopenharmony_ci		boxnum = rtlhal->last_hmeboxnum;
33062306a36Sopenharmony_ci		switch (boxnum) {
33162306a36Sopenharmony_ci		case 0:
33262306a36Sopenharmony_ci			box_reg = REG_HMEBOX_0;
33362306a36Sopenharmony_ci			box_extreg = REG_HMEBOX_EXT_0;
33462306a36Sopenharmony_ci			break;
33562306a36Sopenharmony_ci		case 1:
33662306a36Sopenharmony_ci			box_reg = REG_HMEBOX_1;
33762306a36Sopenharmony_ci			box_extreg = REG_HMEBOX_EXT_1;
33862306a36Sopenharmony_ci			break;
33962306a36Sopenharmony_ci		case 2:
34062306a36Sopenharmony_ci			box_reg = REG_HMEBOX_2;
34162306a36Sopenharmony_ci			box_extreg = REG_HMEBOX_EXT_2;
34262306a36Sopenharmony_ci			break;
34362306a36Sopenharmony_ci		case 3:
34462306a36Sopenharmony_ci			box_reg = REG_HMEBOX_3;
34562306a36Sopenharmony_ci			box_extreg = REG_HMEBOX_EXT_3;
34662306a36Sopenharmony_ci			break;
34762306a36Sopenharmony_ci		default:
34862306a36Sopenharmony_ci			pr_err("switch case %#x not processed\n",
34962306a36Sopenharmony_ci			       boxnum);
35062306a36Sopenharmony_ci			break;
35162306a36Sopenharmony_ci		}
35262306a36Sopenharmony_ci		isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
35362306a36Sopenharmony_ci		while (!isfw_read) {
35462306a36Sopenharmony_ci			wait_h2c_limmit--;
35562306a36Sopenharmony_ci			if (wait_h2c_limmit == 0) {
35662306a36Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
35762306a36Sopenharmony_ci					"Waiting too long for FW read clear HMEBox(%d)!\n",
35862306a36Sopenharmony_ci					boxnum);
35962306a36Sopenharmony_ci				break;
36062306a36Sopenharmony_ci			}
36162306a36Sopenharmony_ci			udelay(10);
36262306a36Sopenharmony_ci			isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
36362306a36Sopenharmony_ci			u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
36462306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
36562306a36Sopenharmony_ci				"Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
36662306a36Sopenharmony_ci				boxnum, u1b_tmp);
36762306a36Sopenharmony_ci		}
36862306a36Sopenharmony_ci		if (!isfw_read) {
36962306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
37062306a36Sopenharmony_ci				"Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
37162306a36Sopenharmony_ci				boxnum);
37262306a36Sopenharmony_ci			break;
37362306a36Sopenharmony_ci		}
37462306a36Sopenharmony_ci		memset(boxcontent, 0, sizeof(boxcontent));
37562306a36Sopenharmony_ci		memset(boxextcontent, 0, sizeof(boxextcontent));
37662306a36Sopenharmony_ci		boxcontent[0] = element_id;
37762306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
37862306a36Sopenharmony_ci			"Write element_id box_reg(%4x) = %2x\n",
37962306a36Sopenharmony_ci			box_reg, element_id);
38062306a36Sopenharmony_ci		switch (cmd_len) {
38162306a36Sopenharmony_ci		case 1:
38262306a36Sopenharmony_ci			boxcontent[0] &= ~(BIT(7));
38362306a36Sopenharmony_ci			memcpy(boxcontent + 1, cmdbuffer + buf_index, 1);
38462306a36Sopenharmony_ci			for (idx = 0; idx < 4; idx++)
38562306a36Sopenharmony_ci				rtl_write_byte(rtlpriv, box_reg + idx,
38662306a36Sopenharmony_ci					       boxcontent[idx]);
38762306a36Sopenharmony_ci			break;
38862306a36Sopenharmony_ci		case 2:
38962306a36Sopenharmony_ci			boxcontent[0] &= ~(BIT(7));
39062306a36Sopenharmony_ci			memcpy(boxcontent + 1, cmdbuffer + buf_index, 2);
39162306a36Sopenharmony_ci			for (idx = 0; idx < 4; idx++)
39262306a36Sopenharmony_ci				rtl_write_byte(rtlpriv, box_reg + idx,
39362306a36Sopenharmony_ci					       boxcontent[idx]);
39462306a36Sopenharmony_ci			break;
39562306a36Sopenharmony_ci		case 3:
39662306a36Sopenharmony_ci			boxcontent[0] &= ~(BIT(7));
39762306a36Sopenharmony_ci			memcpy(boxcontent + 1, cmdbuffer + buf_index, 3);
39862306a36Sopenharmony_ci			for (idx = 0; idx < 4; idx++)
39962306a36Sopenharmony_ci				rtl_write_byte(rtlpriv, box_reg + idx,
40062306a36Sopenharmony_ci					       boxcontent[idx]);
40162306a36Sopenharmony_ci			break;
40262306a36Sopenharmony_ci		case 4:
40362306a36Sopenharmony_ci			boxcontent[0] |= (BIT(7));
40462306a36Sopenharmony_ci			memcpy(boxextcontent, cmdbuffer + buf_index, 2);
40562306a36Sopenharmony_ci			memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 2);
40662306a36Sopenharmony_ci			for (idx = 0; idx < 2; idx++)
40762306a36Sopenharmony_ci				rtl_write_byte(rtlpriv, box_extreg + idx,
40862306a36Sopenharmony_ci					       boxextcontent[idx]);
40962306a36Sopenharmony_ci			for (idx = 0; idx < 4; idx++)
41062306a36Sopenharmony_ci				rtl_write_byte(rtlpriv, box_reg + idx,
41162306a36Sopenharmony_ci					       boxcontent[idx]);
41262306a36Sopenharmony_ci			break;
41362306a36Sopenharmony_ci		case 5:
41462306a36Sopenharmony_ci			boxcontent[0] |= (BIT(7));
41562306a36Sopenharmony_ci			memcpy(boxextcontent, cmdbuffer + buf_index, 2);
41662306a36Sopenharmony_ci			memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 3);
41762306a36Sopenharmony_ci			for (idx = 0; idx < 2; idx++)
41862306a36Sopenharmony_ci				rtl_write_byte(rtlpriv, box_extreg + idx,
41962306a36Sopenharmony_ci					       boxextcontent[idx]);
42062306a36Sopenharmony_ci			for (idx = 0; idx < 4; idx++)
42162306a36Sopenharmony_ci				rtl_write_byte(rtlpriv, box_reg + idx,
42262306a36Sopenharmony_ci					       boxcontent[idx]);
42362306a36Sopenharmony_ci			break;
42462306a36Sopenharmony_ci		default:
42562306a36Sopenharmony_ci			pr_err("switch case %#x not processed\n",
42662306a36Sopenharmony_ci			       cmd_len);
42762306a36Sopenharmony_ci			break;
42862306a36Sopenharmony_ci		}
42962306a36Sopenharmony_ci		bwrite_success = true;
43062306a36Sopenharmony_ci		rtlhal->last_hmeboxnum = boxnum + 1;
43162306a36Sopenharmony_ci		if (rtlhal->last_hmeboxnum == 4)
43262306a36Sopenharmony_ci			rtlhal->last_hmeboxnum = 0;
43362306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
43462306a36Sopenharmony_ci			"pHalData->last_hmeboxnum  = %d\n",
43562306a36Sopenharmony_ci			rtlhal->last_hmeboxnum);
43662306a36Sopenharmony_ci	}
43762306a36Sopenharmony_ci	spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
43862306a36Sopenharmony_ci	rtlhal->h2c_setinprogress = false;
43962306a36Sopenharmony_ci	spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
44062306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
44162306a36Sopenharmony_ci}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_civoid rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
44462306a36Sopenharmony_ci			 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
44562306a36Sopenharmony_ci{
44662306a36Sopenharmony_ci	u32 tmp_cmdbuf[2];
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	memset(tmp_cmdbuf, 0, 8);
44962306a36Sopenharmony_ci	memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
45062306a36Sopenharmony_ci	_rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
45162306a36Sopenharmony_ci	return;
45262306a36Sopenharmony_ci}
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_cistatic bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,
45562306a36Sopenharmony_ci				    struct sk_buff *skb)
45662306a36Sopenharmony_ci{
45762306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
45862306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
45962306a36Sopenharmony_ci	struct rtl8192_tx_ring *ring;
46062306a36Sopenharmony_ci	struct rtl_tx_desc *pdesc;
46162306a36Sopenharmony_ci	u8 idx = 0;
46262306a36Sopenharmony_ci	unsigned long flags;
46362306a36Sopenharmony_ci	struct sk_buff *pskb;
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci	ring = &rtlpci->tx_ring[BEACON_QUEUE];
46662306a36Sopenharmony_ci	pskb = __skb_dequeue(&ring->queue);
46762306a36Sopenharmony_ci	kfree_skb(pskb);
46862306a36Sopenharmony_ci	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
46962306a36Sopenharmony_ci	pdesc = &ring->desc[idx];
47062306a36Sopenharmony_ci	/* discard output from call below */
47162306a36Sopenharmony_ci	rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN);
47262306a36Sopenharmony_ci	rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
47362306a36Sopenharmony_ci	__skb_queue_tail(&ring->queue, skb);
47462306a36Sopenharmony_ci	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
47562306a36Sopenharmony_ci	rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
47662306a36Sopenharmony_ci	return true;
47762306a36Sopenharmony_ci}
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci#define BEACON_PG		0	/*->1 */
48062306a36Sopenharmony_ci#define PSPOLL_PG		2
48162306a36Sopenharmony_ci#define NULL_PG			3
48262306a36Sopenharmony_ci#define PROBERSP_PG		4	/*->5 */
48362306a36Sopenharmony_ci#define TOTAL_RESERVED_PKT_LEN	768
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_cistatic u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
48662306a36Sopenharmony_ci	/* page 0 beacon */
48762306a36Sopenharmony_ci	0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
48862306a36Sopenharmony_ci	0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
48962306a36Sopenharmony_ci	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
49062306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49162306a36Sopenharmony_ci	0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
49262306a36Sopenharmony_ci	0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
49362306a36Sopenharmony_ci	0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
49462306a36Sopenharmony_ci	0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
49562306a36Sopenharmony_ci	0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
49662306a36Sopenharmony_ci	0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
49762306a36Sopenharmony_ci	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49862306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49962306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50062306a36Sopenharmony_ci	0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
50162306a36Sopenharmony_ci	0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50262306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_ci	/* page 1 beacon */
50562306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50662306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50762306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50862306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50962306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51062306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51162306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51262306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51362306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51462306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51562306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51662306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51762306a36Sopenharmony_ci	0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
51862306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51962306a36Sopenharmony_ci	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52062306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	/* page 2  ps-poll */
52362306a36Sopenharmony_ci	0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
52462306a36Sopenharmony_ci	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
52562306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52662306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52762306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52862306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52962306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53062306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53162306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53262306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53362306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53462306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53562306a36Sopenharmony_ci	0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
53662306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
53762306a36Sopenharmony_ci	0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53862306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	/* page 3  null */
54162306a36Sopenharmony_ci	0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
54262306a36Sopenharmony_ci	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
54362306a36Sopenharmony_ci	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
54462306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54562306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54662306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54762306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54862306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54962306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55062306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55162306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55262306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55362306a36Sopenharmony_ci	0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
55462306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
55562306a36Sopenharmony_ci	0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55662306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci	/* page 4  probe_resp */
55962306a36Sopenharmony_ci	0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
56062306a36Sopenharmony_ci	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
56162306a36Sopenharmony_ci	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
56262306a36Sopenharmony_ci	0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
56362306a36Sopenharmony_ci	0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
56462306a36Sopenharmony_ci	0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
56562306a36Sopenharmony_ci	0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
56662306a36Sopenharmony_ci	0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
56762306a36Sopenharmony_ci	0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
56862306a36Sopenharmony_ci	0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
56962306a36Sopenharmony_ci	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57062306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57162306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57262306a36Sopenharmony_ci	0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
57362306a36Sopenharmony_ci	0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57462306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	/* page 5  probe_resp */
57762306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57862306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57962306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58062306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58162306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58262306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58362306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58462306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58562306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58662306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58762306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58862306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58962306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59062306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59162306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59262306a36Sopenharmony_ci	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59362306a36Sopenharmony_ci};
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_civoid rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
59662306a36Sopenharmony_ci{
59762306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
59862306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
59962306a36Sopenharmony_ci	struct sk_buff *skb = NULL;
60062306a36Sopenharmony_ci	u32 totalpacketlen;
60162306a36Sopenharmony_ci	bool rtstatus;
60262306a36Sopenharmony_ci	u8 u1rsvdpageloc[3] = { 0 };
60362306a36Sopenharmony_ci	bool dlok = false;
60462306a36Sopenharmony_ci	u8 *beacon;
60562306a36Sopenharmony_ci	u8 *p_pspoll;
60662306a36Sopenharmony_ci	u8 *nullfunc;
60762306a36Sopenharmony_ci	u8 *p_probersp;
60862306a36Sopenharmony_ci	/*---------------------------------------------------------
60962306a36Sopenharmony_ci						(1) beacon
61062306a36Sopenharmony_ci	---------------------------------------------------------*/
61162306a36Sopenharmony_ci	beacon = &reserved_page_packet[BEACON_PG * 128];
61262306a36Sopenharmony_ci	SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
61362306a36Sopenharmony_ci	SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
61462306a36Sopenharmony_ci	/*-------------------------------------------------------
61562306a36Sopenharmony_ci						(2) ps-poll
61662306a36Sopenharmony_ci	--------------------------------------------------------*/
61762306a36Sopenharmony_ci	p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
61862306a36Sopenharmony_ci	SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
61962306a36Sopenharmony_ci	SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
62062306a36Sopenharmony_ci	SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
62162306a36Sopenharmony_ci	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
62262306a36Sopenharmony_ci	/*--------------------------------------------------------
62362306a36Sopenharmony_ci						(3) null data
62462306a36Sopenharmony_ci	---------------------------------------------------------*/
62562306a36Sopenharmony_ci	nullfunc = &reserved_page_packet[NULL_PG * 128];
62662306a36Sopenharmony_ci	SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
62762306a36Sopenharmony_ci	SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
62862306a36Sopenharmony_ci	SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
62962306a36Sopenharmony_ci	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
63062306a36Sopenharmony_ci	/*---------------------------------------------------------
63162306a36Sopenharmony_ci						(4) probe response
63262306a36Sopenharmony_ci	----------------------------------------------------------*/
63362306a36Sopenharmony_ci	p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
63462306a36Sopenharmony_ci	SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
63562306a36Sopenharmony_ci	SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
63662306a36Sopenharmony_ci	SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
63762306a36Sopenharmony_ci	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
63862306a36Sopenharmony_ci	totalpacketlen = TOTAL_RESERVED_PKT_LEN;
63962306a36Sopenharmony_ci	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
64062306a36Sopenharmony_ci		      "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
64162306a36Sopenharmony_ci		      &reserved_page_packet[0], totalpacketlen);
64262306a36Sopenharmony_ci	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
64362306a36Sopenharmony_ci		      "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
64462306a36Sopenharmony_ci		      u1rsvdpageloc, 3);
64562306a36Sopenharmony_ci	skb = dev_alloc_skb(totalpacketlen);
64662306a36Sopenharmony_ci	if (!skb) {
64762306a36Sopenharmony_ci		dlok = false;
64862306a36Sopenharmony_ci	} else {
64962306a36Sopenharmony_ci		skb_put_data(skb, &reserved_page_packet, totalpacketlen);
65062306a36Sopenharmony_ci		rtstatus = _rtl92d_cmd_send_packet(hw, skb);
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci		if (rtstatus)
65362306a36Sopenharmony_ci			dlok = true;
65462306a36Sopenharmony_ci	}
65562306a36Sopenharmony_ci	if (dlok) {
65662306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
65762306a36Sopenharmony_ci			"Set RSVD page location to Fw\n");
65862306a36Sopenharmony_ci		RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
65962306a36Sopenharmony_ci			      "H2C_RSVDPAGE", u1rsvdpageloc, 3);
66062306a36Sopenharmony_ci		rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,
66162306a36Sopenharmony_ci			sizeof(u1rsvdpageloc), u1rsvdpageloc);
66262306a36Sopenharmony_ci	} else
66362306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
66462306a36Sopenharmony_ci			"Set RSVD page location to Fw FAIL!!!!!!\n");
66562306a36Sopenharmony_ci}
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_civoid rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
66862306a36Sopenharmony_ci{
66962306a36Sopenharmony_ci	u8 u1_joinbssrpt_parm[1] = {0};
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci	SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
67262306a36Sopenharmony_ci	rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
67362306a36Sopenharmony_ci}
674