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