1
2
3
4#include "../wifi.h"
5#include "../pci.h"
6#include "../base.h"
7#include "../core.h"
8#include "reg.h"
9#include "def.h"
10#include "fw.h"
11#include "../rtl8723com/fw_common.h"
12
13static bool _rtl8723be_check_fw_read_last_h2c(struct ieee80211_hw *hw,
14 u8 boxnum)
15{
16 struct rtl_priv *rtlpriv = rtl_priv(hw);
17 u8 val_hmetfr;
18 bool result = false;
19
20 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
21 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
22 result = true;
23 return result;
24}
25
26static void _rtl8723be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
27 u32 cmd_len, u8 *p_cmdbuffer)
28{
29 struct rtl_priv *rtlpriv = rtl_priv(hw);
30 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
31 u8 boxnum;
32 u16 box_reg = 0, box_extreg = 0;
33 u8 u1b_tmp;
34 bool isfw_read = false;
35 u8 buf_index = 0;
36 bool bwrite_sucess = false;
37 u8 wait_h2c_limmit = 100;
38 u8 wait_writeh2c_limmit = 100;
39 u8 boxcontent[4], boxextcontent[4];
40 u32 h2c_waitcounter = 0;
41 unsigned long flag;
42 u8 idx;
43
44 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
45
46 while (true) {
47 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
48 if (rtlhal->h2c_setinprogress) {
49 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
50 "H2C set in progress! Wait to set..element_id(%d).\n",
51 element_id);
52
53 while (rtlhal->h2c_setinprogress) {
54 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
55 flag);
56 h2c_waitcounter++;
57 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
58 "Wait 100 us (%d times)...\n",
59 h2c_waitcounter);
60 udelay(100);
61
62 if (h2c_waitcounter > 1000)
63 return;
64 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
65 flag);
66 }
67 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
68 } else {
69 rtlhal->h2c_setinprogress = true;
70 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
71 break;
72 }
73 }
74
75 while (!bwrite_sucess) {
76 wait_writeh2c_limmit--;
77 if (wait_writeh2c_limmit == 0) {
78 pr_err("Write H2C fail because no trigger for FW INT!\n");
79 break;
80 }
81
82 boxnum = rtlhal->last_hmeboxnum;
83 switch (boxnum) {
84 case 0:
85 box_reg = REG_HMEBOX_0;
86 box_extreg = REG_HMEBOX_EXT_0;
87 break;
88 case 1:
89 box_reg = REG_HMEBOX_1;
90 box_extreg = REG_HMEBOX_EXT_1;
91 break;
92 case 2:
93 box_reg = REG_HMEBOX_2;
94 box_extreg = REG_HMEBOX_EXT_2;
95 break;
96 case 3:
97 box_reg = REG_HMEBOX_3;
98 box_extreg = REG_HMEBOX_EXT_3;
99 break;
100 default:
101 pr_err("switch case %#x not processed\n",
102 boxnum);
103 break;
104 }
105
106 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, boxnum);
107 while (!isfw_read) {
108 wait_h2c_limmit--;
109 if (wait_h2c_limmit == 0) {
110 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
111 "Waiting too long for FW read clear HMEBox(%d)!\n",
112 boxnum);
113 break;
114 }
115
116 udelay(10);
117
118 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw,
119 boxnum);
120 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
121 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
122 "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
123 boxnum, u1b_tmp);
124 }
125
126 if (!isfw_read) {
127 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
128 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
129 boxnum);
130 break;
131 }
132
133 memset(boxcontent, 0, sizeof(boxcontent));
134 memset(boxextcontent, 0, sizeof(boxextcontent));
135 boxcontent[0] = element_id;
136 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
137 "Write element_id box_reg(%4x) = %2x\n",
138 box_reg, element_id);
139
140 switch (cmd_len) {
141 case 1:
142 case 2:
143 case 3:
144
145 memcpy((u8 *)(boxcontent) + 1,
146 p_cmdbuffer + buf_index, cmd_len);
147
148 for (idx = 0; idx < 4; idx++) {
149 rtl_write_byte(rtlpriv, box_reg + idx,
150 boxcontent[idx]);
151 }
152 break;
153 case 4:
154 case 5:
155 case 6:
156 case 7:
157
158 memcpy((u8 *)(boxextcontent),
159 p_cmdbuffer + buf_index+3, cmd_len-3);
160 memcpy((u8 *)(boxcontent) + 1,
161 p_cmdbuffer + buf_index, 3);
162
163 for (idx = 0; idx < 4; idx++) {
164 rtl_write_byte(rtlpriv, box_extreg + idx,
165 boxextcontent[idx]);
166 }
167
168 for (idx = 0; idx < 4; idx++) {
169 rtl_write_byte(rtlpriv, box_reg + idx,
170 boxcontent[idx]);
171 }
172 break;
173 default:
174 pr_err("switch case %#x not processed\n",
175 cmd_len);
176 break;
177 }
178
179 bwrite_sucess = true;
180
181 rtlhal->last_hmeboxnum = boxnum + 1;
182 if (rtlhal->last_hmeboxnum == 4)
183 rtlhal->last_hmeboxnum = 0;
184
185 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
186 "pHalData->last_hmeboxnum = %d\n",
187 rtlhal->last_hmeboxnum);
188 }
189
190 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
191 rtlhal->h2c_setinprogress = false;
192 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
193
194 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
195}
196
197void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
198 u32 cmd_len, u8 *p_cmdbuffer)
199{
200 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
201 u32 tmp_cmdbuf[2];
202
203 if (!rtlhal->fw_ready) {
204 WARN_ONCE(true,
205 "rtl8723be: error H2C cmd because of Fw download fail!!!\n");
206 return;
207 }
208
209 memset(tmp_cmdbuf, 0, 8);
210 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
211 _rtl8723be_fill_h2c_command(hw, element_id, cmd_len,
212 (u8 *)&tmp_cmdbuf);
213 return;
214}
215
216void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
217{
218 struct rtl_priv *rtlpriv = rtl_priv(hw);
219 u8 u1_h2c_set_pwrmode[H2C_PWEMODE_LENGTH] = { 0 };
220 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
221 u8 rlbm, power_state = 0, byte5 = 0;
222 u8 awake_intvl;
223 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
224 bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
225 btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
226 bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
227 btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
228
229 if (bt_ctrl_lps)
230 mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
231
232 rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
233 mode, bt_ctrl_lps);
234
235 switch (mode) {
236 case FW_PS_MIN_MODE:
237 rlbm = 0;
238 awake_intvl = 2;
239 break;
240 case FW_PS_MAX_MODE:
241 rlbm = 1;
242 awake_intvl = 2;
243 break;
244 case FW_PS_DTIM_MODE:
245 rlbm = 2;
246 awake_intvl = ppsc->reg_max_lps_awakeintvl;
247
248
249
250 break;
251 default:
252 rlbm = 2;
253 awake_intvl = 4;
254 break;
255 }
256
257 if (rtlpriv->mac80211.p2p) {
258 awake_intvl = 2;
259 rlbm = 1;
260 }
261
262 if (mode == FW_PS_ACTIVE_MODE) {
263 byte5 = 0x40;
264 power_state = FW_PWR_STATE_ACTIVE;
265 } else {
266 if (bt_ctrl_lps) {
267 byte5 = btc_ops->btc_get_lps_val(rtlpriv);
268 power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
269
270 if ((rlbm == 2) && (byte5 & BIT(4))) {
271
272
273
274 awake_intvl = 2;
275 rlbm = 2;
276 }
277 } else {
278 byte5 = 0x40;
279 power_state = FW_PWR_STATE_RF_OFF;
280 }
281 }
282
283 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
284 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
285 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
286 bt_ctrl_lps ? 0 : ppsc->smart_ps);
287 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
288 awake_intvl);
289 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
290 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
291 SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
292
293 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
294 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
295 u1_h2c_set_pwrmode, H2C_PWEMODE_LENGTH);
296 if (rtlpriv->cfg->ops->get_btc_status())
297 btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
298 H2C_PWEMODE_LENGTH);
299 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_SETPWRMODE, H2C_PWEMODE_LENGTH,
300 u1_h2c_set_pwrmode);
301}
302
303void rtl8723be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
304{
305 u8 parm[3] = { 0, 0, 0 };
306
307
308
309
310
311
312 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
313 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
314
315 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_MSRRPT, 3, parm);
316}
317
318#define BEACON_PG 0
319#define PSPOLL_PG 2
320#define NULL_PG 3
321#define PROBERSP_PG 4
322#define QOS_NULL_PG 6
323#define BT_QOS_NULL_PG 7
324
325#define TOTAL_RESERVED_PKT_LEN 1024
326
327static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
328
329 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
330 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
331 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
334 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
335 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
336 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
337 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
338 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
342 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
343 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
344 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
345
346
347 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363
364
365 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
366 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381
382
383 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
384 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
385 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399
400
401 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
402 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
403 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
404 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
405 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
406 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
407 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
408 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
409 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
410 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
411 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
415 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417
418
419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
431 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435
436
437 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
438 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
439 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
445 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
449 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453
454
455 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
456 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
457 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471
472};
473
474void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
475 bool b_dl_finished)
476{
477 struct rtl_priv *rtlpriv = rtl_priv(hw);
478 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
479 struct sk_buff *skb = NULL;
480
481 u32 totalpacketlen;
482 bool rtstatus;
483 u8 u1rsvdpageloc[5] = { 0 };
484 bool b_dlok = false;
485
486 u8 *beacon;
487 u8 *p_pspoll;
488 u8 *nullfunc;
489 u8 *p_probersp;
490 u8 *qosnull;
491 u8 *btqosnull;
492
493
494
495
496 beacon = &reserved_page_packet[BEACON_PG * 128];
497 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
498 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
499
500
501
502
503
504 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
505 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
506 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
507 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
508
509 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
510
511
512
513
514
515 nullfunc = &reserved_page_packet[NULL_PG * 128];
516 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
517 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
518 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
519
520 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
521
522
523
524
525
526 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
527 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
528 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
529 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
530
531 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
532
533
534
535
536
537 qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
538 SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
539 SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
540 SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
541
542 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
543
544
545
546
547
548 btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
549 SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
550 SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
551 SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
552
553 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
554
555 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
556
557 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
558 "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
559 &reserved_page_packet[0], totalpacketlen);
560 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
561 "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
562 u1rsvdpageloc, sizeof(u1rsvdpageloc));
563
564 skb = dev_alloc_skb(totalpacketlen);
565 if (!skb)
566 return;
567 skb_put_data(skb, &reserved_page_packet, totalpacketlen);
568
569 rtstatus = rtl_cmd_send_packet(hw, skb);
570
571 if (rtstatus)
572 b_dlok = true;
573
574 if (b_dlok) {
575 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
576 "Set RSVD page location to Fw.\n");
577 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n",
578 u1rsvdpageloc, sizeof(u1rsvdpageloc));
579 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RSVDPAGE,
580 sizeof(u1rsvdpageloc), u1rsvdpageloc);
581 } else
582 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
583 "Set RSVD page location to Fw FAIL!!!!!!.\n");
584}
585
586
587static void rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
588 u8 ctwindow)
589{
590 u8 u1_ctwindow_period[1] = { ctwindow};
591
592 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_CTW_CMD, 1,
593 u1_ctwindow_period);
594}
595
596void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw,
597 u8 p2p_ps_state)
598{
599 struct rtl_priv *rtlpriv = rtl_priv(hw);
600 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
601 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
602 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
603 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
604 u8 i;
605 u16 ctwindow;
606 u32 start_time, tsf_low;
607
608 switch (p2p_ps_state) {
609 case P2P_PS_DISABLE:
610 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
611 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
612 break;
613 case P2P_PS_ENABLE:
614 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
615
616 if (p2pinfo->ctwindow > 0) {
617 p2p_ps_offload->ctwindow_en = 1;
618 ctwindow = p2pinfo->ctwindow;
619 rtl8723be_set_p2p_ctw_period_cmd(hw, ctwindow);
620 }
621
622 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
623
624
625
626 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
627 if (i == 0)
628 p2p_ps_offload->noa0_en = 1;
629 else
630 p2p_ps_offload->noa1_en = 1;
631
632
633 rtl_write_dword(rtlpriv, 0x5E0,
634 p2pinfo->noa_duration[i]);
635 rtl_write_dword(rtlpriv, 0x5E4,
636 p2pinfo->noa_interval[i]);
637
638
639 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
640
641 start_time = p2pinfo->noa_start_time[i];
642 if (p2pinfo->noa_count_type[i] != 1) {
643 while (start_time <= (tsf_low + (50 * 1024))) {
644 start_time += p2pinfo->noa_interval[i];
645 if (p2pinfo->noa_count_type[i] != 255)
646 p2pinfo->noa_count_type[i]--;
647 }
648 }
649 rtl_write_dword(rtlpriv, 0x5E8, start_time);
650 rtl_write_dword(rtlpriv, 0x5EC,
651 p2pinfo->noa_count_type[i]);
652 }
653
654 if ((p2pinfo->opp_ps == 1) ||
655 (p2pinfo->noa_num > 0)) {
656
657 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
658
659 p2p_ps_offload->offload_en = 1;
660
661 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
662 p2p_ps_offload->role = 1;
663 p2p_ps_offload->allstasleep = 0;
664 } else {
665 p2p_ps_offload->role = 0;
666 }
667 p2p_ps_offload->discovery = 0;
668 }
669 break;
670 case P2P_PS_SCAN:
671 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
672 p2p_ps_offload->discovery = 1;
673 break;
674 case P2P_PS_SCAN_DONE:
675 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
676 p2p_ps_offload->discovery = 0;
677 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
678 break;
679 default:
680 break;
681 }
682
683 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_OFFLOAD, 1,
684 (u8 *)p2p_ps_offload);
685}
686