xref: /openbmc/linux/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c (revision cbecf716ca618fd44feda6bd9a64a8179d031fc5)
148fa0b4dSLarry Finger // SPDX-License-Identifier: GPL-2.0
248fa0b4dSLarry Finger /* Copyright(c) 2009-2012  Realtek Corporation.*/
3f1d2b4d3SLarry Finger 
4f1d2b4d3SLarry Finger #include "../wifi.h"
5f1d2b4d3SLarry Finger #include "../pci.h"
6f1d2b4d3SLarry Finger #include "../base.h"
7f1d2b4d3SLarry Finger #include "../core.h"
8f1d2b4d3SLarry Finger #include "reg.h"
9f1d2b4d3SLarry Finger #include "def.h"
10f1d2b4d3SLarry Finger #include "fw.h"
11f1d2b4d3SLarry Finger #include "../rtl8723com/fw_common.h"
12f1d2b4d3SLarry Finger 
_rtl8723e_check_fw_read_last_h2c(struct ieee80211_hw * hw,u8 boxnum)13f1d2b4d3SLarry Finger static bool _rtl8723e_check_fw_read_last_h2c(struct ieee80211_hw *hw,
14f1d2b4d3SLarry Finger 					     u8 boxnum)
15f1d2b4d3SLarry Finger {
16f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = rtl_priv(hw);
17f1d2b4d3SLarry Finger 	u8 val_hmetfr, val_mcutst_1;
18f1d2b4d3SLarry Finger 	bool result = false;
19f1d2b4d3SLarry Finger 
20f1d2b4d3SLarry Finger 	val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
21f1d2b4d3SLarry Finger 	val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
22f1d2b4d3SLarry Finger 
23f1d2b4d3SLarry Finger 	if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
24f1d2b4d3SLarry Finger 		result = true;
25f1d2b4d3SLarry Finger 	return result;
26f1d2b4d3SLarry Finger }
27f1d2b4d3SLarry Finger 
_rtl8723e_fill_h2c_command(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * cmdbuffer)28f1d2b4d3SLarry Finger static void _rtl8723e_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
29f1d2b4d3SLarry Finger 				       u32 cmd_len, u8 *cmdbuffer)
30f1d2b4d3SLarry Finger {
31f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = rtl_priv(hw);
32f1d2b4d3SLarry Finger 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
33f1d2b4d3SLarry Finger 	u8 boxnum;
34f1d2b4d3SLarry Finger 	u16 box_reg = 0, box_extreg = 0;
35f1d2b4d3SLarry Finger 	u8 u1b_tmp;
36f1d2b4d3SLarry Finger 	bool isfw_read = false;
37f1d2b4d3SLarry Finger 	u8 buf_index = 0;
38f1d2b4d3SLarry Finger 	bool bwrite_sucess = false;
39f1d2b4d3SLarry Finger 	u8 wait_h2c_limmit = 100;
40f1d2b4d3SLarry Finger 	u8 wait_writeh2c_limmit = 100;
41f1d2b4d3SLarry Finger 	u8 boxcontent[4], boxextcontent[2];
42f1d2b4d3SLarry Finger 	u32 h2c_waitcounter = 0;
43f1d2b4d3SLarry Finger 	unsigned long flag;
44f1d2b4d3SLarry Finger 	u8 idx;
45f1d2b4d3SLarry Finger 
46*8f11dad4SLarry Finger 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
47f1d2b4d3SLarry Finger 
48f1d2b4d3SLarry Finger 	while (true) {
49f1d2b4d3SLarry Finger 		spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
50f1d2b4d3SLarry Finger 		if (rtlhal->h2c_setinprogress) {
51*8f11dad4SLarry Finger 			rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
52f1d2b4d3SLarry Finger 				"H2C set in progress! Wait to set..element_id(%d).\n",
53f1d2b4d3SLarry Finger 				element_id);
54f1d2b4d3SLarry Finger 
55f1d2b4d3SLarry Finger 			while (rtlhal->h2c_setinprogress) {
56f1d2b4d3SLarry Finger 				spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
57f1d2b4d3SLarry Finger 						       flag);
58f1d2b4d3SLarry Finger 				h2c_waitcounter++;
59*8f11dad4SLarry Finger 				rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
60f1d2b4d3SLarry Finger 					"Wait 100 us (%d times)...\n",
61f1d2b4d3SLarry Finger 					h2c_waitcounter);
62f1d2b4d3SLarry Finger 				udelay(100);
63f1d2b4d3SLarry Finger 
64f1d2b4d3SLarry Finger 				if (h2c_waitcounter > 1000)
65f1d2b4d3SLarry Finger 					return;
66f1d2b4d3SLarry Finger 				spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
67f1d2b4d3SLarry Finger 						  flag);
68f1d2b4d3SLarry Finger 			}
69f1d2b4d3SLarry Finger 			spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
70f1d2b4d3SLarry Finger 		} else {
71f1d2b4d3SLarry Finger 			rtlhal->h2c_setinprogress = true;
72f1d2b4d3SLarry Finger 			spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
73f1d2b4d3SLarry Finger 			break;
74f1d2b4d3SLarry Finger 		}
75f1d2b4d3SLarry Finger 	}
76f1d2b4d3SLarry Finger 
77f1d2b4d3SLarry Finger 	while (!bwrite_sucess) {
78f1d2b4d3SLarry Finger 		wait_writeh2c_limmit--;
79f1d2b4d3SLarry Finger 		if (wait_writeh2c_limmit == 0) {
80a67005bcSLarry Finger 			pr_err("Write H2C fail because no trigger for FW INT!\n");
81f1d2b4d3SLarry Finger 			break;
82f1d2b4d3SLarry Finger 		}
83f1d2b4d3SLarry Finger 
84f1d2b4d3SLarry Finger 		boxnum = rtlhal->last_hmeboxnum;
85f1d2b4d3SLarry Finger 		switch (boxnum) {
86f1d2b4d3SLarry Finger 		case 0:
87f1d2b4d3SLarry Finger 			box_reg = REG_HMEBOX_0;
88f1d2b4d3SLarry Finger 			box_extreg = REG_HMEBOX_EXT_0;
89f1d2b4d3SLarry Finger 			break;
90f1d2b4d3SLarry Finger 		case 1:
91f1d2b4d3SLarry Finger 			box_reg = REG_HMEBOX_1;
92f1d2b4d3SLarry Finger 			box_extreg = REG_HMEBOX_EXT_1;
93f1d2b4d3SLarry Finger 			break;
94f1d2b4d3SLarry Finger 		case 2:
95f1d2b4d3SLarry Finger 			box_reg = REG_HMEBOX_2;
96f1d2b4d3SLarry Finger 			box_extreg = REG_HMEBOX_EXT_2;
97f1d2b4d3SLarry Finger 			break;
98f1d2b4d3SLarry Finger 		case 3:
99f1d2b4d3SLarry Finger 			box_reg = REG_HMEBOX_3;
100f1d2b4d3SLarry Finger 			box_extreg = REG_HMEBOX_EXT_3;
101f1d2b4d3SLarry Finger 			break;
102f1d2b4d3SLarry Finger 		default:
103a67005bcSLarry Finger 			pr_err("switch case %#x not processed\n",
104a67005bcSLarry Finger 			       boxnum);
105f1d2b4d3SLarry Finger 			break;
106f1d2b4d3SLarry Finger 		}
107f1d2b4d3SLarry Finger 
108f1d2b4d3SLarry Finger 		isfw_read = _rtl8723e_check_fw_read_last_h2c(hw, boxnum);
109f1d2b4d3SLarry Finger 		while (!isfw_read) {
110f1d2b4d3SLarry Finger 
111f1d2b4d3SLarry Finger 			wait_h2c_limmit--;
112f1d2b4d3SLarry Finger 			if (wait_h2c_limmit == 0) {
113*8f11dad4SLarry Finger 				rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
1149165dabbSMasanari Iida 					"Waiting too long for FW read clear HMEBox(%d)!\n",
115f1d2b4d3SLarry Finger 					boxnum);
116f1d2b4d3SLarry Finger 				break;
117f1d2b4d3SLarry Finger 			}
118f1d2b4d3SLarry Finger 
119f1d2b4d3SLarry Finger 			udelay(10);
120f1d2b4d3SLarry Finger 
121f1d2b4d3SLarry Finger 			isfw_read = _rtl8723e_check_fw_read_last_h2c(hw,
122f1d2b4d3SLarry Finger 								boxnum);
123f1d2b4d3SLarry Finger 			u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
124*8f11dad4SLarry Finger 			rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
125f1d2b4d3SLarry Finger 				"Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
126f1d2b4d3SLarry Finger 				boxnum, u1b_tmp);
127f1d2b4d3SLarry Finger 		}
128f1d2b4d3SLarry Finger 
129f1d2b4d3SLarry Finger 		if (!isfw_read) {
130*8f11dad4SLarry Finger 			rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
131f1d2b4d3SLarry Finger 				"Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
132f1d2b4d3SLarry Finger 				boxnum);
133f1d2b4d3SLarry Finger 			break;
134f1d2b4d3SLarry Finger 		}
135f1d2b4d3SLarry Finger 
136f1d2b4d3SLarry Finger 		memset(boxcontent, 0, sizeof(boxcontent));
137f1d2b4d3SLarry Finger 		memset(boxextcontent, 0, sizeof(boxextcontent));
138f1d2b4d3SLarry Finger 		boxcontent[0] = element_id;
139*8f11dad4SLarry Finger 		rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
140f1d2b4d3SLarry Finger 			"Write element_id box_reg(%4x) = %2x\n",
141f1d2b4d3SLarry Finger 			box_reg, element_id);
142f1d2b4d3SLarry Finger 
143f1d2b4d3SLarry Finger 		switch (cmd_len) {
144f1d2b4d3SLarry Finger 		case 1:
145f1d2b4d3SLarry Finger 			boxcontent[0] &= ~(BIT(7));
146f1d2b4d3SLarry Finger 			memcpy((u8 *)(boxcontent) + 1,
147f1d2b4d3SLarry Finger 			       cmdbuffer + buf_index, 1);
148f1d2b4d3SLarry Finger 
149f1d2b4d3SLarry Finger 			for (idx = 0; idx < 4; idx++) {
150f1d2b4d3SLarry Finger 				rtl_write_byte(rtlpriv, box_reg + idx,
151f1d2b4d3SLarry Finger 					       boxcontent[idx]);
152f1d2b4d3SLarry Finger 			}
153f1d2b4d3SLarry Finger 			break;
154f1d2b4d3SLarry Finger 		case 2:
155f1d2b4d3SLarry Finger 			boxcontent[0] &= ~(BIT(7));
156f1d2b4d3SLarry Finger 			memcpy((u8 *)(boxcontent) + 1,
157f1d2b4d3SLarry Finger 			       cmdbuffer + buf_index, 2);
158f1d2b4d3SLarry Finger 
159f1d2b4d3SLarry Finger 			for (idx = 0; idx < 4; idx++) {
160f1d2b4d3SLarry Finger 				rtl_write_byte(rtlpriv, box_reg + idx,
161f1d2b4d3SLarry Finger 					       boxcontent[idx]);
162f1d2b4d3SLarry Finger 			}
163f1d2b4d3SLarry Finger 			break;
164f1d2b4d3SLarry Finger 		case 3:
165f1d2b4d3SLarry Finger 			boxcontent[0] &= ~(BIT(7));
166f1d2b4d3SLarry Finger 			memcpy((u8 *)(boxcontent) + 1,
167f1d2b4d3SLarry Finger 			       cmdbuffer + buf_index, 3);
168f1d2b4d3SLarry Finger 
169f1d2b4d3SLarry Finger 			for (idx = 0; idx < 4; idx++) {
170f1d2b4d3SLarry Finger 				rtl_write_byte(rtlpriv, box_reg + idx,
171f1d2b4d3SLarry Finger 					       boxcontent[idx]);
172f1d2b4d3SLarry Finger 			}
173f1d2b4d3SLarry Finger 			break;
174f1d2b4d3SLarry Finger 		case 4:
175f1d2b4d3SLarry Finger 			boxcontent[0] |= (BIT(7));
176f1d2b4d3SLarry Finger 			memcpy((u8 *)(boxextcontent),
177f1d2b4d3SLarry Finger 			       cmdbuffer + buf_index, 2);
178f1d2b4d3SLarry Finger 			memcpy((u8 *)(boxcontent) + 1,
179f1d2b4d3SLarry Finger 			       cmdbuffer + buf_index + 2, 2);
180f1d2b4d3SLarry Finger 
181f1d2b4d3SLarry Finger 			for (idx = 0; idx < 2; idx++) {
182f1d2b4d3SLarry Finger 				rtl_write_byte(rtlpriv, box_extreg + idx,
183f1d2b4d3SLarry Finger 					       boxextcontent[idx]);
184f1d2b4d3SLarry Finger 			}
185f1d2b4d3SLarry Finger 
186f1d2b4d3SLarry Finger 			for (idx = 0; idx < 4; idx++) {
187f1d2b4d3SLarry Finger 				rtl_write_byte(rtlpriv, box_reg + idx,
188f1d2b4d3SLarry Finger 					       boxcontent[idx]);
189f1d2b4d3SLarry Finger 			}
190f1d2b4d3SLarry Finger 			break;
191f1d2b4d3SLarry Finger 		case 5:
192f1d2b4d3SLarry Finger 			boxcontent[0] |= (BIT(7));
193f1d2b4d3SLarry Finger 			memcpy((u8 *)(boxextcontent),
194f1d2b4d3SLarry Finger 			       cmdbuffer + buf_index, 2);
195f1d2b4d3SLarry Finger 			memcpy((u8 *)(boxcontent) + 1,
196f1d2b4d3SLarry Finger 			       cmdbuffer + buf_index + 2, 3);
197f1d2b4d3SLarry Finger 
198f1d2b4d3SLarry Finger 			for (idx = 0; idx < 2; idx++) {
199f1d2b4d3SLarry Finger 				rtl_write_byte(rtlpriv, box_extreg + idx,
200f1d2b4d3SLarry Finger 					       boxextcontent[idx]);
201f1d2b4d3SLarry Finger 			}
202f1d2b4d3SLarry Finger 
203f1d2b4d3SLarry Finger 			for (idx = 0; idx < 4; idx++) {
204f1d2b4d3SLarry Finger 				rtl_write_byte(rtlpriv, box_reg + idx,
205f1d2b4d3SLarry Finger 					       boxcontent[idx]);
206f1d2b4d3SLarry Finger 			}
207f1d2b4d3SLarry Finger 			break;
208f1d2b4d3SLarry Finger 		default:
209a67005bcSLarry Finger 			pr_err("switch case %#x not processed\n",
210a67005bcSLarry Finger 			       cmd_len);
211f1d2b4d3SLarry Finger 			break;
212f1d2b4d3SLarry Finger 		}
213f1d2b4d3SLarry Finger 
214f1d2b4d3SLarry Finger 		bwrite_sucess = true;
215f1d2b4d3SLarry Finger 
216f1d2b4d3SLarry Finger 		rtlhal->last_hmeboxnum = boxnum + 1;
217f1d2b4d3SLarry Finger 		if (rtlhal->last_hmeboxnum == 4)
218f1d2b4d3SLarry Finger 			rtlhal->last_hmeboxnum = 0;
219f1d2b4d3SLarry Finger 
220*8f11dad4SLarry Finger 		rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
221f1d2b4d3SLarry Finger 			"pHalData->last_hmeboxnum  = %d\n",
222f1d2b4d3SLarry Finger 			rtlhal->last_hmeboxnum);
223f1d2b4d3SLarry Finger 	}
224f1d2b4d3SLarry Finger 
225f1d2b4d3SLarry Finger 	spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
226f1d2b4d3SLarry Finger 	rtlhal->h2c_setinprogress = false;
227f1d2b4d3SLarry Finger 	spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
228f1d2b4d3SLarry Finger 
229*8f11dad4SLarry Finger 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
230f1d2b4d3SLarry Finger }
231f1d2b4d3SLarry Finger 
rtl8723e_fill_h2c_cmd(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * cmdbuffer)232f1d2b4d3SLarry Finger void rtl8723e_fill_h2c_cmd(struct ieee80211_hw *hw,
233f1d2b4d3SLarry Finger 			   u8 element_id, u32 cmd_len, u8 *cmdbuffer)
234f1d2b4d3SLarry Finger {
235f1d2b4d3SLarry Finger 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
236f1d2b4d3SLarry Finger 	u32 tmp_cmdbuf[2];
237f1d2b4d3SLarry Finger 
238f1d2b4d3SLarry Finger 	if (!rtlhal->fw_ready) {
239531940f9SLarry Finger 		WARN_ONCE(true,
240531940f9SLarry Finger 			  "rtl8723ae: error H2C cmd because of Fw download fail!!!\n");
241f1d2b4d3SLarry Finger 		return;
242f1d2b4d3SLarry Finger 	}
243f1d2b4d3SLarry Finger 	memset(tmp_cmdbuf, 0, 8);
244f1d2b4d3SLarry Finger 	memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
245f1d2b4d3SLarry Finger 	_rtl8723e_fill_h2c_command(hw, element_id, cmd_len,
246f1d2b4d3SLarry Finger 				   (u8 *)&tmp_cmdbuf);
247f1d2b4d3SLarry Finger }
248f1d2b4d3SLarry Finger 
rtl8723e_set_fw_pwrmode_cmd(struct ieee80211_hw * hw,u8 mode)249f1d2b4d3SLarry Finger void rtl8723e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
250f1d2b4d3SLarry Finger {
251f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = rtl_priv(hw);
252f1d2b4d3SLarry Finger 	u8 u1_h2c_set_pwrmode[3] = { 0 };
253f1d2b4d3SLarry Finger 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
254f1d2b4d3SLarry Finger 
255*8f11dad4SLarry Finger 	rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
256f1d2b4d3SLarry Finger 
257f1d2b4d3SLarry Finger 	SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
258f1d2b4d3SLarry Finger 	SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
259f1d2b4d3SLarry Finger 		(rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1);
260f1d2b4d3SLarry Finger 	SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
261f1d2b4d3SLarry Finger 					      ppsc->reg_max_lps_awakeintvl);
262f1d2b4d3SLarry Finger 
263f1d2b4d3SLarry Finger 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
264f1d2b4d3SLarry Finger 		      "rtl8723e_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
265f1d2b4d3SLarry Finger 		      u1_h2c_set_pwrmode, 3);
266f1d2b4d3SLarry Finger 	rtl8723e_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
267f1d2b4d3SLarry Finger }
268f1d2b4d3SLarry Finger 
269f1d2b4d3SLarry Finger #define BEACON_PG		0 /* ->1 */
270f1d2b4d3SLarry Finger #define PSPOLL_PG		2
271f1d2b4d3SLarry Finger #define NULL_PG			3
272f1d2b4d3SLarry Finger #define PROBERSP_PG		4 /* ->5 */
273f1d2b4d3SLarry Finger 
274f1d2b4d3SLarry Finger #define TOTAL_RESERVED_PKT_LEN	768
275f1d2b4d3SLarry Finger 
276f1d2b4d3SLarry Finger static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
277f1d2b4d3SLarry Finger 	/* page 0 beacon */
278f1d2b4d3SLarry Finger 	0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
279f1d2b4d3SLarry Finger 	0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
280f1d2b4d3SLarry Finger 	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
281f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282f1d2b4d3SLarry Finger 	0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
283f1d2b4d3SLarry Finger 	0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
284f1d2b4d3SLarry Finger 	0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
285f1d2b4d3SLarry Finger 	0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
286f1d2b4d3SLarry Finger 	0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
287f1d2b4d3SLarry Finger 	0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
288f1d2b4d3SLarry Finger 	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291f1d2b4d3SLarry Finger 	0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
292f1d2b4d3SLarry Finger 	0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294f1d2b4d3SLarry Finger 
295f1d2b4d3SLarry Finger 	/* page 1 beacon */
296f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308f1d2b4d3SLarry Finger 	0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
309f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310f1d2b4d3SLarry Finger 	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312f1d2b4d3SLarry Finger 
313f1d2b4d3SLarry Finger 	/* page 2  ps-poll */
314f1d2b4d3SLarry Finger 	0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
315f1d2b4d3SLarry Finger 	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
316f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326f1d2b4d3SLarry Finger 	0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
327f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
328f1d2b4d3SLarry Finger 	0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330f1d2b4d3SLarry Finger 
331f1d2b4d3SLarry Finger 	/* page 3  null */
332f1d2b4d3SLarry Finger 	0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
333f1d2b4d3SLarry Finger 	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
334f1d2b4d3SLarry Finger 	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
335f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344f1d2b4d3SLarry Finger 	0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
345f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
346f1d2b4d3SLarry Finger 	0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348f1d2b4d3SLarry Finger 
349f1d2b4d3SLarry Finger 	/* page 4  probe_resp */
350f1d2b4d3SLarry Finger 	0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
351f1d2b4d3SLarry Finger 	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
352f1d2b4d3SLarry Finger 	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
353f1d2b4d3SLarry Finger 	0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
354f1d2b4d3SLarry Finger 	0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
355f1d2b4d3SLarry Finger 	0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
356f1d2b4d3SLarry Finger 	0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
357f1d2b4d3SLarry Finger 	0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
358f1d2b4d3SLarry Finger 	0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
359f1d2b4d3SLarry Finger 	0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
360f1d2b4d3SLarry Finger 	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363f1d2b4d3SLarry Finger 	0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
364f1d2b4d3SLarry Finger 	0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366f1d2b4d3SLarry Finger 
367f1d2b4d3SLarry Finger 	/* page 5  probe_resp */
368f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384f1d2b4d3SLarry Finger };
385f1d2b4d3SLarry Finger 
rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw * hw,bool b_dl_finished)386f1d2b4d3SLarry Finger void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
387f1d2b4d3SLarry Finger {
388f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = rtl_priv(hw);
389f1d2b4d3SLarry Finger 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
390f1d2b4d3SLarry Finger 	struct sk_buff *skb = NULL;
391f1d2b4d3SLarry Finger 	u32 totalpacketlen;
392f1d2b4d3SLarry Finger 	bool rtstatus;
393f1d2b4d3SLarry Finger 	u8 u1rsvdpageloc[3] = { 0 };
394f1d2b4d3SLarry Finger 	bool b_dlok = false;
395f1d2b4d3SLarry Finger 	u8 *beacon;
396f1d2b4d3SLarry Finger 	u8 *p_pspoll;
397f1d2b4d3SLarry Finger 	u8 *nullfunc;
398f1d2b4d3SLarry Finger 	u8 *p_probersp;
399f1d2b4d3SLarry Finger 
400f1d2b4d3SLarry Finger 	/*---------------------------------------------------------
401f1d2b4d3SLarry Finger 	 *			(1) beacon
402f1d2b4d3SLarry Finger 	 *---------------------------------------------------------
403f1d2b4d3SLarry Finger 	 */
404f1d2b4d3SLarry Finger 	beacon = &reserved_page_packet[BEACON_PG * 128];
405f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
406f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
407f1d2b4d3SLarry Finger 
408f1d2b4d3SLarry Finger 	/*-------------------------------------------------------
409f1d2b4d3SLarry Finger 	 *			(2) ps-poll
410f1d2b4d3SLarry Finger 	 *--------------------------------------------------------
411f1d2b4d3SLarry Finger 	 */
412f1d2b4d3SLarry Finger 	p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
413f1d2b4d3SLarry Finger 	SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
414f1d2b4d3SLarry Finger 	SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
415f1d2b4d3SLarry Finger 	SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
416f1d2b4d3SLarry Finger 
417f1d2b4d3SLarry Finger 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
418f1d2b4d3SLarry Finger 
419f1d2b4d3SLarry Finger 	/*--------------------------------------------------------
420f1d2b4d3SLarry Finger 	 *			(3) null data
421f1d2b4d3SLarry Finger 	 *---------------------------------------------------------
422f1d2b4d3SLarry Finger 	 */
423f1d2b4d3SLarry Finger 	nullfunc = &reserved_page_packet[NULL_PG * 128];
424f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
425f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
426f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
427f1d2b4d3SLarry Finger 
428f1d2b4d3SLarry Finger 	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
429f1d2b4d3SLarry Finger 
430f1d2b4d3SLarry Finger 	/*---------------------------------------------------------
431f1d2b4d3SLarry Finger 	 *			(4) probe response
432f1d2b4d3SLarry Finger 	 *----------------------------------------------------------
433f1d2b4d3SLarry Finger 	 */
434f1d2b4d3SLarry Finger 	p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
435f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
436f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
437f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
438f1d2b4d3SLarry Finger 
439f1d2b4d3SLarry Finger 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
440f1d2b4d3SLarry Finger 
441f1d2b4d3SLarry Finger 	totalpacketlen = TOTAL_RESERVED_PKT_LEN;
442f1d2b4d3SLarry Finger 
443f1d2b4d3SLarry Finger 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
444f1d2b4d3SLarry Finger 		      "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
445f1d2b4d3SLarry Finger 		      &reserved_page_packet[0], totalpacketlen);
446f1d2b4d3SLarry Finger 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
447f1d2b4d3SLarry Finger 		      "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
448f1d2b4d3SLarry Finger 		      u1rsvdpageloc, 3);
449f1d2b4d3SLarry Finger 
450f1d2b4d3SLarry Finger 	skb = dev_alloc_skb(totalpacketlen);
45160209d48SPing-Ke Shih 	if (!skb)
45260209d48SPing-Ke Shih 		return;
453ad941e69Syuan linyu 	skb_put_data(skb, &reserved_page_packet, totalpacketlen);
454f1d2b4d3SLarry Finger 
455f1d2b4d3SLarry Finger 	rtstatus = rtl_cmd_send_packet(hw, skb);
456f1d2b4d3SLarry Finger 
457f1d2b4d3SLarry Finger 	if (rtstatus)
458f1d2b4d3SLarry Finger 		b_dlok = true;
459f1d2b4d3SLarry Finger 
460f1d2b4d3SLarry Finger 	if (b_dlok) {
461*8f11dad4SLarry Finger 		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
462f1d2b4d3SLarry Finger 			"Set RSVD page location to Fw.\n");
463f1d2b4d3SLarry Finger 		RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
464f1d2b4d3SLarry Finger 			      "H2C_RSVDPAGE:\n",
465f1d2b4d3SLarry Finger 			      u1rsvdpageloc, 3);
466f1d2b4d3SLarry Finger 		rtl8723e_fill_h2c_cmd(hw, H2C_RSVDPAGE,
467f1d2b4d3SLarry Finger 				      sizeof(u1rsvdpageloc), u1rsvdpageloc);
468f1d2b4d3SLarry Finger 	} else
469*8f11dad4SLarry Finger 		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
470f1d2b4d3SLarry Finger 			"Set RSVD page location to Fw FAIL!!!!!!.\n");
471f1d2b4d3SLarry Finger }
472f1d2b4d3SLarry Finger 
rtl8723e_set_fw_joinbss_report_cmd(struct ieee80211_hw * hw,u8 mstatus)473f1d2b4d3SLarry Finger void rtl8723e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
474f1d2b4d3SLarry Finger {
475f1d2b4d3SLarry Finger 	u8 u1_joinbssrpt_parm[1] = { 0 };
476f1d2b4d3SLarry Finger 
477f1d2b4d3SLarry Finger 	SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
478f1d2b4d3SLarry Finger 
479f1d2b4d3SLarry Finger 	rtl8723e_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
480f1d2b4d3SLarry Finger }
481f1d2b4d3SLarry Finger 
rtl8723e_set_p2p_ctw_period_cmd(struct ieee80211_hw * hw,u8 ctwindow)482f1d2b4d3SLarry Finger static void rtl8723e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
483f1d2b4d3SLarry Finger 					    u8 ctwindow)
484f1d2b4d3SLarry Finger {
485f1d2b4d3SLarry Finger 	u8 u1_ctwindow_period[1] = { ctwindow};
486f1d2b4d3SLarry Finger 
487f1d2b4d3SLarry Finger 	rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
488f1d2b4d3SLarry Finger 
489f1d2b4d3SLarry Finger }
490f1d2b4d3SLarry Finger 
rtl8723e_set_p2p_ps_offload_cmd(struct ieee80211_hw * hw,u8 p2p_ps_state)491f1d2b4d3SLarry Finger void rtl8723e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
492f1d2b4d3SLarry Finger {
493f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = rtl_priv(hw);
494f1d2b4d3SLarry Finger 	struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
495f1d2b4d3SLarry Finger 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
496f1d2b4d3SLarry Finger 	struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
497f1d2b4d3SLarry Finger 	struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
498f1d2b4d3SLarry Finger 	u8	i;
499f1d2b4d3SLarry Finger 	u16	ctwindow;
500f1d2b4d3SLarry Finger 	u32	start_time, tsf_low;
501f1d2b4d3SLarry Finger 
502f1d2b4d3SLarry Finger 	switch (p2p_ps_state) {
503f1d2b4d3SLarry Finger 	case P2P_PS_DISABLE:
504*8f11dad4SLarry Finger 		rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
505f1d2b4d3SLarry Finger 		memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
506f1d2b4d3SLarry Finger 		break;
507f1d2b4d3SLarry Finger 	case P2P_PS_ENABLE:
508*8f11dad4SLarry Finger 		rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
509f1d2b4d3SLarry Finger 		/* update CTWindow value. */
510f1d2b4d3SLarry Finger 		if (p2pinfo->ctwindow > 0) {
511f1d2b4d3SLarry Finger 			p2p_ps_offload->ctwindow_en = 1;
512f1d2b4d3SLarry Finger 			ctwindow = p2pinfo->ctwindow;
513f1d2b4d3SLarry Finger 			rtl8723e_set_p2p_ctw_period_cmd(hw, ctwindow);
514f1d2b4d3SLarry Finger 		}
515f1d2b4d3SLarry Finger 
516f1d2b4d3SLarry Finger 		/* hw only support 2 set of NoA */
517f1d2b4d3SLarry Finger 		for (i = 0 ; i < p2pinfo->noa_num ; i++) {
518f1d2b4d3SLarry Finger 			/* To control the register setting for which NOA*/
519f1d2b4d3SLarry Finger 			rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
520f1d2b4d3SLarry Finger 			if (i == 0)
521f1d2b4d3SLarry Finger 				p2p_ps_offload->noa0_en = 1;
522f1d2b4d3SLarry Finger 			else
523f1d2b4d3SLarry Finger 				p2p_ps_offload->noa1_en = 1;
524f1d2b4d3SLarry Finger 
525f1d2b4d3SLarry Finger 			/* config P2P NoA Descriptor Register */
526f1d2b4d3SLarry Finger 			rtl_write_dword(rtlpriv, 0x5E0,
527f1d2b4d3SLarry Finger 					p2pinfo->noa_duration[i]);
528f1d2b4d3SLarry Finger 			rtl_write_dword(rtlpriv, 0x5E4,
529f1d2b4d3SLarry Finger 					p2pinfo->noa_interval[i]);
530f1d2b4d3SLarry Finger 
531f1d2b4d3SLarry Finger 			/*Get Current TSF value */
532f1d2b4d3SLarry Finger 			tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
533f1d2b4d3SLarry Finger 
534f1d2b4d3SLarry Finger 			start_time = p2pinfo->noa_start_time[i];
535f1d2b4d3SLarry Finger 			if (p2pinfo->noa_count_type[i] != 1) {
536f1d2b4d3SLarry Finger 				while (start_time <=
537f1d2b4d3SLarry Finger 					(tsf_low+(50*1024))) {
538f1d2b4d3SLarry Finger 					start_time +=
539f1d2b4d3SLarry Finger 						p2pinfo->noa_interval[i];
540f1d2b4d3SLarry Finger 					if (p2pinfo->noa_count_type[i] != 255)
541f1d2b4d3SLarry Finger 						p2pinfo->noa_count_type[i]--;
542f1d2b4d3SLarry Finger 				}
543f1d2b4d3SLarry Finger 			}
544f1d2b4d3SLarry Finger 			rtl_write_dword(rtlpriv, 0x5E8, start_time);
545f1d2b4d3SLarry Finger 			rtl_write_dword(rtlpriv, 0x5EC,
546f1d2b4d3SLarry Finger 				p2pinfo->noa_count_type[i]);
547f1d2b4d3SLarry Finger 
548f1d2b4d3SLarry Finger 		}
549f1d2b4d3SLarry Finger 
550f1d2b4d3SLarry Finger 		if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
551f1d2b4d3SLarry Finger 			/* rst p2p circuit */
552f1d2b4d3SLarry Finger 			rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
553f1d2b4d3SLarry Finger 
554f1d2b4d3SLarry Finger 			p2p_ps_offload->offload_en = 1;
555f1d2b4d3SLarry Finger 
556f1d2b4d3SLarry Finger 			if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
557f1d2b4d3SLarry Finger 				p2p_ps_offload->role = 1;
558f1d2b4d3SLarry Finger 				p2p_ps_offload->allstasleep = 0;
559f1d2b4d3SLarry Finger 			} else {
560f1d2b4d3SLarry Finger 				p2p_ps_offload->role = 0;
561f1d2b4d3SLarry Finger 			}
562f1d2b4d3SLarry Finger 
563f1d2b4d3SLarry Finger 			p2p_ps_offload->discovery = 0;
564f1d2b4d3SLarry Finger 		}
565f1d2b4d3SLarry Finger 		break;
566f1d2b4d3SLarry Finger 	case P2P_PS_SCAN:
567*8f11dad4SLarry Finger 		rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
568f1d2b4d3SLarry Finger 		p2p_ps_offload->discovery = 1;
569f1d2b4d3SLarry Finger 		break;
570f1d2b4d3SLarry Finger 	case P2P_PS_SCAN_DONE:
571*8f11dad4SLarry Finger 		rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
572f1d2b4d3SLarry Finger 		p2p_ps_offload->discovery = 0;
573f1d2b4d3SLarry Finger 		p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
574f1d2b4d3SLarry Finger 		break;
575f1d2b4d3SLarry Finger 	default:
576f1d2b4d3SLarry Finger 		break;
577f1d2b4d3SLarry Finger 	}
578f1d2b4d3SLarry Finger 
579f1d2b4d3SLarry Finger 	rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
580f1d2b4d3SLarry Finger 
581f1d2b4d3SLarry Finger }
582