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