1 /******************************************************************************
3 * Copyright(c) 2009-2012 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
33 #include "../rtl8723com/fw_common.h"
35 static bool _rtl8723e_check_fw_read_last_h2c(struct ieee80211_hw
*hw
,
38 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
39 u8 val_hmetfr
, val_mcutst_1
;
42 val_hmetfr
= rtl_read_byte(rtlpriv
, REG_HMETFR
);
43 val_mcutst_1
= rtl_read_byte(rtlpriv
, (REG_MCUTST_1
+ boxnum
));
45 if (((val_hmetfr
>> boxnum
) & BIT(0)) == 0 && val_mcutst_1
== 0)
50 static void _rtl8723e_fill_h2c_command(struct ieee80211_hw
*hw
, u8 element_id
,
51 u32 cmd_len
, u8
*cmdbuffer
)
53 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
54 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
56 u16 box_reg
= 0, box_extreg
= 0;
58 bool isfw_read
= false;
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;
68 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
, "come in\n");
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",
77 while (rtlhal
->h2c_setinprogress
) {
78 spin_unlock_irqrestore(&rtlpriv
->locks
.h2c_lock
,
81 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
,
82 "Wait 100 us (%d times)...\n",
86 if (h2c_waitcounter
> 1000)
88 spin_lock_irqsave(&rtlpriv
->locks
.h2c_lock
,
91 spin_unlock_irqrestore(&rtlpriv
->locks
.h2c_lock
, flag
);
93 rtlhal
->h2c_setinprogress
= true;
94 spin_unlock_irqrestore(&rtlpriv
->locks
.h2c_lock
, flag
);
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");
107 boxnum
= rtlhal
->last_hmeboxnum
;
110 box_reg
= REG_HMEBOX_0
;
111 box_extreg
= REG_HMEBOX_EXT_0
;
114 box_reg
= REG_HMEBOX_1
;
115 box_extreg
= REG_HMEBOX_EXT_1
;
118 box_reg
= REG_HMEBOX_2
;
119 box_extreg
= REG_HMEBOX_EXT_2
;
122 box_reg
= REG_HMEBOX_3
;
123 box_extreg
= REG_HMEBOX_EXT_3
;
126 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_EMERG
,
127 "switch case not process\n");
131 isfw_read
= _rtl8723e_check_fw_read_last_h2c(hw
, boxnum
);
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",
144 isfw_read
= _rtl8723e_check_fw_read_last_h2c(hw
,
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",
153 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
,
154 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
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
);
168 boxcontent
[0] &= ~(BIT(7));
169 memcpy((u8
*)(boxcontent
) + 1,
170 cmdbuffer
+ buf_index
, 1);
172 for (idx
= 0; idx
< 4; idx
++) {
173 rtl_write_byte(rtlpriv
, box_reg
+ idx
,
178 boxcontent
[0] &= ~(BIT(7));
179 memcpy((u8
*)(boxcontent
) + 1,
180 cmdbuffer
+ buf_index
, 2);
182 for (idx
= 0; idx
< 4; idx
++) {
183 rtl_write_byte(rtlpriv
, box_reg
+ idx
,
188 boxcontent
[0] &= ~(BIT(7));
189 memcpy((u8
*)(boxcontent
) + 1,
190 cmdbuffer
+ buf_index
, 3);
192 for (idx
= 0; idx
< 4; idx
++) {
193 rtl_write_byte(rtlpriv
, box_reg
+ idx
,
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);
204 for (idx
= 0; idx
< 2; idx
++) {
205 rtl_write_byte(rtlpriv
, box_extreg
+ idx
,
209 for (idx
= 0; idx
< 4; idx
++) {
210 rtl_write_byte(rtlpriv
, box_reg
+ idx
,
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);
221 for (idx
= 0; idx
< 2; idx
++) {
222 rtl_write_byte(rtlpriv
, box_extreg
+ idx
,
226 for (idx
= 0; idx
< 4; idx
++) {
227 rtl_write_byte(rtlpriv
, box_reg
+ idx
,
232 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_EMERG
,
233 "switch case not process\n");
237 bwrite_sucess
= true;
239 rtlhal
->last_hmeboxnum
= boxnum
+ 1;
240 if (rtlhal
->last_hmeboxnum
== 4)
241 rtlhal
->last_hmeboxnum
= 0;
243 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
,
244 "pHalData->last_hmeboxnum = %d\n",
245 rtlhal
->last_hmeboxnum
);
248 spin_lock_irqsave(&rtlpriv
->locks
.h2c_lock
, flag
);
249 rtlhal
->h2c_setinprogress
= false;
250 spin_unlock_irqrestore(&rtlpriv
->locks
.h2c_lock
, flag
);
252 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
, "go out\n");
255 void rtl8723e_fill_h2c_cmd(struct ieee80211_hw
*hw
,
256 u8 element_id
, u32 cmd_len
, u8
*cmdbuffer
)
258 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
261 if (!rtlhal
->fw_ready
) {
263 "return H2C cmd because of Fw download fail!!!\n");
266 memset(tmp_cmdbuf
, 0, 8);
267 memcpy(tmp_cmdbuf
, cmdbuffer
, cmd_len
);
268 _rtl8723e_fill_h2c_command(hw
, element_id
, cmd_len
,
272 void rtl8723e_set_fw_pwrmode_cmd(struct ieee80211_hw
*hw
, u8 mode
)
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
));
278 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
, "FW LPS mode = %d\n", mode
);
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
);
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
);
292 #define BEACON_PG 0 /* ->1 */
295 #define PROBERSP_PG 4 /* ->5 */
297 #define TOTAL_RESERVED_PKT_LEN 768
299 static u8 reserved_page_packet
[TOTAL_RESERVED_PKT_LEN
] = {
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,
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,
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,
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,
372 /* page 4 probe_resp */
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,
390 /* page 5 probe_resp */
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,
409 void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw
*hw
, bool b_dl_finished
)
411 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
412 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
413 struct sk_buff
*skb
= NULL
;
416 u8 u1rsvdpageloc
[3] = { 0 };
423 /*---------------------------------------------------------
425 *---------------------------------------------------------
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
);
431 /*-------------------------------------------------------
433 *--------------------------------------------------------
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
);
440 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc
, PSPOLL_PG
);
442 /*--------------------------------------------------------
444 *---------------------------------------------------------
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
);
451 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc
, NULL_PG
);
453 /*---------------------------------------------------------
455 *----------------------------------------------------------
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
);
462 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc
, PROBERSP_PG
);
464 totalpacketlen
= TOTAL_RESERVED_PKT_LEN
;
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",
473 skb
= dev_alloc_skb(totalpacketlen
);
474 memcpy((u8
*)skb_put(skb
, totalpacketlen
),
475 &reserved_page_packet
, totalpacketlen
);
477 rtstatus
= rtl_cmd_send_packet(hw
, skb
);
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
,
488 rtl8723e_fill_h2c_cmd(hw
, H2C_RSVDPAGE
,
489 sizeof(u1rsvdpageloc
), u1rsvdpageloc
);
491 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_WARNING
,
492 "Set RSVD page location to Fw FAIL!!!!!!.\n");
495 void rtl8723e_set_fw_joinbss_report_cmd(struct ieee80211_hw
*hw
, u8 mstatus
)
497 u8 u1_joinbssrpt_parm
[1] = { 0 };
499 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm
, mstatus
);
501 rtl8723e_fill_h2c_cmd(hw
, H2C_JOINBSSRPT
, 1, u1_joinbssrpt_parm
);
504 static void rtl8723e_set_p2p_ctw_period_cmd(struct ieee80211_hw
*hw
,
507 u8 u1_ctwindow_period
[1] = { ctwindow
};
509 rtl8723e_fill_h2c_cmd(hw
, H2C_P2P_PS_CTW_CMD
, 1, u1_ctwindow_period
);
513 void rtl8723e_set_p2p_ps_offload_cmd(struct ieee80211_hw
*hw
, u8 p2p_ps_state
)
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
;
522 u32 start_time
, tsf_low
;
524 switch (p2p_ps_state
) {
526 RT_TRACE(rtlpriv
, COMP_FW
, DBG_LOUD
, "P2P_PS_DISABLE\n");
527 memset(p2p_ps_offload
, 0, sizeof(*p2p_ps_offload
));
530 RT_TRACE(rtlpriv
, COMP_FW
, DBG_LOUD
, "P2P_PS_ENABLE\n");
531 /* update CTWindow value. */
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
);
538 /* hw only support 2 set of NoA */
539 for (i
= 0 ; i
< p2pinfo
->noa_num
; i
++) {
540 /* To control the register setting for which NOA*/
541 rtl_write_byte(rtlpriv
, 0x5cf, (i
<< 4));
543 p2p_ps_offload
->noa0_en
= 1;
545 p2p_ps_offload
->noa1_en
= 1;
547 /* config P2P NoA Descriptor Register */
548 rtl_write_dword(rtlpriv
, 0x5E0,
549 p2pinfo
->noa_duration
[i
]);
550 rtl_write_dword(rtlpriv
, 0x5E4,
551 p2pinfo
->noa_interval
[i
]);
553 /*Get Current TSF value */
554 tsf_low
= rtl_read_dword(rtlpriv
, REG_TSFTR
);
556 start_time
= p2pinfo
->noa_start_time
[i
];
557 if (p2pinfo
->noa_count_type
[i
] != 1) {
559 (tsf_low
+(50*1024))) {
561 p2pinfo
->noa_interval
[i
];
562 if (p2pinfo
->noa_count_type
[i
] != 255)
563 p2pinfo
->noa_count_type
[i
]--;
566 rtl_write_dword(rtlpriv
, 0x5E8, start_time
);
567 rtl_write_dword(rtlpriv
, 0x5EC,
568 p2pinfo
->noa_count_type
[i
]);
572 if ((p2pinfo
->opp_ps
== 1) || (p2pinfo
->noa_num
> 0)) {
573 /* rst p2p circuit */
574 rtl_write_byte(rtlpriv
, REG_DUAL_TSF_RST
, BIT(4));
576 p2p_ps_offload
->offload_en
= 1;
578 if (P2P_ROLE_GO
== rtlpriv
->mac80211
.p2p
) {
579 p2p_ps_offload
->role
= 1;
580 p2p_ps_offload
->allstasleep
= 0;
582 p2p_ps_offload
->role
= 0;
585 p2p_ps_offload
->discovery
= 0;
589 RT_TRACE(rtlpriv
, COMP_FW
, DBG_LOUD
, "P2P_PS_SCAN\n");
590 p2p_ps_offload
->discovery
= 1;
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
;
601 rtl8723e_fill_h2c_cmd(hw
, H2C_P2P_PS_OFFLOAD
, 1, (u8
*)p2p_ps_offload
);