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