193121c03SLarry Finger // SPDX-License-Identifier: GPL-2.0
293121c03SLarry Finger /* Copyright(c) 2009-2014  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 
_rtl8723be_check_fw_read_last_h2c(struct ieee80211_hw * hw,u8 boxnum)13f1d2b4d3SLarry Finger static bool _rtl8723be_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;
18f1d2b4d3SLarry Finger 	bool result = false;
19f1d2b4d3SLarry Finger 
20f1d2b4d3SLarry Finger 	val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
21f1d2b4d3SLarry Finger 	if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
22f1d2b4d3SLarry Finger 		result = true;
23f1d2b4d3SLarry Finger 	return result;
24f1d2b4d3SLarry Finger }
25f1d2b4d3SLarry Finger 
_rtl8723be_fill_h2c_command(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * p_cmdbuffer)26f1d2b4d3SLarry Finger static void _rtl8723be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
27f1d2b4d3SLarry Finger 					u32 cmd_len, u8 *p_cmdbuffer)
28f1d2b4d3SLarry Finger {
29f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = rtl_priv(hw);
30f1d2b4d3SLarry Finger 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
31f1d2b4d3SLarry Finger 	u8 boxnum;
32f1d2b4d3SLarry Finger 	u16 box_reg = 0, box_extreg = 0;
33f1d2b4d3SLarry Finger 	u8 u1b_tmp;
34f1d2b4d3SLarry Finger 	bool isfw_read = false;
35f1d2b4d3SLarry Finger 	u8 buf_index = 0;
36f1d2b4d3SLarry Finger 	bool bwrite_sucess = false;
37f1d2b4d3SLarry Finger 	u8 wait_h2c_limmit = 100;
38f1d2b4d3SLarry Finger 	u8 wait_writeh2c_limmit = 100;
39f1d2b4d3SLarry Finger 	u8 boxcontent[4], boxextcontent[4];
40f1d2b4d3SLarry Finger 	u32 h2c_waitcounter = 0;
41f1d2b4d3SLarry Finger 	unsigned long flag;
42f1d2b4d3SLarry Finger 	u8 idx;
43f1d2b4d3SLarry Finger 
44*e6dd230aSLarry Finger 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
45f1d2b4d3SLarry Finger 
46f1d2b4d3SLarry Finger 	while (true) {
47f1d2b4d3SLarry Finger 		spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
48f1d2b4d3SLarry Finger 		if (rtlhal->h2c_setinprogress) {
49*e6dd230aSLarry Finger 			rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
50f1d2b4d3SLarry Finger 				"H2C set in progress! Wait to set..element_id(%d).\n",
51f1d2b4d3SLarry Finger 				element_id);
52f1d2b4d3SLarry Finger 
53f1d2b4d3SLarry Finger 			while (rtlhal->h2c_setinprogress) {
54f1d2b4d3SLarry Finger 				spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
55f1d2b4d3SLarry Finger 						       flag);
56f1d2b4d3SLarry Finger 				h2c_waitcounter++;
57*e6dd230aSLarry Finger 				rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
58f1d2b4d3SLarry Finger 					"Wait 100 us (%d times)...\n",
59f1d2b4d3SLarry Finger 					h2c_waitcounter);
60f1d2b4d3SLarry Finger 				udelay(100);
61f1d2b4d3SLarry Finger 
62f1d2b4d3SLarry Finger 				if (h2c_waitcounter > 1000)
63f1d2b4d3SLarry Finger 					return;
64f1d2b4d3SLarry Finger 				spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
65f1d2b4d3SLarry Finger 						  flag);
66f1d2b4d3SLarry Finger 			}
67f1d2b4d3SLarry Finger 			spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
68f1d2b4d3SLarry Finger 		} else {
69f1d2b4d3SLarry Finger 			rtlhal->h2c_setinprogress = true;
70f1d2b4d3SLarry Finger 			spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
71f1d2b4d3SLarry Finger 			break;
72f1d2b4d3SLarry Finger 		}
73f1d2b4d3SLarry Finger 	}
74f1d2b4d3SLarry Finger 
75f1d2b4d3SLarry Finger 	while (!bwrite_sucess) {
76f1d2b4d3SLarry Finger 		wait_writeh2c_limmit--;
77f1d2b4d3SLarry Finger 		if (wait_writeh2c_limmit == 0) {
784e2b4378SLarry Finger 			pr_err("Write H2C fail because no trigger for FW INT!\n");
79f1d2b4d3SLarry Finger 			break;
80f1d2b4d3SLarry Finger 		}
81f1d2b4d3SLarry Finger 
82f1d2b4d3SLarry Finger 		boxnum = rtlhal->last_hmeboxnum;
83f1d2b4d3SLarry Finger 		switch (boxnum) {
84f1d2b4d3SLarry Finger 		case 0:
85f1d2b4d3SLarry Finger 			box_reg = REG_HMEBOX_0;
86f1d2b4d3SLarry Finger 			box_extreg = REG_HMEBOX_EXT_0;
87f1d2b4d3SLarry Finger 			break;
88f1d2b4d3SLarry Finger 		case 1:
89f1d2b4d3SLarry Finger 			box_reg = REG_HMEBOX_1;
90f1d2b4d3SLarry Finger 			box_extreg = REG_HMEBOX_EXT_1;
91f1d2b4d3SLarry Finger 			break;
92f1d2b4d3SLarry Finger 		case 2:
93f1d2b4d3SLarry Finger 			box_reg = REG_HMEBOX_2;
94f1d2b4d3SLarry Finger 			box_extreg = REG_HMEBOX_EXT_2;
95f1d2b4d3SLarry Finger 			break;
96f1d2b4d3SLarry Finger 		case 3:
97f1d2b4d3SLarry Finger 			box_reg = REG_HMEBOX_3;
98f1d2b4d3SLarry Finger 			box_extreg = REG_HMEBOX_EXT_3;
99f1d2b4d3SLarry Finger 			break;
100f1d2b4d3SLarry Finger 		default:
1014e2b4378SLarry Finger 			pr_err("switch case %#x not processed\n",
1024e2b4378SLarry Finger 			       boxnum);
103f1d2b4d3SLarry Finger 			break;
104f1d2b4d3SLarry Finger 		}
105f1d2b4d3SLarry Finger 
106f1d2b4d3SLarry Finger 		isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, boxnum);
107f1d2b4d3SLarry Finger 		while (!isfw_read) {
108f1d2b4d3SLarry Finger 			wait_h2c_limmit--;
109f1d2b4d3SLarry Finger 			if (wait_h2c_limmit == 0) {
110*e6dd230aSLarry Finger 				rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
111f1d2b4d3SLarry Finger 					"Waiting too long for FW read clear HMEBox(%d)!\n",
112f1d2b4d3SLarry Finger 					boxnum);
113f1d2b4d3SLarry Finger 				break;
114f1d2b4d3SLarry Finger 			}
115f1d2b4d3SLarry Finger 
116f1d2b4d3SLarry Finger 			udelay(10);
117f1d2b4d3SLarry Finger 
118f1d2b4d3SLarry Finger 			isfw_read = _rtl8723be_check_fw_read_last_h2c(hw,
119f1d2b4d3SLarry Finger 								boxnum);
120f1d2b4d3SLarry Finger 			u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
121*e6dd230aSLarry Finger 			rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
122f1d2b4d3SLarry Finger 				"Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
123f1d2b4d3SLarry Finger 				boxnum, u1b_tmp);
124f1d2b4d3SLarry Finger 		}
125f1d2b4d3SLarry Finger 
126f1d2b4d3SLarry Finger 		if (!isfw_read) {
127*e6dd230aSLarry Finger 			rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
128f1d2b4d3SLarry Finger 				"Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
129f1d2b4d3SLarry Finger 				boxnum);
130f1d2b4d3SLarry Finger 			break;
131f1d2b4d3SLarry Finger 		}
132f1d2b4d3SLarry Finger 
133f1d2b4d3SLarry Finger 		memset(boxcontent, 0, sizeof(boxcontent));
134f1d2b4d3SLarry Finger 		memset(boxextcontent, 0, sizeof(boxextcontent));
135f1d2b4d3SLarry Finger 		boxcontent[0] = element_id;
136*e6dd230aSLarry Finger 		rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
137f1d2b4d3SLarry Finger 			"Write element_id box_reg(%4x) = %2x\n",
138f1d2b4d3SLarry Finger 			box_reg, element_id);
139f1d2b4d3SLarry Finger 
140f1d2b4d3SLarry Finger 		switch (cmd_len) {
141f1d2b4d3SLarry Finger 		case 1:
142f1d2b4d3SLarry Finger 		case 2:
143f1d2b4d3SLarry Finger 		case 3:
144f1d2b4d3SLarry Finger 			/*boxcontent[0] &= ~(BIT(7));*/
145f1d2b4d3SLarry Finger 			memcpy((u8 *)(boxcontent) + 1,
146f1d2b4d3SLarry Finger 			       p_cmdbuffer + buf_index, cmd_len);
147f1d2b4d3SLarry Finger 
148f1d2b4d3SLarry Finger 			for (idx = 0; idx < 4; idx++) {
149f1d2b4d3SLarry Finger 				rtl_write_byte(rtlpriv, box_reg + idx,
150f1d2b4d3SLarry Finger 					       boxcontent[idx]);
151f1d2b4d3SLarry Finger 			}
152f1d2b4d3SLarry Finger 			break;
153f1d2b4d3SLarry Finger 		case 4:
154f1d2b4d3SLarry Finger 		case 5:
155f1d2b4d3SLarry Finger 		case 6:
156f1d2b4d3SLarry Finger 		case 7:
157f1d2b4d3SLarry Finger 			/*boxcontent[0] |= (BIT(7));*/
158f1d2b4d3SLarry Finger 			memcpy((u8 *)(boxextcontent),
159f1d2b4d3SLarry Finger 			       p_cmdbuffer + buf_index+3, cmd_len-3);
160f1d2b4d3SLarry Finger 			memcpy((u8 *)(boxcontent) + 1,
161f1d2b4d3SLarry Finger 			       p_cmdbuffer + buf_index, 3);
162f1d2b4d3SLarry Finger 
163f1d2b4d3SLarry Finger 			for (idx = 0; idx < 4; idx++) {
164f1d2b4d3SLarry Finger 				rtl_write_byte(rtlpriv, box_extreg + idx,
165f1d2b4d3SLarry Finger 					       boxextcontent[idx]);
166f1d2b4d3SLarry Finger 			}
167f1d2b4d3SLarry Finger 
168f1d2b4d3SLarry Finger 			for (idx = 0; idx < 4; idx++) {
169f1d2b4d3SLarry Finger 				rtl_write_byte(rtlpriv, box_reg + idx,
170f1d2b4d3SLarry Finger 					       boxcontent[idx]);
171f1d2b4d3SLarry Finger 			}
172f1d2b4d3SLarry Finger 			break;
173f1d2b4d3SLarry Finger 		default:
1744e2b4378SLarry Finger 			pr_err("switch case %#x not processed\n",
1754e2b4378SLarry Finger 			       cmd_len);
176f1d2b4d3SLarry Finger 			break;
177f1d2b4d3SLarry Finger 		}
178f1d2b4d3SLarry Finger 
179f1d2b4d3SLarry Finger 		bwrite_sucess = true;
180f1d2b4d3SLarry Finger 
181f1d2b4d3SLarry Finger 		rtlhal->last_hmeboxnum = boxnum + 1;
182f1d2b4d3SLarry Finger 		if (rtlhal->last_hmeboxnum == 4)
183f1d2b4d3SLarry Finger 			rtlhal->last_hmeboxnum = 0;
184f1d2b4d3SLarry Finger 
185*e6dd230aSLarry Finger 		rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
186f1d2b4d3SLarry Finger 			"pHalData->last_hmeboxnum  = %d\n",
187f1d2b4d3SLarry Finger 			rtlhal->last_hmeboxnum);
188f1d2b4d3SLarry Finger 	}
189f1d2b4d3SLarry Finger 
190f1d2b4d3SLarry Finger 	spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
191f1d2b4d3SLarry Finger 	rtlhal->h2c_setinprogress = false;
192f1d2b4d3SLarry Finger 	spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
193f1d2b4d3SLarry Finger 
194*e6dd230aSLarry Finger 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
195f1d2b4d3SLarry Finger }
196f1d2b4d3SLarry Finger 
rtl8723be_fill_h2c_cmd(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * p_cmdbuffer)197f1d2b4d3SLarry Finger void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
198f1d2b4d3SLarry Finger 			    u32 cmd_len, u8 *p_cmdbuffer)
199f1d2b4d3SLarry Finger {
200f1d2b4d3SLarry Finger 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
201f1d2b4d3SLarry Finger 	u32 tmp_cmdbuf[2];
202f1d2b4d3SLarry Finger 
203f1d2b4d3SLarry Finger 	if (!rtlhal->fw_ready) {
204531940f9SLarry Finger 		WARN_ONCE(true,
205531940f9SLarry Finger 			  "rtl8723be: error H2C cmd because of Fw download fail!!!\n");
206f1d2b4d3SLarry Finger 		return;
207f1d2b4d3SLarry Finger 	}
208f1d2b4d3SLarry Finger 
209f1d2b4d3SLarry Finger 	memset(tmp_cmdbuf, 0, 8);
210f1d2b4d3SLarry Finger 	memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
211f1d2b4d3SLarry Finger 	_rtl8723be_fill_h2c_command(hw, element_id, cmd_len,
212f1d2b4d3SLarry Finger 				    (u8 *)&tmp_cmdbuf);
213f1d2b4d3SLarry Finger 	return;
214f1d2b4d3SLarry Finger }
215f1d2b4d3SLarry Finger 
rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw * hw,u8 mode)216f1d2b4d3SLarry Finger void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
217f1d2b4d3SLarry Finger {
218f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = rtl_priv(hw);
219f1d2b4d3SLarry Finger 	u8 u1_h2c_set_pwrmode[H2C_PWEMODE_LENGTH] = { 0 };
220f1d2b4d3SLarry Finger 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
22142213f2fSPing-Ke Shih 	u8 rlbm, power_state = 0, byte5 = 0;
22242213f2fSPing-Ke Shih 	u8 awake_intvl;	/* DTIM = (awake_intvl - 1) */
22354685f9cSPing-Ke Shih 	struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
22442213f2fSPing-Ke Shih 	bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
22542213f2fSPing-Ke Shih 			    btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
226135f4fbdSPing-Ke Shih 	bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
227135f4fbdSPing-Ke Shih 			  btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
228135f4fbdSPing-Ke Shih 
229135f4fbdSPing-Ke Shih 	if (bt_ctrl_lps)
230135f4fbdSPing-Ke Shih 		mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
23154685f9cSPing-Ke Shih 
232*e6dd230aSLarry Finger 	rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
23342213f2fSPing-Ke Shih 		mode, bt_ctrl_lps);
23442213f2fSPing-Ke Shih 
23542213f2fSPing-Ke Shih 	switch (mode) {
23642213f2fSPing-Ke Shih 	case FW_PS_MIN_MODE:
23742213f2fSPing-Ke Shih 		rlbm = 0;
23842213f2fSPing-Ke Shih 		awake_intvl = 2;
23942213f2fSPing-Ke Shih 		break;
24042213f2fSPing-Ke Shih 	case FW_PS_MAX_MODE:
24142213f2fSPing-Ke Shih 		rlbm = 1;
24242213f2fSPing-Ke Shih 		awake_intvl = 2;
24342213f2fSPing-Ke Shih 		break;
24442213f2fSPing-Ke Shih 	case FW_PS_DTIM_MODE:
24542213f2fSPing-Ke Shih 		rlbm = 2;
24642213f2fSPing-Ke Shih 		awake_intvl = ppsc->reg_max_lps_awakeintvl;
24742213f2fSPing-Ke Shih 		/* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
24842213f2fSPing-Ke Shih 		 * is only used in swlps.
24942213f2fSPing-Ke Shih 		 */
25042213f2fSPing-Ke Shih 		break;
25142213f2fSPing-Ke Shih 	default:
25242213f2fSPing-Ke Shih 		rlbm = 2;
25342213f2fSPing-Ke Shih 		awake_intvl = 4;
25442213f2fSPing-Ke Shih 		break;
25542213f2fSPing-Ke Shih 	}
25642213f2fSPing-Ke Shih 
25742213f2fSPing-Ke Shih 	if (rtlpriv->mac80211.p2p) {
25842213f2fSPing-Ke Shih 		awake_intvl = 2;
25942213f2fSPing-Ke Shih 		rlbm = 1;
26042213f2fSPing-Ke Shih 	}
26142213f2fSPing-Ke Shih 
26242213f2fSPing-Ke Shih 	if (mode == FW_PS_ACTIVE_MODE) {
26342213f2fSPing-Ke Shih 		byte5 = 0x40;
26442213f2fSPing-Ke Shih 		power_state = FW_PWR_STATE_ACTIVE;
26542213f2fSPing-Ke Shih 	} else {
26642213f2fSPing-Ke Shih 		if (bt_ctrl_lps) {
26742213f2fSPing-Ke Shih 			byte5 = btc_ops->btc_get_lps_val(rtlpriv);
26842213f2fSPing-Ke Shih 			power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
26942213f2fSPing-Ke Shih 
27042213f2fSPing-Ke Shih 			if ((rlbm == 2) && (byte5 & BIT(4))) {
27142213f2fSPing-Ke Shih 				/* Keep awake interval to 1 to prevent from
27242213f2fSPing-Ke Shih 				 * decreasing coex performance
27342213f2fSPing-Ke Shih 				 */
27442213f2fSPing-Ke Shih 				awake_intvl = 2;
27542213f2fSPing-Ke Shih 				rlbm = 2;
27642213f2fSPing-Ke Shih 			}
27742213f2fSPing-Ke Shih 		} else {
27842213f2fSPing-Ke Shih 			byte5 = 0x40;
27942213f2fSPing-Ke Shih 			power_state = FW_PWR_STATE_RF_OFF;
28042213f2fSPing-Ke Shih 		}
28142213f2fSPing-Ke Shih 	}
282f1d2b4d3SLarry Finger 
283f1d2b4d3SLarry Finger 	SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
284f1d2b4d3SLarry Finger 	SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
285f1d2b4d3SLarry Finger 	SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
286135f4fbdSPing-Ke Shih 					 bt_ctrl_lps ? 0 : ppsc->smart_ps);
287f1d2b4d3SLarry Finger 	SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
28842213f2fSPing-Ke Shih 					       awake_intvl);
289f1d2b4d3SLarry Finger 	SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
290f1d2b4d3SLarry Finger 	SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
29154685f9cSPing-Ke Shih 	SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
292f1d2b4d3SLarry Finger 
293f1d2b4d3SLarry Finger 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
294f1d2b4d3SLarry Finger 		      "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
295f1d2b4d3SLarry Finger 		      u1_h2c_set_pwrmode, H2C_PWEMODE_LENGTH);
29654685f9cSPing-Ke Shih 	if (rtlpriv->cfg->ops->get_btc_status())
29754685f9cSPing-Ke Shih 		btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
29854685f9cSPing-Ke Shih 					     H2C_PWEMODE_LENGTH);
299f1d2b4d3SLarry Finger 	rtl8723be_fill_h2c_cmd(hw, H2C_8723B_SETPWRMODE, H2C_PWEMODE_LENGTH,
300f1d2b4d3SLarry Finger 			       u1_h2c_set_pwrmode);
301f1d2b4d3SLarry Finger }
302f1d2b4d3SLarry Finger 
rtl8723be_set_fw_media_status_rpt_cmd(struct ieee80211_hw * hw,u8 mstatus)303f1d2b4d3SLarry Finger void rtl8723be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
304f1d2b4d3SLarry Finger {
305f1d2b4d3SLarry Finger 	u8 parm[3] = { 0, 0, 0 };
306f1d2b4d3SLarry Finger 	/* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
307f1d2b4d3SLarry Finger 	 *          bit1=0-->update Media Status to MACID
308f1d2b4d3SLarry Finger 	 *          bit1=1-->update Media Status from MACID to MACID_End
309f1d2b4d3SLarry Finger 	 * parm[1]: MACID, if this is INFRA_STA, MacID = 0
310f1d2b4d3SLarry Finger 	 * parm[2]: MACID_End
311f1d2b4d3SLarry Finger 	*/
312f1d2b4d3SLarry Finger 	SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
313f1d2b4d3SLarry Finger 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
314f1d2b4d3SLarry Finger 
315f1d2b4d3SLarry Finger 	rtl8723be_fill_h2c_cmd(hw, H2C_8723B_MSRRPT, 3, parm);
316f1d2b4d3SLarry Finger }
317f1d2b4d3SLarry Finger 
318f1d2b4d3SLarry Finger #define BEACON_PG		0 /* ->1 */
319f1d2b4d3SLarry Finger #define PSPOLL_PG		2
320f1d2b4d3SLarry Finger #define NULL_PG			3
321f1d2b4d3SLarry Finger #define PROBERSP_PG		4 /* ->5 */
32274a7dfbcSPing-Ke Shih #define QOS_NULL_PG		6
32374a7dfbcSPing-Ke Shih #define BT_QOS_NULL_PG	7
324f1d2b4d3SLarry Finger 
32574a7dfbcSPing-Ke Shih #define TOTAL_RESERVED_PKT_LEN	1024	/* can be up to 1280 (tx_bndy=245) */
326f1d2b4d3SLarry Finger 
327f1d2b4d3SLarry Finger static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
328f1d2b4d3SLarry Finger 	/* page 0 beacon */
329f1d2b4d3SLarry Finger 	0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
330f1d2b4d3SLarry Finger 	0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
331f1d2b4d3SLarry Finger 	0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
332f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333f1d2b4d3SLarry Finger 	0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
334f1d2b4d3SLarry Finger 	0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
335f1d2b4d3SLarry Finger 	0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
336f1d2b4d3SLarry Finger 	0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
337f1d2b4d3SLarry Finger 	0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
338f1d2b4d3SLarry Finger 	0x09, 0x03, 0xFF, 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, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
342f1d2b4d3SLarry Finger 	0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
343f1d2b4d3SLarry Finger 	0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
344f1d2b4d3SLarry Finger 	0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
345f1d2b4d3SLarry Finger 
346f1d2b4d3SLarry Finger 	/* page 1 beacon */
347f1d2b4d3SLarry Finger 	0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
348f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358f1d2b4d3SLarry Finger 	0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
359f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
360f1d2b4d3SLarry Finger 	0x00, 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 
364f1d2b4d3SLarry Finger 	/* page 2  ps-poll */
365f1d2b4d3SLarry Finger 	0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
366f1d2b4d3SLarry Finger 	0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
367f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 	0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
377f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 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, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381f1d2b4d3SLarry Finger 
382f1d2b4d3SLarry Finger 	/* page 3  null */
383f1d2b4d3SLarry Finger 	0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
384f1d2b4d3SLarry Finger 	0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
385f1d2b4d3SLarry Finger 	0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
386f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394f1d2b4d3SLarry Finger 	0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
395f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
396f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398f1d2b4d3SLarry Finger 	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399f1d2b4d3SLarry Finger 
400f1d2b4d3SLarry Finger 	/* page 4  probe_resp */
401f1d2b4d3SLarry Finger 	0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
402f1d2b4d3SLarry Finger 	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
403f1d2b4d3SLarry Finger 	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
404f1d2b4d3SLarry Finger 	0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
405f1d2b4d3SLarry Finger 	0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
406f1d2b4d3SLarry Finger 	0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
407f1d2b4d3SLarry Finger 	0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
408f1d2b4d3SLarry Finger 	0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
409f1d2b4d3SLarry Finger 	0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
410f1d2b4d3SLarry Finger 	0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
411f1d2b4d3SLarry Finger 	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414f1d2b4d3SLarry Finger 	0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
415f1d2b4d3SLarry Finger 	0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417f1d2b4d3SLarry Finger 
418f1d2b4d3SLarry Finger 	/* page 5  probe_resp */
419f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43074a7dfbcSPing-Ke Shih 	0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
43174a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
43274a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43374a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43474a7dfbcSPing-Ke Shih 	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43574a7dfbcSPing-Ke Shih 
43674a7dfbcSPing-Ke Shih 	/* page 6 qos null data */
43774a7dfbcSPing-Ke Shih 	0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
43874a7dfbcSPing-Ke Shih 	0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
43974a7dfbcSPing-Ke Shih 	0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
440f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444f1d2b4d3SLarry Finger 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44574a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44674a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44774a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44874a7dfbcSPing-Ke Shih 	0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
44974a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
45074a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45174a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45274a7dfbcSPing-Ke Shih 	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45374a7dfbcSPing-Ke Shih 
45474a7dfbcSPing-Ke Shih 	/* page 7 BT-qos null data */
45574a7dfbcSPing-Ke Shih 	0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
45674a7dfbcSPing-Ke Shih 	0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
45774a7dfbcSPing-Ke Shih 	0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
45874a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45974a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46074a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46174a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46274a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46374a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46474a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46574a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46674a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46774a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46874a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46974a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47074a7dfbcSPing-Ke Shih 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47174a7dfbcSPing-Ke Shih 
472f1d2b4d3SLarry Finger };
473f1d2b4d3SLarry Finger 
rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw * hw,bool b_dl_finished)474f1d2b4d3SLarry Finger void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
475f1d2b4d3SLarry Finger 				  bool b_dl_finished)
476f1d2b4d3SLarry Finger {
477f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = rtl_priv(hw);
478f1d2b4d3SLarry Finger 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
479f1d2b4d3SLarry Finger 	struct sk_buff *skb = NULL;
480f1d2b4d3SLarry Finger 
481f1d2b4d3SLarry Finger 	u32 totalpacketlen;
482f1d2b4d3SLarry Finger 	bool rtstatus;
483f1d2b4d3SLarry Finger 	u8 u1rsvdpageloc[5] = { 0 };
484f1d2b4d3SLarry Finger 	bool b_dlok = false;
485f1d2b4d3SLarry Finger 
486f1d2b4d3SLarry Finger 	u8 *beacon;
487f1d2b4d3SLarry Finger 	u8 *p_pspoll;
488f1d2b4d3SLarry Finger 	u8 *nullfunc;
489f1d2b4d3SLarry Finger 	u8 *p_probersp;
49074a7dfbcSPing-Ke Shih 	u8 *qosnull;
49174a7dfbcSPing-Ke Shih 	u8 *btqosnull;
492f1d2b4d3SLarry Finger 	/*---------------------------------------------------------
493f1d2b4d3SLarry Finger 	 *			(1) beacon
494f1d2b4d3SLarry Finger 	 *---------------------------------------------------------
495f1d2b4d3SLarry Finger 	 */
496f1d2b4d3SLarry Finger 	beacon = &reserved_page_packet[BEACON_PG * 128];
497f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
498f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
499f1d2b4d3SLarry Finger 
500f1d2b4d3SLarry Finger 	/*-------------------------------------------------------
501f1d2b4d3SLarry Finger 	 *			(2) ps-poll
502f1d2b4d3SLarry Finger 	 *-------------------------------------------------------
503f1d2b4d3SLarry Finger 	 */
504f1d2b4d3SLarry Finger 	p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
505f1d2b4d3SLarry Finger 	SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
506f1d2b4d3SLarry Finger 	SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
507f1d2b4d3SLarry Finger 	SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
508f1d2b4d3SLarry Finger 
509f1d2b4d3SLarry Finger 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
510f1d2b4d3SLarry Finger 
511f1d2b4d3SLarry Finger 	/*--------------------------------------------------------
512f1d2b4d3SLarry Finger 	 *			(3) null data
513f1d2b4d3SLarry Finger 	 *--------------------------------------------------------
514f1d2b4d3SLarry Finger 	 */
515f1d2b4d3SLarry Finger 	nullfunc = &reserved_page_packet[NULL_PG * 128];
516f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
517f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
518f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
519f1d2b4d3SLarry Finger 
520f1d2b4d3SLarry Finger 	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
521f1d2b4d3SLarry Finger 
522f1d2b4d3SLarry Finger 	/*---------------------------------------------------------
523f1d2b4d3SLarry Finger 	 *			(4) probe response
524f1d2b4d3SLarry Finger 	 *---------------------------------------------------------
525f1d2b4d3SLarry Finger 	 */
526f1d2b4d3SLarry Finger 	p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
527f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
528f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
529f1d2b4d3SLarry Finger 	SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
530f1d2b4d3SLarry Finger 
531f1d2b4d3SLarry Finger 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
532f1d2b4d3SLarry Finger 
53374a7dfbcSPing-Ke Shih 	/*---------------------------------------------------------
53474a7dfbcSPing-Ke Shih 	 *			(5) QoS Null
53574a7dfbcSPing-Ke Shih 	 *---------------------------------------------------------
53674a7dfbcSPing-Ke Shih 	 */
53774a7dfbcSPing-Ke Shih 	qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
53874a7dfbcSPing-Ke Shih 	SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
53974a7dfbcSPing-Ke Shih 	SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
54074a7dfbcSPing-Ke Shih 	SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
54174a7dfbcSPing-Ke Shih 
54274a7dfbcSPing-Ke Shih 	SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
54374a7dfbcSPing-Ke Shih 
54474a7dfbcSPing-Ke Shih 	/*---------------------------------------------------------
54574a7dfbcSPing-Ke Shih 	 *			(5) QoS Null
54674a7dfbcSPing-Ke Shih 	 *---------------------------------------------------------
54774a7dfbcSPing-Ke Shih 	 */
54874a7dfbcSPing-Ke Shih 	btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
54974a7dfbcSPing-Ke Shih 	SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
55074a7dfbcSPing-Ke Shih 	SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
55174a7dfbcSPing-Ke Shih 	SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
55274a7dfbcSPing-Ke Shih 
55374a7dfbcSPing-Ke Shih 	SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
55474a7dfbcSPing-Ke Shih 
555f1d2b4d3SLarry Finger 	totalpacketlen = TOTAL_RESERVED_PKT_LEN;
556f1d2b4d3SLarry Finger 
557f1d2b4d3SLarry Finger 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
558f1d2b4d3SLarry Finger 		      "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
559f1d2b4d3SLarry Finger 		      &reserved_page_packet[0], totalpacketlen);
560f1d2b4d3SLarry Finger 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
561f1d2b4d3SLarry Finger 		      "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
56274a7dfbcSPing-Ke Shih 		      u1rsvdpageloc, sizeof(u1rsvdpageloc));
563f1d2b4d3SLarry Finger 
564f1d2b4d3SLarry Finger 	skb = dev_alloc_skb(totalpacketlen);
56560209d48SPing-Ke Shih 	if (!skb)
56660209d48SPing-Ke Shih 		return;
567ad941e69Syuan linyu 	skb_put_data(skb, &reserved_page_packet, totalpacketlen);
568f1d2b4d3SLarry Finger 
569f1d2b4d3SLarry Finger 	rtstatus = rtl_cmd_send_packet(hw, skb);
570f1d2b4d3SLarry Finger 
571f1d2b4d3SLarry Finger 	if (rtstatus)
572f1d2b4d3SLarry Finger 		b_dlok = true;
573f1d2b4d3SLarry Finger 
574f1d2b4d3SLarry Finger 	if (b_dlok) {
575*e6dd230aSLarry Finger 		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
576f1d2b4d3SLarry Finger 			"Set RSVD page location to Fw.\n");
577f1d2b4d3SLarry Finger 		RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n",
57874a7dfbcSPing-Ke Shih 			      u1rsvdpageloc, sizeof(u1rsvdpageloc));
579f1d2b4d3SLarry Finger 		rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RSVDPAGE,
580f1d2b4d3SLarry Finger 				       sizeof(u1rsvdpageloc), u1rsvdpageloc);
581f1d2b4d3SLarry Finger 	} else
582*e6dd230aSLarry Finger 		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
583f1d2b4d3SLarry Finger 			"Set RSVD page location to Fw FAIL!!!!!!.\n");
584f1d2b4d3SLarry Finger }
585f1d2b4d3SLarry Finger 
586f1d2b4d3SLarry Finger /*Should check FW support p2p or not.*/
rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw * hw,u8 ctwindow)587f1d2b4d3SLarry Finger static void rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
588f1d2b4d3SLarry Finger 					     u8 ctwindow)
589f1d2b4d3SLarry Finger {
590f1d2b4d3SLarry Finger 	u8 u1_ctwindow_period[1] = { ctwindow};
591f1d2b4d3SLarry Finger 
592f1d2b4d3SLarry Finger 	rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_CTW_CMD, 1,
593f1d2b4d3SLarry Finger 			       u1_ctwindow_period);
594f1d2b4d3SLarry Finger }
595f1d2b4d3SLarry Finger 
rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw * hw,u8 p2p_ps_state)596f1d2b4d3SLarry Finger void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw,
597f1d2b4d3SLarry Finger 				      u8 p2p_ps_state)
598f1d2b4d3SLarry Finger {
599f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = rtl_priv(hw);
600f1d2b4d3SLarry Finger 	struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
601f1d2b4d3SLarry Finger 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
602f1d2b4d3SLarry Finger 	struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
603f1d2b4d3SLarry Finger 	struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
604f1d2b4d3SLarry Finger 	u8 i;
605f1d2b4d3SLarry Finger 	u16 ctwindow;
606f1d2b4d3SLarry Finger 	u32 start_time, tsf_low;
607f1d2b4d3SLarry Finger 
608f1d2b4d3SLarry Finger 	switch (p2p_ps_state) {
609f1d2b4d3SLarry Finger 	case P2P_PS_DISABLE:
610*e6dd230aSLarry Finger 		rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
611f1d2b4d3SLarry Finger 		memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
612f1d2b4d3SLarry Finger 		break;
613f1d2b4d3SLarry Finger 	case P2P_PS_ENABLE:
614*e6dd230aSLarry Finger 		rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
615f1d2b4d3SLarry Finger 		/* update CTWindow value. */
616f1d2b4d3SLarry Finger 		if (p2pinfo->ctwindow > 0) {
617f1d2b4d3SLarry Finger 			p2p_ps_offload->ctwindow_en = 1;
618f1d2b4d3SLarry Finger 			ctwindow = p2pinfo->ctwindow;
619f1d2b4d3SLarry Finger 			rtl8723be_set_p2p_ctw_period_cmd(hw, ctwindow);
620f1d2b4d3SLarry Finger 		}
621f1d2b4d3SLarry Finger 		/* hw only support 2 set of NoA */
622f1d2b4d3SLarry Finger 		for (i = 0 ; i < p2pinfo->noa_num ; i++) {
623f1d2b4d3SLarry Finger 			/* To control the register setting
624f1d2b4d3SLarry Finger 			 * for which NOA
625f1d2b4d3SLarry Finger 			 */
626f1d2b4d3SLarry Finger 			rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
627f1d2b4d3SLarry Finger 			if (i == 0)
628f1d2b4d3SLarry Finger 				p2p_ps_offload->noa0_en = 1;
629f1d2b4d3SLarry Finger 			else
630f1d2b4d3SLarry Finger 				p2p_ps_offload->noa1_en = 1;
631f1d2b4d3SLarry Finger 
632f1d2b4d3SLarry Finger 			/* config P2P NoA Descriptor Register */
633f1d2b4d3SLarry Finger 			rtl_write_dword(rtlpriv, 0x5E0,
634f1d2b4d3SLarry Finger 					p2pinfo->noa_duration[i]);
635f1d2b4d3SLarry Finger 			rtl_write_dword(rtlpriv, 0x5E4,
636f1d2b4d3SLarry Finger 					p2pinfo->noa_interval[i]);
637f1d2b4d3SLarry Finger 
638f1d2b4d3SLarry Finger 			/*Get Current TSF value */
639f1d2b4d3SLarry Finger 			tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
640f1d2b4d3SLarry Finger 
641f1d2b4d3SLarry Finger 			start_time = p2pinfo->noa_start_time[i];
642f1d2b4d3SLarry Finger 			if (p2pinfo->noa_count_type[i] != 1) {
643f1d2b4d3SLarry Finger 				while (start_time <= (tsf_low + (50 * 1024))) {
644f1d2b4d3SLarry Finger 					start_time += p2pinfo->noa_interval[i];
645f1d2b4d3SLarry Finger 					if (p2pinfo->noa_count_type[i] != 255)
646f1d2b4d3SLarry Finger 						p2pinfo->noa_count_type[i]--;
647f1d2b4d3SLarry Finger 				}
648f1d2b4d3SLarry Finger 			}
649f1d2b4d3SLarry Finger 			rtl_write_dword(rtlpriv, 0x5E8, start_time);
650f1d2b4d3SLarry Finger 			rtl_write_dword(rtlpriv, 0x5EC,
651f1d2b4d3SLarry Finger 					p2pinfo->noa_count_type[i]);
652f1d2b4d3SLarry Finger 		}
653f1d2b4d3SLarry Finger 
654f1d2b4d3SLarry Finger 		if ((p2pinfo->opp_ps == 1) ||
655f1d2b4d3SLarry Finger 		    (p2pinfo->noa_num > 0)) {
656f1d2b4d3SLarry Finger 			/* rst p2p circuit */
657f1d2b4d3SLarry Finger 			rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
658f1d2b4d3SLarry Finger 
659f1d2b4d3SLarry Finger 			p2p_ps_offload->offload_en = 1;
660f1d2b4d3SLarry Finger 
661f1d2b4d3SLarry Finger 			if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
662f1d2b4d3SLarry Finger 				p2p_ps_offload->role = 1;
663f1d2b4d3SLarry Finger 				p2p_ps_offload->allstasleep = 0;
664f1d2b4d3SLarry Finger 			} else {
665f1d2b4d3SLarry Finger 				p2p_ps_offload->role = 0;
666f1d2b4d3SLarry Finger 			}
667f1d2b4d3SLarry Finger 			p2p_ps_offload->discovery = 0;
668f1d2b4d3SLarry Finger 		}
669f1d2b4d3SLarry Finger 		break;
670f1d2b4d3SLarry Finger 	case P2P_PS_SCAN:
671*e6dd230aSLarry Finger 		rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
672f1d2b4d3SLarry Finger 		p2p_ps_offload->discovery = 1;
673f1d2b4d3SLarry Finger 		break;
674f1d2b4d3SLarry Finger 	case P2P_PS_SCAN_DONE:
675*e6dd230aSLarry Finger 		rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
676f1d2b4d3SLarry Finger 		p2p_ps_offload->discovery = 0;
677f1d2b4d3SLarry Finger 		p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
678f1d2b4d3SLarry Finger 		break;
679f1d2b4d3SLarry Finger 	default:
680f1d2b4d3SLarry Finger 		break;
681f1d2b4d3SLarry Finger 	}
682f1d2b4d3SLarry Finger 
683f1d2b4d3SLarry Finger 	rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_OFFLOAD, 1,
684f1d2b4d3SLarry Finger 			       (u8 *)p2p_ps_offload);
685f1d2b4d3SLarry Finger }
686