1647f21b1SLarry Finger // SPDX-License-Identifier: GPL-2.0
2647f21b1SLarry Finger /* Copyright(c) 2009-2014 Realtek Corporation.*/
3b1a3bfc9SLarry Finger
4b1a3bfc9SLarry Finger #include "../wifi.h"
5b1a3bfc9SLarry Finger #include "../pci.h"
6b1a3bfc9SLarry Finger #include "../base.h"
7557f9331SLarry Finger #include "../core.h"
889d32c90SLarry Finger #include "../efuse.h"
9b1a3bfc9SLarry Finger #include "reg.h"
10b1a3bfc9SLarry Finger #include "def.h"
11b1a3bfc9SLarry Finger #include "fw.h"
12b1a3bfc9SLarry Finger #include "dm.h"
13b1a3bfc9SLarry Finger
_rtl92ee_enable_fw_download(struct ieee80211_hw * hw,bool enable)14b1a3bfc9SLarry Finger static void _rtl92ee_enable_fw_download(struct ieee80211_hw *hw, bool enable)
15b1a3bfc9SLarry Finger {
16b1a3bfc9SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
17b1a3bfc9SLarry Finger u8 tmp;
18b1a3bfc9SLarry Finger
19b1a3bfc9SLarry Finger if (enable) {
20b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x05);
21b1a3bfc9SLarry Finger
22b1a3bfc9SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
23b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
24b1a3bfc9SLarry Finger } else {
25b1a3bfc9SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
26b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
27b1a3bfc9SLarry Finger }
28b1a3bfc9SLarry Finger }
29b1a3bfc9SLarry Finger
_rtl92ee_write_fw(struct ieee80211_hw * hw,enum version_8192e version,u8 * buffer,u32 size)30b1a3bfc9SLarry Finger static void _rtl92ee_write_fw(struct ieee80211_hw *hw,
31b1a3bfc9SLarry Finger enum version_8192e version,
32b1a3bfc9SLarry Finger u8 *buffer, u32 size)
33b1a3bfc9SLarry Finger {
34b1a3bfc9SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
35b1a3bfc9SLarry Finger u8 *bufferptr = (u8 *)buffer;
36b1a3bfc9SLarry Finger u32 pagenums, remainsize;
37b1a3bfc9SLarry Finger u32 page, offset;
38b1a3bfc9SLarry Finger
39e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
40b1a3bfc9SLarry Finger
4189d32c90SLarry Finger rtl_fill_dummy(bufferptr, &size);
42b1a3bfc9SLarry Finger
43b1a3bfc9SLarry Finger pagenums = size / FW_8192C_PAGE_SIZE;
44b1a3bfc9SLarry Finger remainsize = size % FW_8192C_PAGE_SIZE;
45b1a3bfc9SLarry Finger
46a44f59d6SLarry Finger if (pagenums > 8)
47a44f59d6SLarry Finger pr_err("Page numbers should not greater then 8\n");
48b1a3bfc9SLarry Finger
49b1a3bfc9SLarry Finger for (page = 0; page < pagenums; page++) {
50b1a3bfc9SLarry Finger offset = page * FW_8192C_PAGE_SIZE;
5189d32c90SLarry Finger rtl_fw_page_write(hw, page, (bufferptr + offset),
52b1a3bfc9SLarry Finger FW_8192C_PAGE_SIZE);
53b1a3bfc9SLarry Finger udelay(2);
54b1a3bfc9SLarry Finger }
55b1a3bfc9SLarry Finger
56b1a3bfc9SLarry Finger if (remainsize) {
57b1a3bfc9SLarry Finger offset = pagenums * FW_8192C_PAGE_SIZE;
58b1a3bfc9SLarry Finger page = pagenums;
5989d32c90SLarry Finger rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
60b1a3bfc9SLarry Finger }
61b1a3bfc9SLarry Finger }
62b1a3bfc9SLarry Finger
_rtl92ee_fw_free_to_go(struct ieee80211_hw * hw)63b1a3bfc9SLarry Finger static int _rtl92ee_fw_free_to_go(struct ieee80211_hw *hw)
64b1a3bfc9SLarry Finger {
65b1a3bfc9SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
66b1a3bfc9SLarry Finger int err = -EIO;
67b1a3bfc9SLarry Finger u32 counter = 0;
68b1a3bfc9SLarry Finger u32 value32;
69b1a3bfc9SLarry Finger
70b1a3bfc9SLarry Finger do {
71b1a3bfc9SLarry Finger value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
72b1a3bfc9SLarry Finger } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
73b1a3bfc9SLarry Finger (!(value32 & FWDL_CHKSUM_RPT)));
74b1a3bfc9SLarry Finger
75b1a3bfc9SLarry Finger if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
76a44f59d6SLarry Finger pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n",
77b1a3bfc9SLarry Finger value32);
78b1a3bfc9SLarry Finger goto exit;
79b1a3bfc9SLarry Finger }
80b1a3bfc9SLarry Finger value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
81b1a3bfc9SLarry Finger value32 |= MCUFWDL_RDY;
82b1a3bfc9SLarry Finger value32 &= ~WINTINI_RDY;
83b1a3bfc9SLarry Finger rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
84b1a3bfc9SLarry Finger
85b1a3bfc9SLarry Finger rtl92ee_firmware_selfreset(hw);
86b1a3bfc9SLarry Finger counter = 0;
87b1a3bfc9SLarry Finger
88b1a3bfc9SLarry Finger do {
89b1a3bfc9SLarry Finger value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
90c93ac39dSLarry Finger if (value32 & WINTINI_RDY)
91c93ac39dSLarry Finger return 0;
92b1a3bfc9SLarry Finger
93b1a3bfc9SLarry Finger udelay(FW_8192C_POLLING_DELAY*10);
94b1a3bfc9SLarry Finger
95b1a3bfc9SLarry Finger } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
96b1a3bfc9SLarry Finger
97a44f59d6SLarry Finger pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x. count = %d\n",
98b1a3bfc9SLarry Finger value32, counter);
99b1a3bfc9SLarry Finger
100b1a3bfc9SLarry Finger exit:
101b1a3bfc9SLarry Finger return err;
102b1a3bfc9SLarry Finger }
103b1a3bfc9SLarry Finger
rtl92ee_download_fw(struct ieee80211_hw * hw,bool buse_wake_on_wlan_fw)104b1a3bfc9SLarry Finger int rtl92ee_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw)
105b1a3bfc9SLarry Finger {
106b1a3bfc9SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
107b1a3bfc9SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1088d882bcfSLarry Finger struct rtlwifi_firmware_header *pfwheader;
109b1a3bfc9SLarry Finger u8 *pfwdata;
110b1a3bfc9SLarry Finger u32 fwsize;
111b1a3bfc9SLarry Finger enum version_8192e version = rtlhal->version;
112b1a3bfc9SLarry Finger
113b1a3bfc9SLarry Finger if (!rtlhal->pfirmware)
114b1a3bfc9SLarry Finger return 1;
115b1a3bfc9SLarry Finger
1168d882bcfSLarry Finger pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware;
1178d882bcfSLarry Finger rtlhal->fw_version = le16_to_cpu(pfwheader->version);
118b1a3bfc9SLarry Finger rtlhal->fw_subversion = pfwheader->subversion;
119b1a3bfc9SLarry Finger pfwdata = (u8 *)rtlhal->pfirmware;
120b1a3bfc9SLarry Finger fwsize = rtlhal->fwsize;
121e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
122b1a3bfc9SLarry Finger "normal Firmware SIZE %d\n", fwsize);
123b1a3bfc9SLarry Finger
124b1a3bfc9SLarry Finger if (IS_FW_HEADER_EXIST(pfwheader)) {
125e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
126b1a3bfc9SLarry Finger "Firmware Version(%d), Signature(%#x),Size(%d)\n",
127b1a3bfc9SLarry Finger pfwheader->version, pfwheader->signature,
1288d882bcfSLarry Finger (int)sizeof(struct rtlwifi_firmware_header));
129b1a3bfc9SLarry Finger
1308d882bcfSLarry Finger pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header);
1318d882bcfSLarry Finger fwsize = fwsize - sizeof(struct rtlwifi_firmware_header);
132b1a3bfc9SLarry Finger } else {
133e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
134b1a3bfc9SLarry Finger "Firmware no Header, Signature(%#x)\n",
135b1a3bfc9SLarry Finger pfwheader->signature);
136b1a3bfc9SLarry Finger }
137b1a3bfc9SLarry Finger
138b1a3bfc9SLarry Finger if (rtlhal->mac_func_enable) {
139b1a3bfc9SLarry Finger if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
140b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
141b1a3bfc9SLarry Finger rtl92ee_firmware_selfreset(hw);
142b1a3bfc9SLarry Finger }
143b1a3bfc9SLarry Finger }
144b1a3bfc9SLarry Finger _rtl92ee_enable_fw_download(hw, true);
145b1a3bfc9SLarry Finger _rtl92ee_write_fw(hw, version, pfwdata, fwsize);
146b1a3bfc9SLarry Finger _rtl92ee_enable_fw_download(hw, false);
147b1a3bfc9SLarry Finger
14859f4567dSzhengbin return _rtl92ee_fw_free_to_go(hw);
149b1a3bfc9SLarry Finger }
150b1a3bfc9SLarry Finger
_rtl92ee_check_fw_read_last_h2c(struct ieee80211_hw * hw,u8 boxnum)151b1a3bfc9SLarry Finger static bool _rtl92ee_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
152b1a3bfc9SLarry Finger {
153b1a3bfc9SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
154b1a3bfc9SLarry Finger u8 val_hmetfr;
155b1a3bfc9SLarry Finger bool result = false;
156b1a3bfc9SLarry Finger
157b1a3bfc9SLarry Finger val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
158b1a3bfc9SLarry Finger if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
159b1a3bfc9SLarry Finger result = true;
160b1a3bfc9SLarry Finger return result;
161b1a3bfc9SLarry Finger }
162b1a3bfc9SLarry Finger
_rtl92ee_fill_h2c_command(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * cmdbuffer)163b1a3bfc9SLarry Finger static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
164b1a3bfc9SLarry Finger u32 cmd_len, u8 *cmdbuffer)
165b1a3bfc9SLarry Finger {
166b1a3bfc9SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
167b1a3bfc9SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
168b1a3bfc9SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
169b1a3bfc9SLarry Finger u8 boxnum;
170b1a3bfc9SLarry Finger u16 box_reg = 0, box_extreg = 0;
171b1a3bfc9SLarry Finger u8 u1b_tmp;
172b1a3bfc9SLarry Finger bool isfw_read = false;
173b1a3bfc9SLarry Finger u8 buf_index = 0;
174b1a3bfc9SLarry Finger bool bwrite_sucess = false;
175b1a3bfc9SLarry Finger u8 wait_h2c_limmit = 100;
176b1a3bfc9SLarry Finger u8 boxcontent[4], boxextcontent[4];
177b1a3bfc9SLarry Finger u32 h2c_waitcounter = 0;
178b1a3bfc9SLarry Finger unsigned long flag;
179b1a3bfc9SLarry Finger u8 idx;
180b1a3bfc9SLarry Finger
181b1a3bfc9SLarry Finger if (ppsc->dot11_psmode != EACTIVE ||
182b1a3bfc9SLarry Finger ppsc->inactive_pwrstate == ERFOFF) {
183e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
184b1a3bfc9SLarry Finger "FillH2CCommand8192E(): Return because RF is off!!!\n");
185b1a3bfc9SLarry Finger return;
186b1a3bfc9SLarry Finger }
187b1a3bfc9SLarry Finger
188e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
189b1a3bfc9SLarry Finger
190b1a3bfc9SLarry Finger /* 1. Prevent race condition in setting H2C cmd.
191b1a3bfc9SLarry Finger * (copy from MgntActSet_RF_State().)
192b1a3bfc9SLarry Finger */
193b1a3bfc9SLarry Finger while (true) {
194b1a3bfc9SLarry Finger spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
195b1a3bfc9SLarry Finger if (rtlhal->h2c_setinprogress) {
196e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
197b1a3bfc9SLarry Finger "H2C set in progress! Wait to set..element_id(%d).\n",
198b1a3bfc9SLarry Finger element_id);
199b1a3bfc9SLarry Finger
200b1a3bfc9SLarry Finger while (rtlhal->h2c_setinprogress) {
201b1a3bfc9SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
202b1a3bfc9SLarry Finger flag);
203b1a3bfc9SLarry Finger h2c_waitcounter++;
204e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
205b1a3bfc9SLarry Finger "Wait 100 us (%d times)...\n",
206b1a3bfc9SLarry Finger h2c_waitcounter);
207b1a3bfc9SLarry Finger udelay(100);
208b1a3bfc9SLarry Finger
209b1a3bfc9SLarry Finger if (h2c_waitcounter > 1000)
210b1a3bfc9SLarry Finger return;
211b1a3bfc9SLarry Finger spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
212b1a3bfc9SLarry Finger flag);
213b1a3bfc9SLarry Finger }
214b1a3bfc9SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
215b1a3bfc9SLarry Finger } else {
216b1a3bfc9SLarry Finger rtlhal->h2c_setinprogress = true;
217b1a3bfc9SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
218b1a3bfc9SLarry Finger break;
219b1a3bfc9SLarry Finger }
220b1a3bfc9SLarry Finger }
221b1a3bfc9SLarry Finger
222b1a3bfc9SLarry Finger while (!bwrite_sucess) {
223b1a3bfc9SLarry Finger /* 2. Find the last BOX number which has been writen. */
224b1a3bfc9SLarry Finger boxnum = rtlhal->last_hmeboxnum;
225b1a3bfc9SLarry Finger switch (boxnum) {
226b1a3bfc9SLarry Finger case 0:
227b1a3bfc9SLarry Finger box_reg = REG_HMEBOX_0;
228b1a3bfc9SLarry Finger box_extreg = REG_HMEBOX_EXT_0;
229b1a3bfc9SLarry Finger break;
230b1a3bfc9SLarry Finger case 1:
231b1a3bfc9SLarry Finger box_reg = REG_HMEBOX_1;
232b1a3bfc9SLarry Finger box_extreg = REG_HMEBOX_EXT_1;
233b1a3bfc9SLarry Finger break;
234b1a3bfc9SLarry Finger case 2:
235b1a3bfc9SLarry Finger box_reg = REG_HMEBOX_2;
236b1a3bfc9SLarry Finger box_extreg = REG_HMEBOX_EXT_2;
237b1a3bfc9SLarry Finger break;
238b1a3bfc9SLarry Finger case 3:
239b1a3bfc9SLarry Finger box_reg = REG_HMEBOX_3;
240b1a3bfc9SLarry Finger box_extreg = REG_HMEBOX_EXT_3;
241b1a3bfc9SLarry Finger break;
242b1a3bfc9SLarry Finger default:
243e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
244ad574889SJoe Perches "switch case %#x not processed\n", boxnum);
245b1a3bfc9SLarry Finger break;
246b1a3bfc9SLarry Finger }
247b1a3bfc9SLarry Finger
248b1a3bfc9SLarry Finger /* 3. Check if the box content is empty. */
249b1a3bfc9SLarry Finger isfw_read = false;
250b1a3bfc9SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_CR);
251b1a3bfc9SLarry Finger
252b1a3bfc9SLarry Finger if (u1b_tmp != 0xea) {
253b1a3bfc9SLarry Finger isfw_read = true;
254b1a3bfc9SLarry Finger } else {
255b1a3bfc9SLarry Finger if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS) == 0xea ||
256b1a3bfc9SLarry Finger rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY) == 0xea)
257b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_CFG1 + 3, 0xff);
258b1a3bfc9SLarry Finger }
259b1a3bfc9SLarry Finger
260b1a3bfc9SLarry Finger if (isfw_read) {
261b1a3bfc9SLarry Finger wait_h2c_limmit = 100;
262b1a3bfc9SLarry Finger isfw_read = _rtl92ee_check_fw_read_last_h2c(hw, boxnum);
263b1a3bfc9SLarry Finger while (!isfw_read) {
264b1a3bfc9SLarry Finger wait_h2c_limmit--;
265b1a3bfc9SLarry Finger if (wait_h2c_limmit == 0) {
266e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
267b1a3bfc9SLarry Finger "Waiting too long for FW read clear HMEBox(%d)!!!\n",
268b1a3bfc9SLarry Finger boxnum);
269b1a3bfc9SLarry Finger break;
270b1a3bfc9SLarry Finger }
271b1a3bfc9SLarry Finger udelay(10);
272b1a3bfc9SLarry Finger isfw_read =
273b1a3bfc9SLarry Finger _rtl92ee_check_fw_read_last_h2c(hw, boxnum);
274b1a3bfc9SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
275e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
276b1a3bfc9SLarry Finger "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
277b1a3bfc9SLarry Finger boxnum, u1b_tmp);
278b1a3bfc9SLarry Finger }
279b1a3bfc9SLarry Finger }
280b1a3bfc9SLarry Finger
281b1a3bfc9SLarry Finger /* If Fw has not read the last
282b1a3bfc9SLarry Finger * H2C cmd, break and give up this H2C.
283b1a3bfc9SLarry Finger */
284b1a3bfc9SLarry Finger if (!isfw_read) {
285e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
286b1a3bfc9SLarry Finger "Write H2C reg BOX[%d] fail,Fw don't read.\n",
287b1a3bfc9SLarry Finger boxnum);
288b1a3bfc9SLarry Finger break;
289b1a3bfc9SLarry Finger }
290b1a3bfc9SLarry Finger /* 4. Fill the H2C cmd into box */
291b1a3bfc9SLarry Finger memset(boxcontent, 0, sizeof(boxcontent));
292b1a3bfc9SLarry Finger memset(boxextcontent, 0, sizeof(boxextcontent));
293b1a3bfc9SLarry Finger boxcontent[0] = element_id;
294e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
295b1a3bfc9SLarry Finger "Write element_id box_reg(%4x) = %2x\n",
296b1a3bfc9SLarry Finger box_reg, element_id);
297b1a3bfc9SLarry Finger
298b1a3bfc9SLarry Finger switch (cmd_len) {
299b1a3bfc9SLarry Finger case 1:
300b1a3bfc9SLarry Finger case 2:
301b1a3bfc9SLarry Finger case 3:
302b1a3bfc9SLarry Finger /*boxcontent[0] &= ~(BIT(7));*/
303b1a3bfc9SLarry Finger memcpy((u8 *)(boxcontent) + 1,
304b1a3bfc9SLarry Finger cmdbuffer + buf_index, cmd_len);
305b1a3bfc9SLarry Finger
306b1a3bfc9SLarry Finger for (idx = 0; idx < 4; idx++) {
307b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, box_reg + idx,
308b1a3bfc9SLarry Finger boxcontent[idx]);
309b1a3bfc9SLarry Finger }
310b1a3bfc9SLarry Finger break;
311b1a3bfc9SLarry Finger case 4:
312b1a3bfc9SLarry Finger case 5:
313b1a3bfc9SLarry Finger case 6:
314b1a3bfc9SLarry Finger case 7:
315b1a3bfc9SLarry Finger /*boxcontent[0] |= (BIT(7));*/
316b1a3bfc9SLarry Finger memcpy((u8 *)(boxextcontent),
317b1a3bfc9SLarry Finger cmdbuffer + buf_index+3, cmd_len-3);
318b1a3bfc9SLarry Finger memcpy((u8 *)(boxcontent) + 1,
319b1a3bfc9SLarry Finger cmdbuffer + buf_index, 3);
320b1a3bfc9SLarry Finger
321b1a3bfc9SLarry Finger for (idx = 0; idx < 4; idx++) {
322b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, box_extreg + idx,
323b1a3bfc9SLarry Finger boxextcontent[idx]);
324b1a3bfc9SLarry Finger }
325b1a3bfc9SLarry Finger
326b1a3bfc9SLarry Finger for (idx = 0; idx < 4; idx++) {
327b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, box_reg + idx,
328b1a3bfc9SLarry Finger boxcontent[idx]);
329b1a3bfc9SLarry Finger }
330b1a3bfc9SLarry Finger break;
331b1a3bfc9SLarry Finger default:
332e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
333ad574889SJoe Perches "switch case %#x not processed\n", cmd_len);
334b1a3bfc9SLarry Finger break;
335b1a3bfc9SLarry Finger }
336b1a3bfc9SLarry Finger
337b1a3bfc9SLarry Finger bwrite_sucess = true;
338b1a3bfc9SLarry Finger
339b1a3bfc9SLarry Finger rtlhal->last_hmeboxnum = boxnum + 1;
340b1a3bfc9SLarry Finger if (rtlhal->last_hmeboxnum == 4)
341b1a3bfc9SLarry Finger rtlhal->last_hmeboxnum = 0;
342b1a3bfc9SLarry Finger
343e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
344b1a3bfc9SLarry Finger "pHalData->last_hmeboxnum = %d\n",
345b1a3bfc9SLarry Finger rtlhal->last_hmeboxnum);
346b1a3bfc9SLarry Finger }
347b1a3bfc9SLarry Finger
348b1a3bfc9SLarry Finger spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
349b1a3bfc9SLarry Finger rtlhal->h2c_setinprogress = false;
350b1a3bfc9SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
351b1a3bfc9SLarry Finger
352e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
353b1a3bfc9SLarry Finger }
354b1a3bfc9SLarry Finger
rtl92ee_fill_h2c_cmd(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * cmdbuffer)355b1a3bfc9SLarry Finger void rtl92ee_fill_h2c_cmd(struct ieee80211_hw *hw,
356b1a3bfc9SLarry Finger u8 element_id, u32 cmd_len, u8 *cmdbuffer)
357b1a3bfc9SLarry Finger {
358b1a3bfc9SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
359b1a3bfc9SLarry Finger u32 tmp_cmdbuf[2];
360b1a3bfc9SLarry Finger
361b1a3bfc9SLarry Finger if (!rtlhal->fw_ready) {
362531940f9SLarry Finger WARN_ONCE(true,
363531940f9SLarry Finger "rtl8192ee: error H2C cmd because of Fw download fail!!!\n");
364b1a3bfc9SLarry Finger return;
365b1a3bfc9SLarry Finger }
366b1a3bfc9SLarry Finger
367b1a3bfc9SLarry Finger memset(tmp_cmdbuf, 0, 8);
368b1a3bfc9SLarry Finger memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
369b1a3bfc9SLarry Finger _rtl92ee_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
370b1a3bfc9SLarry Finger }
371b1a3bfc9SLarry Finger
rtl92ee_firmware_selfreset(struct ieee80211_hw * hw)372b1a3bfc9SLarry Finger void rtl92ee_firmware_selfreset(struct ieee80211_hw *hw)
373b1a3bfc9SLarry Finger {
374b1a3bfc9SLarry Finger u8 u1b_tmp;
375b1a3bfc9SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
376b1a3bfc9SLarry Finger
377b1a3bfc9SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
378b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
379b1a3bfc9SLarry Finger
380b1a3bfc9SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
381b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
382b1a3bfc9SLarry Finger
383b1a3bfc9SLarry Finger udelay(50);
384b1a3bfc9SLarry Finger
385b1a3bfc9SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
386b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0)));
387b1a3bfc9SLarry Finger
388b1a3bfc9SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
389b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2)));
390b1a3bfc9SLarry Finger
391e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
392b1a3bfc9SLarry Finger " _8051Reset92E(): 8051 reset success .\n");
393b1a3bfc9SLarry Finger }
394b1a3bfc9SLarry Finger
rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw * hw,u8 mode)395b1a3bfc9SLarry Finger void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
396b1a3bfc9SLarry Finger {
397b1a3bfc9SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
398b1a3bfc9SLarry Finger u8 u1_h2c_set_pwrmode[H2C_92E_PWEMODE_LENGTH] = { 0 };
399b1a3bfc9SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
40042213f2fSPing-Ke Shih u8 rlbm, power_state = 0, byte5 = 0;
40142213f2fSPing-Ke Shih u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
40254685f9cSPing-Ke Shih struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
40342213f2fSPing-Ke Shih bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
40442213f2fSPing-Ke Shih btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
405135f4fbdSPing-Ke Shih bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
406135f4fbdSPing-Ke Shih btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
407135f4fbdSPing-Ke Shih
408135f4fbdSPing-Ke Shih if (bt_ctrl_lps)
409135f4fbdSPing-Ke Shih mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
410b1a3bfc9SLarry Finger
411e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
41242213f2fSPing-Ke Shih mode, bt_ctrl_lps);
41342213f2fSPing-Ke Shih
41442213f2fSPing-Ke Shih switch (mode) {
41542213f2fSPing-Ke Shih case FW_PS_MIN_MODE:
41642213f2fSPing-Ke Shih rlbm = 0;
41742213f2fSPing-Ke Shih awake_intvl = 2;
41842213f2fSPing-Ke Shih break;
41942213f2fSPing-Ke Shih case FW_PS_MAX_MODE:
42042213f2fSPing-Ke Shih rlbm = 1;
42142213f2fSPing-Ke Shih awake_intvl = 2;
42242213f2fSPing-Ke Shih break;
42342213f2fSPing-Ke Shih case FW_PS_DTIM_MODE:
42442213f2fSPing-Ke Shih rlbm = 2;
42542213f2fSPing-Ke Shih awake_intvl = ppsc->reg_max_lps_awakeintvl;
42642213f2fSPing-Ke Shih /* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
42742213f2fSPing-Ke Shih * is only used in swlps.
42842213f2fSPing-Ke Shih */
42942213f2fSPing-Ke Shih break;
43042213f2fSPing-Ke Shih default:
43142213f2fSPing-Ke Shih rlbm = 2;
43242213f2fSPing-Ke Shih awake_intvl = 4;
43342213f2fSPing-Ke Shih break;
43442213f2fSPing-Ke Shih }
43542213f2fSPing-Ke Shih
43642213f2fSPing-Ke Shih if (rtlpriv->mac80211.p2p) {
43742213f2fSPing-Ke Shih awake_intvl = 2;
43842213f2fSPing-Ke Shih rlbm = 1;
43942213f2fSPing-Ke Shih }
44042213f2fSPing-Ke Shih
44142213f2fSPing-Ke Shih if (mode == FW_PS_ACTIVE_MODE) {
44242213f2fSPing-Ke Shih byte5 = 0x40;
44342213f2fSPing-Ke Shih power_state = FW_PWR_STATE_ACTIVE;
44442213f2fSPing-Ke Shih } else {
44542213f2fSPing-Ke Shih if (bt_ctrl_lps) {
44642213f2fSPing-Ke Shih byte5 = btc_ops->btc_get_lps_val(rtlpriv);
44742213f2fSPing-Ke Shih power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
44842213f2fSPing-Ke Shih
44942213f2fSPing-Ke Shih if ((rlbm == 2) && (byte5 & BIT(4))) {
45042213f2fSPing-Ke Shih /* Keep awake interval to 1 to prevent from
45142213f2fSPing-Ke Shih * decreasing coex performance
45242213f2fSPing-Ke Shih */
45342213f2fSPing-Ke Shih awake_intvl = 2;
45442213f2fSPing-Ke Shih rlbm = 2;
45542213f2fSPing-Ke Shih }
45642213f2fSPing-Ke Shih } else {
45742213f2fSPing-Ke Shih byte5 = 0x40;
45842213f2fSPing-Ke Shih power_state = FW_PWR_STATE_RF_OFF;
45942213f2fSPing-Ke Shih }
46042213f2fSPing-Ke Shih }
461b1a3bfc9SLarry Finger
462b1a3bfc9SLarry Finger SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
463b1a3bfc9SLarry Finger SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
464b1a3bfc9SLarry Finger SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
465135f4fbdSPing-Ke Shih bt_ctrl_lps ? 0 :
466135f4fbdSPing-Ke Shih ((rtlpriv->mac80211.p2p) ?
467135f4fbdSPing-Ke Shih ppsc->smart_ps : 1));
468b1a3bfc9SLarry Finger SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
46942213f2fSPing-Ke Shih awake_intvl);
470b1a3bfc9SLarry Finger SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
471b1a3bfc9SLarry Finger SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
47254685f9cSPing-Ke Shih SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
473b1a3bfc9SLarry Finger
474b1a3bfc9SLarry Finger RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
475b1a3bfc9SLarry Finger "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
476b1a3bfc9SLarry Finger u1_h2c_set_pwrmode, H2C_92E_PWEMODE_LENGTH);
47754685f9cSPing-Ke Shih if (rtlpriv->cfg->ops->get_btc_status())
47854685f9cSPing-Ke Shih btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
47954685f9cSPing-Ke Shih H2C_92E_PWEMODE_LENGTH);
480b1a3bfc9SLarry Finger rtl92ee_fill_h2c_cmd(hw, H2C_92E_SETPWRMODE, H2C_92E_PWEMODE_LENGTH,
481b1a3bfc9SLarry Finger u1_h2c_set_pwrmode);
482b1a3bfc9SLarry Finger }
483b1a3bfc9SLarry Finger
rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw * hw,u8 mstatus)484b1a3bfc9SLarry Finger void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
485b1a3bfc9SLarry Finger {
486b1a3bfc9SLarry Finger u8 parm[3] = { 0 , 0 , 0 };
487b1a3bfc9SLarry Finger /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
488b1a3bfc9SLarry Finger * bit1=0-->update Media Status to MACID
489b1a3bfc9SLarry Finger * bit1=1-->update Media Status from MACID to MACID_End
490b1a3bfc9SLarry Finger * parm[1]: MACID, if this is INFRA_STA, MacID = 0
491b1a3bfc9SLarry Finger * parm[2]: MACID_End
492b1a3bfc9SLarry Finger */
493b1a3bfc9SLarry Finger
494b1a3bfc9SLarry Finger SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
495b1a3bfc9SLarry Finger SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
496b1a3bfc9SLarry Finger
497b1a3bfc9SLarry Finger rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm);
498b1a3bfc9SLarry Finger }
499b1a3bfc9SLarry Finger
500b1a3bfc9SLarry Finger #define BEACON_PG 0 /* ->1 */
501b1a3bfc9SLarry Finger #define PSPOLL_PG 2
502b1a3bfc9SLarry Finger #define NULL_PG 3
503b1a3bfc9SLarry Finger #define PROBERSP_PG 4 /* ->5 */
50474a7dfbcSPing-Ke Shih #define QOS_NULL_PG 6
50574a7dfbcSPing-Ke Shih #define BT_QOS_NULL_PG 7
506b1a3bfc9SLarry Finger
50774a7dfbcSPing-Ke Shih #define TOTAL_RESERVED_PKT_LEN 1024
508b1a3bfc9SLarry Finger
509b1a3bfc9SLarry Finger static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
510b1a3bfc9SLarry Finger /* page 0 beacon */
511b1a3bfc9SLarry Finger 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
512b1a3bfc9SLarry Finger 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
513b1a3bfc9SLarry Finger 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
514b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515b1a3bfc9SLarry Finger 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
516b1a3bfc9SLarry Finger 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
517b1a3bfc9SLarry Finger 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
518b1a3bfc9SLarry Finger 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
519b1a3bfc9SLarry Finger 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
520b1a3bfc9SLarry Finger 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
521b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
523b1a3bfc9SLarry Finger 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
524b1a3bfc9SLarry Finger 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
525b1a3bfc9SLarry Finger 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
526b1a3bfc9SLarry Finger 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
527b1a3bfc9SLarry Finger
528b1a3bfc9SLarry Finger /* page 1 beacon */
529b1a3bfc9SLarry Finger 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
530b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
533b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540b1a3bfc9SLarry Finger 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
541b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
542b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545b1a3bfc9SLarry Finger
546b1a3bfc9SLarry Finger /* page 2 ps-poll */
547b1a3bfc9SLarry Finger 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
548b1a3bfc9SLarry Finger 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
549b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558b1a3bfc9SLarry Finger 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
559b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
560b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562b1a3bfc9SLarry Finger 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563b1a3bfc9SLarry Finger
564b1a3bfc9SLarry Finger /* page 3 null */
565b1a3bfc9SLarry Finger 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
566b1a3bfc9SLarry Finger 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
567b1a3bfc9SLarry Finger 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
568b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576b1a3bfc9SLarry Finger 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
577b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
578b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580b1a3bfc9SLarry Finger 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581b1a3bfc9SLarry Finger
582b1a3bfc9SLarry Finger /* page 4 probe_resp */
583b1a3bfc9SLarry Finger 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
584b1a3bfc9SLarry Finger 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
585b1a3bfc9SLarry Finger 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
586b1a3bfc9SLarry Finger 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
587b1a3bfc9SLarry Finger 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
588b1a3bfc9SLarry Finger 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
589b1a3bfc9SLarry Finger 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
590b1a3bfc9SLarry Finger 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
591b1a3bfc9SLarry Finger 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
592b1a3bfc9SLarry Finger 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
593b1a3bfc9SLarry Finger 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596b1a3bfc9SLarry Finger 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
597b1a3bfc9SLarry Finger 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599b1a3bfc9SLarry Finger
600b1a3bfc9SLarry Finger /* page 5 probe_resp */
601b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60874a7dfbcSPing-Ke Shih 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
60974a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
61074a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61174a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61274a7dfbcSPing-Ke Shih 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61374a7dfbcSPing-Ke Shih
61474a7dfbcSPing-Ke Shih /* page 6 qos null data */
61574a7dfbcSPing-Ke Shih 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
61674a7dfbcSPing-Ke Shih 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
61774a7dfbcSPing-Ke Shih 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
61874a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61974a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62074a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62174a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62274a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62374a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62474a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62574a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62674a7dfbcSPing-Ke Shih 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
62774a7dfbcSPing-Ke Shih 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
62874a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62974a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63074a7dfbcSPing-Ke Shih 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63174a7dfbcSPing-Ke Shih
63274a7dfbcSPing-Ke Shih /* page 7 BT-qos null data */
63374a7dfbcSPing-Ke Shih 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
63474a7dfbcSPing-Ke Shih 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
63574a7dfbcSPing-Ke Shih 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
63674a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63774a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63874a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63974a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64074a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64174a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64274a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64374a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652b1a3bfc9SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653b1a3bfc9SLarry Finger };
654b1a3bfc9SLarry Finger
rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw * hw,bool b_dl_finished)655b1a3bfc9SLarry Finger void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
656b1a3bfc9SLarry Finger {
657b1a3bfc9SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
658b1a3bfc9SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
659b1a3bfc9SLarry Finger struct sk_buff *skb = NULL;
660519ce2f9SLarry Finger bool rtstatus;
661b1a3bfc9SLarry Finger u32 totalpacketlen;
662b1a3bfc9SLarry Finger u8 u1rsvdpageloc[5] = { 0 };
663b1a3bfc9SLarry Finger bool b_dlok = false;
664b1a3bfc9SLarry Finger
665b1a3bfc9SLarry Finger u8 *beacon;
666b1a3bfc9SLarry Finger u8 *p_pspoll;
667b1a3bfc9SLarry Finger u8 *nullfunc;
668b1a3bfc9SLarry Finger u8 *p_probersp;
66974a7dfbcSPing-Ke Shih u8 *qosnull;
67074a7dfbcSPing-Ke Shih u8 *btqosnull;
671b1a3bfc9SLarry Finger /*---------------------------------------------------------
672b1a3bfc9SLarry Finger * (1) beacon
673b1a3bfc9SLarry Finger *---------------------------------------------------------
674b1a3bfc9SLarry Finger */
675b1a3bfc9SLarry Finger beacon = &reserved_page_packet[BEACON_PG * 128];
676b1a3bfc9SLarry Finger SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
677b1a3bfc9SLarry Finger SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
678b1a3bfc9SLarry Finger
679b1a3bfc9SLarry Finger /*-------------------------------------------------------
680b1a3bfc9SLarry Finger * (2) ps-poll
681b1a3bfc9SLarry Finger *--------------------------------------------------------
682b1a3bfc9SLarry Finger */
683b1a3bfc9SLarry Finger p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
684b1a3bfc9SLarry Finger SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
685b1a3bfc9SLarry Finger SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
686b1a3bfc9SLarry Finger SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
687b1a3bfc9SLarry Finger
688b1a3bfc9SLarry Finger SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
689b1a3bfc9SLarry Finger
690b1a3bfc9SLarry Finger /*--------------------------------------------------------
691b1a3bfc9SLarry Finger * (3) null data
692b1a3bfc9SLarry Finger *---------------------------------------------------------
693b1a3bfc9SLarry Finger */
694b1a3bfc9SLarry Finger nullfunc = &reserved_page_packet[NULL_PG * 128];
695b1a3bfc9SLarry Finger SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
696b1a3bfc9SLarry Finger SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
697b1a3bfc9SLarry Finger SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
698b1a3bfc9SLarry Finger
699b1a3bfc9SLarry Finger SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
700b1a3bfc9SLarry Finger
701b1a3bfc9SLarry Finger /*---------------------------------------------------------
702b1a3bfc9SLarry Finger * (4) probe response
703b1a3bfc9SLarry Finger *----------------------------------------------------------
704b1a3bfc9SLarry Finger */
705b1a3bfc9SLarry Finger p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
706b1a3bfc9SLarry Finger SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
707b1a3bfc9SLarry Finger SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
708b1a3bfc9SLarry Finger SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
709b1a3bfc9SLarry Finger
710b1a3bfc9SLarry Finger SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
711b1a3bfc9SLarry Finger
71274a7dfbcSPing-Ke Shih /*---------------------------------------------------------
71374a7dfbcSPing-Ke Shih * (5) QoS null data
71474a7dfbcSPing-Ke Shih *----------------------------------------------------------
71574a7dfbcSPing-Ke Shih */
71674a7dfbcSPing-Ke Shih qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
71774a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
71874a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
71974a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
72074a7dfbcSPing-Ke Shih
72174a7dfbcSPing-Ke Shih SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
72274a7dfbcSPing-Ke Shih
72374a7dfbcSPing-Ke Shih /*---------------------------------------------------------
72474a7dfbcSPing-Ke Shih * (6) BT QoS null data
72574a7dfbcSPing-Ke Shih *----------------------------------------------------------
72674a7dfbcSPing-Ke Shih */
72774a7dfbcSPing-Ke Shih btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
72874a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
72974a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
73074a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
73174a7dfbcSPing-Ke Shih
73274a7dfbcSPing-Ke Shih SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
73374a7dfbcSPing-Ke Shih
734b1a3bfc9SLarry Finger totalpacketlen = TOTAL_RESERVED_PKT_LEN;
735b1a3bfc9SLarry Finger
736b1a3bfc9SLarry Finger RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
737b1a3bfc9SLarry Finger "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
738b1a3bfc9SLarry Finger &reserved_page_packet[0], totalpacketlen);
739b1a3bfc9SLarry Finger RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
740b1a3bfc9SLarry Finger "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
741b1a3bfc9SLarry Finger u1rsvdpageloc, 3);
742b1a3bfc9SLarry Finger
743b1a3bfc9SLarry Finger skb = dev_alloc_skb(totalpacketlen);
74460209d48SPing-Ke Shih if (!skb)
74560209d48SPing-Ke Shih return;
746ad941e69Syuan linyu skb_put_data(skb, &reserved_page_packet, totalpacketlen);
747b1a3bfc9SLarry Finger
748519ce2f9SLarry Finger rtstatus = rtl_cmd_send_packet(hw, skb);
749519ce2f9SLarry Finger if (rtstatus)
750b1a3bfc9SLarry Finger b_dlok = true;
751b1a3bfc9SLarry Finger
752b1a3bfc9SLarry Finger if (b_dlok) {
753e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
754b1a3bfc9SLarry Finger "Set RSVD page location to Fw.\n");
755b1a3bfc9SLarry Finger RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
756b1a3bfc9SLarry Finger "H2C_RSVDPAGE:\n", u1rsvdpageloc, 3);
757b1a3bfc9SLarry Finger rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSVDPAGE,
758b1a3bfc9SLarry Finger sizeof(u1rsvdpageloc), u1rsvdpageloc);
759b1a3bfc9SLarry Finger } else {
760e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
761b1a3bfc9SLarry Finger "Set RSVD page location to Fw FAIL!!!!!!.\n");
762b1a3bfc9SLarry Finger }
763b1a3bfc9SLarry Finger }
764b1a3bfc9SLarry Finger
765b1a3bfc9SLarry Finger /*Shoud check FW support p2p or not.*/
rtl92ee_set_p2p_ctw_period_cmd(struct ieee80211_hw * hw,u8 ctwindow)766b1a3bfc9SLarry Finger static void rtl92ee_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
767b1a3bfc9SLarry Finger {
768b1a3bfc9SLarry Finger u8 u1_ctwindow_period[1] = {ctwindow};
769b1a3bfc9SLarry Finger
770b1a3bfc9SLarry Finger rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
771b1a3bfc9SLarry Finger }
772b1a3bfc9SLarry Finger
rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw * hw,u8 p2p_ps_state)773b1a3bfc9SLarry Finger void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
774b1a3bfc9SLarry Finger {
775b1a3bfc9SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
776b1a3bfc9SLarry Finger struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
777b1a3bfc9SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
778b1a3bfc9SLarry Finger struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
779b1a3bfc9SLarry Finger struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
780b1a3bfc9SLarry Finger u8 i;
781b1a3bfc9SLarry Finger u16 ctwindow;
782b1a3bfc9SLarry Finger u32 start_time, tsf_low;
783b1a3bfc9SLarry Finger
784b1a3bfc9SLarry Finger switch (p2p_ps_state) {
785b1a3bfc9SLarry Finger case P2P_PS_DISABLE:
786e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
787b1a3bfc9SLarry Finger memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
788b1a3bfc9SLarry Finger break;
789b1a3bfc9SLarry Finger case P2P_PS_ENABLE:
790e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
791b1a3bfc9SLarry Finger /* update CTWindow value. */
792b1a3bfc9SLarry Finger if (p2pinfo->ctwindow > 0) {
793b1a3bfc9SLarry Finger p2p_ps_offload->ctwindow_en = 1;
794b1a3bfc9SLarry Finger ctwindow = p2pinfo->ctwindow;
795b1a3bfc9SLarry Finger rtl92ee_set_p2p_ctw_period_cmd(hw, ctwindow);
796b1a3bfc9SLarry Finger }
797b1a3bfc9SLarry Finger /* hw only support 2 set of NoA */
798b1a3bfc9SLarry Finger for (i = 0 ; i < p2pinfo->noa_num ; i++) {
799b1a3bfc9SLarry Finger /* To control the register setting for which NOA*/
800b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
801b1a3bfc9SLarry Finger if (i == 0)
802b1a3bfc9SLarry Finger p2p_ps_offload->noa0_en = 1;
803b1a3bfc9SLarry Finger else
804b1a3bfc9SLarry Finger p2p_ps_offload->noa1_en = 1;
805b1a3bfc9SLarry Finger /* config P2P NoA Descriptor Register */
806b1a3bfc9SLarry Finger rtl_write_dword(rtlpriv, 0x5E0,
807b1a3bfc9SLarry Finger p2pinfo->noa_duration[i]);
808b1a3bfc9SLarry Finger rtl_write_dword(rtlpriv, 0x5E4,
809b1a3bfc9SLarry Finger p2pinfo->noa_interval[i]);
810b1a3bfc9SLarry Finger
811b1a3bfc9SLarry Finger /*Get Current TSF value */
812b1a3bfc9SLarry Finger tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
813b1a3bfc9SLarry Finger
814b1a3bfc9SLarry Finger start_time = p2pinfo->noa_start_time[i];
815b1a3bfc9SLarry Finger if (p2pinfo->noa_count_type[i] != 1) {
816b1a3bfc9SLarry Finger while (start_time <= (tsf_low + (50 * 1024))) {
817b1a3bfc9SLarry Finger start_time += p2pinfo->noa_interval[i];
818b1a3bfc9SLarry Finger if (p2pinfo->noa_count_type[i] != 255)
819b1a3bfc9SLarry Finger p2pinfo->noa_count_type[i]--;
820b1a3bfc9SLarry Finger }
821b1a3bfc9SLarry Finger }
822b1a3bfc9SLarry Finger rtl_write_dword(rtlpriv, 0x5E8, start_time);
823b1a3bfc9SLarry Finger rtl_write_dword(rtlpriv, 0x5EC,
824b1a3bfc9SLarry Finger p2pinfo->noa_count_type[i]);
825b1a3bfc9SLarry Finger }
826b1a3bfc9SLarry Finger if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
827b1a3bfc9SLarry Finger /* rst p2p circuit */
828b1a3bfc9SLarry Finger rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
829b1a3bfc9SLarry Finger p2p_ps_offload->offload_en = 1;
830b1a3bfc9SLarry Finger
831b1a3bfc9SLarry Finger if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
832b1a3bfc9SLarry Finger p2p_ps_offload->role = 1;
833b1a3bfc9SLarry Finger p2p_ps_offload->allstasleep = 0;
834b1a3bfc9SLarry Finger } else {
835b1a3bfc9SLarry Finger p2p_ps_offload->role = 0;
836b1a3bfc9SLarry Finger }
837b1a3bfc9SLarry Finger p2p_ps_offload->discovery = 0;
838b1a3bfc9SLarry Finger }
839b1a3bfc9SLarry Finger break;
840b1a3bfc9SLarry Finger case P2P_PS_SCAN:
841e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
842b1a3bfc9SLarry Finger p2p_ps_offload->discovery = 1;
843b1a3bfc9SLarry Finger break;
844b1a3bfc9SLarry Finger case P2P_PS_SCAN_DONE:
845e24a2a87SLarry Finger rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
846b1a3bfc9SLarry Finger p2p_ps_offload->discovery = 0;
847b1a3bfc9SLarry Finger p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
848b1a3bfc9SLarry Finger break;
849b1a3bfc9SLarry Finger default:
850b1a3bfc9SLarry Finger break;
851b1a3bfc9SLarry Finger }
852b1a3bfc9SLarry Finger rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_OFFLOAD, 1,
853b1a3bfc9SLarry Finger (u8 *)p2p_ps_offload);
854b1a3bfc9SLarry Finger }
855b1a3bfc9SLarry Finger
rtl92ee_c2h_ra_report_handler(struct ieee80211_hw * hw,u8 * cmd_buf,u8 cmd_len)85616cefa44SPing-Ke Shih void rtl92ee_c2h_ra_report_handler(struct ieee80211_hw *hw,
857b1a3bfc9SLarry Finger u8 *cmd_buf, u8 cmd_len)
858b1a3bfc9SLarry Finger {
859b1a3bfc9SLarry Finger u8 rate = cmd_buf[0] & 0x3F;
860b1a3bfc9SLarry Finger bool collision_state = cmd_buf[3] & BIT(0);
861b1a3bfc9SLarry Finger
862b1a3bfc9SLarry Finger rtl92ee_dm_dynamic_arfb_select(hw, rate, collision_state);
863b1a3bfc9SLarry Finger }
864