1 /******************************************************************************
3 * Copyright(c) 2009-2014 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 _rtl8723be_check_fw_read_last_h2c(struct ieee80211_hw
*hw
,
38 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
42 val_hmetfr
= rtl_read_byte(rtlpriv
, REG_HMETFR
);
43 if (((val_hmetfr
>> boxnum
) & BIT(0)) == 0)
48 static void _rtl8723be_fill_h2c_command(struct ieee80211_hw
*hw
, u8 element_id
,
49 u32 cmd_len
, u8
*p_cmdbuffer
)
51 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
52 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
54 u16 box_reg
= 0, box_extreg
= 0;
56 bool isfw_read
= false;
58 bool bwrite_sucess
= false;
59 u8 wait_h2c_limmit
= 100;
60 u8 wait_writeh2c_limmit
= 100;
61 u8 boxcontent
[4], boxextcontent
[4];
62 u32 h2c_waitcounter
= 0;
66 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
, "come in\n");
69 spin_lock_irqsave(&rtlpriv
->locks
.h2c_lock
, flag
);
70 if (rtlhal
->h2c_setinprogress
) {
71 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
,
72 "H2C set in progress! Wait to set..element_id(%d).\n",
75 while (rtlhal
->h2c_setinprogress
) {
76 spin_unlock_irqrestore(&rtlpriv
->locks
.h2c_lock
,
79 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
,
80 "Wait 100 us (%d times)...\n",
84 if (h2c_waitcounter
> 1000)
86 spin_lock_irqsave(&rtlpriv
->locks
.h2c_lock
,
89 spin_unlock_irqrestore(&rtlpriv
->locks
.h2c_lock
, flag
);
91 rtlhal
->h2c_setinprogress
= true;
92 spin_unlock_irqrestore(&rtlpriv
->locks
.h2c_lock
, flag
);
97 while (!bwrite_sucess
) {
98 wait_writeh2c_limmit
--;
99 if (wait_writeh2c_limmit
== 0) {
100 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_EMERG
,
101 "Write H2C fail because no trigger for FW INT!\n");
105 boxnum
= rtlhal
->last_hmeboxnum
;
108 box_reg
= REG_HMEBOX_0
;
109 box_extreg
= REG_HMEBOX_EXT_0
;
112 box_reg
= REG_HMEBOX_1
;
113 box_extreg
= REG_HMEBOX_EXT_1
;
116 box_reg
= REG_HMEBOX_2
;
117 box_extreg
= REG_HMEBOX_EXT_2
;
120 box_reg
= REG_HMEBOX_3
;
121 box_extreg
= REG_HMEBOX_EXT_3
;
124 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_EMERG
,
125 "switch case not process\n");
129 isfw_read
= _rtl8723be_check_fw_read_last_h2c(hw
, boxnum
);
132 if (wait_h2c_limmit
== 0) {
133 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
,
134 "Waiting too long for FW read clear HMEBox(%d)!\n",
141 isfw_read
= _rtl8723be_check_fw_read_last_h2c(hw
,
143 u1b_tmp
= rtl_read_byte(rtlpriv
, 0x130);
144 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
,
145 "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
150 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
,
151 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
156 memset(boxcontent
, 0, sizeof(boxcontent
));
157 memset(boxextcontent
, 0, sizeof(boxextcontent
));
158 boxcontent
[0] = element_id
;
159 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
,
160 "Write element_id box_reg(%4x) = %2x\n",
161 box_reg
, element_id
);
167 /*boxcontent[0] &= ~(BIT(7));*/
168 memcpy((u8
*)(boxcontent
) + 1,
169 p_cmdbuffer
+ buf_index
, cmd_len
);
171 for (idx
= 0; idx
< 4; idx
++) {
172 rtl_write_byte(rtlpriv
, box_reg
+ idx
,
180 /*boxcontent[0] |= (BIT(7));*/
181 memcpy((u8
*)(boxextcontent
),
182 p_cmdbuffer
+ buf_index
+3, cmd_len
-3);
183 memcpy((u8
*)(boxcontent
) + 1,
184 p_cmdbuffer
+ buf_index
, 3);
186 for (idx
= 0; idx
< 4; idx
++) {
187 rtl_write_byte(rtlpriv
, box_extreg
+ idx
,
191 for (idx
= 0; idx
< 4; idx
++) {
192 rtl_write_byte(rtlpriv
, box_reg
+ idx
,
197 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_EMERG
,
198 "switch case not process\n");
202 bwrite_sucess
= true;
204 rtlhal
->last_hmeboxnum
= boxnum
+ 1;
205 if (rtlhal
->last_hmeboxnum
== 4)
206 rtlhal
->last_hmeboxnum
= 0;
208 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
,
209 "pHalData->last_hmeboxnum = %d\n",
210 rtlhal
->last_hmeboxnum
);
213 spin_lock_irqsave(&rtlpriv
->locks
.h2c_lock
, flag
);
214 rtlhal
->h2c_setinprogress
= false;
215 spin_unlock_irqrestore(&rtlpriv
->locks
.h2c_lock
, flag
);
217 RT_TRACE(rtlpriv
, COMP_CMD
, DBG_LOUD
, "go out\n");
220 void rtl8723be_fill_h2c_cmd(struct ieee80211_hw
*hw
, u8 element_id
,
221 u32 cmd_len
, u8
*p_cmdbuffer
)
223 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
226 if (!rtlhal
->fw_ready
) {
228 "return H2C cmd because of Fw download fail!!!\n");
232 memset(tmp_cmdbuf
, 0, 8);
233 memcpy(tmp_cmdbuf
, p_cmdbuffer
, cmd_len
);
234 _rtl8723be_fill_h2c_command(hw
, element_id
, cmd_len
,
239 void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw
*hw
, u8 mode
)
241 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
242 u8 u1_h2c_set_pwrmode
[H2C_PWEMODE_LENGTH
] = { 0 };
243 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
244 u8 rlbm
, power_state
= 0;
245 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
, "FW LPS mode = %d\n", mode
);
247 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode
, ((mode
) ? 1 : 0));
248 rlbm
= 0;/*YJ,temp,120316. FW now not support RLBM=2.*/
249 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode
, rlbm
);
250 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode
,
251 (rtlpriv
->mac80211
.p2p
) ?
253 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode
,
254 ppsc
->reg_max_lps_awakeintvl
);
255 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode
, 0);
256 if (mode
== FW_PS_ACTIVE_MODE
)
257 power_state
|= FW_PWR_STATE_ACTIVE
;
259 power_state
|= FW_PWR_STATE_RF_OFF
;
260 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode
, power_state
);
262 RT_PRINT_DATA(rtlpriv
, COMP_CMD
, DBG_DMESG
,
263 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
264 u1_h2c_set_pwrmode
, H2C_PWEMODE_LENGTH
);
265 rtl8723be_fill_h2c_cmd(hw
, H2C_8723B_SETPWRMODE
, H2C_PWEMODE_LENGTH
,
269 void rtl8723be_set_fw_media_status_rpt_cmd(struct ieee80211_hw
*hw
, u8 mstatus
)
271 u8 parm
[3] = { 0, 0, 0 };
272 /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
273 * bit1=0-->update Media Status to MACID
274 * bit1=1-->update Media Status from MACID to MACID_End
275 * parm[1]: MACID, if this is INFRA_STA, MacID = 0
278 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm
, mstatus
);
279 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm
, 0);
281 rtl8723be_fill_h2c_cmd(hw
, H2C_8723B_MSRRPT
, 3, parm
);
284 #define BEACON_PG 0 /* ->1 */
287 #define PROBERSP_PG 4 /* ->5 */
289 #define TOTAL_RESERVED_PKT_LEN 768
291 static u8 reserved_page_packet
[TOTAL_RESERVED_PKT_LEN
] = {
293 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
294 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
295 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
298 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
299 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
300 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
301 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
302 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
306 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
307 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
308 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
311 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 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,
329 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
330 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
348 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
349 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 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 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 /* page 4 probe_resp */
365 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
366 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
367 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
368 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
369 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
370 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
371 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
372 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
373 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
374 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
375 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
379 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 /* page 5 probe_resp */
383 0x00, 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 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 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,
401 void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw
*hw
,
404 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
405 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
406 struct sk_buff
*skb
= NULL
;
410 u8 u1rsvdpageloc
[5] = { 0 };
417 /*---------------------------------------------------------
419 *---------------------------------------------------------
421 beacon
= &reserved_page_packet
[BEACON_PG
* 128];
422 SET_80211_HDR_ADDRESS2(beacon
, mac
->mac_addr
);
423 SET_80211_HDR_ADDRESS3(beacon
, mac
->bssid
);
425 /*-------------------------------------------------------
427 *-------------------------------------------------------
429 p_pspoll
= &reserved_page_packet
[PSPOLL_PG
* 128];
430 SET_80211_PS_POLL_AID(p_pspoll
, (mac
->assoc_id
| 0xc000));
431 SET_80211_PS_POLL_BSSID(p_pspoll
, mac
->bssid
);
432 SET_80211_PS_POLL_TA(p_pspoll
, mac
->mac_addr
);
434 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc
, PSPOLL_PG
);
436 /*--------------------------------------------------------
438 *--------------------------------------------------------
440 nullfunc
= &reserved_page_packet
[NULL_PG
* 128];
441 SET_80211_HDR_ADDRESS1(nullfunc
, mac
->bssid
);
442 SET_80211_HDR_ADDRESS2(nullfunc
, mac
->mac_addr
);
443 SET_80211_HDR_ADDRESS3(nullfunc
, mac
->bssid
);
445 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc
, NULL_PG
);
447 /*---------------------------------------------------------
449 *---------------------------------------------------------
451 p_probersp
= &reserved_page_packet
[PROBERSP_PG
* 128];
452 SET_80211_HDR_ADDRESS1(p_probersp
, mac
->bssid
);
453 SET_80211_HDR_ADDRESS2(p_probersp
, mac
->mac_addr
);
454 SET_80211_HDR_ADDRESS3(p_probersp
, mac
->bssid
);
456 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc
, PROBERSP_PG
);
458 totalpacketlen
= TOTAL_RESERVED_PKT_LEN
;
460 RT_PRINT_DATA(rtlpriv
, COMP_CMD
, DBG_LOUD
,
461 "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
462 &reserved_page_packet
[0], totalpacketlen
);
463 RT_PRINT_DATA(rtlpriv
, COMP_CMD
, DBG_DMESG
,
464 "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
467 skb
= dev_alloc_skb(totalpacketlen
);
468 memcpy((u8
*)skb_put(skb
, totalpacketlen
),
469 &reserved_page_packet
, totalpacketlen
);
471 rtstatus
= rtl_cmd_send_packet(hw
, skb
);
477 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
478 "Set RSVD page location to Fw.\n");
479 RT_PRINT_DATA(rtlpriv
, COMP_CMD
, DBG_DMESG
, "H2C_RSVDPAGE:\n",
481 rtl8723be_fill_h2c_cmd(hw
, H2C_8723B_RSVDPAGE
,
482 sizeof(u1rsvdpageloc
), u1rsvdpageloc
);
484 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_WARNING
,
485 "Set RSVD page location to Fw FAIL!!!!!!.\n");
488 /*Should check FW support p2p or not.*/
489 static void rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw
*hw
,
492 u8 u1_ctwindow_period
[1] = { ctwindow
};
494 rtl8723be_fill_h2c_cmd(hw
, H2C_8723B_P2P_PS_CTW_CMD
, 1,
498 void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw
*hw
,
501 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
502 struct rtl_ps_ctl
*rtlps
= rtl_psc(rtl_priv(hw
));
503 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
504 struct rtl_p2p_ps_info
*p2pinfo
= &(rtlps
->p2p_ps_info
);
505 struct p2p_ps_offload_t
*p2p_ps_offload
= &rtlhal
->p2p_ps_offload
;
508 u32 start_time
, tsf_low
;
510 switch (p2p_ps_state
) {
512 RT_TRACE(rtlpriv
, COMP_FW
, DBG_LOUD
, "P2P_PS_DISABLE\n");
513 memset(p2p_ps_offload
, 0, sizeof(*p2p_ps_offload
));
516 RT_TRACE(rtlpriv
, COMP_FW
, DBG_LOUD
, "P2P_PS_ENABLE\n");
517 /* update CTWindow value. */
518 if (p2pinfo
->ctwindow
> 0) {
519 p2p_ps_offload
->ctwindow_en
= 1;
520 ctwindow
= p2pinfo
->ctwindow
;
521 rtl8723be_set_p2p_ctw_period_cmd(hw
, ctwindow
);
523 /* hw only support 2 set of NoA */
524 for (i
= 0 ; i
< p2pinfo
->noa_num
; i
++) {
525 /* To control the register setting
528 rtl_write_byte(rtlpriv
, 0x5cf, (i
<< 4));
530 p2p_ps_offload
->noa0_en
= 1;
532 p2p_ps_offload
->noa1_en
= 1;
534 /* config P2P NoA Descriptor Register */
535 rtl_write_dword(rtlpriv
, 0x5E0,
536 p2pinfo
->noa_duration
[i
]);
537 rtl_write_dword(rtlpriv
, 0x5E4,
538 p2pinfo
->noa_interval
[i
]);
540 /*Get Current TSF value */
541 tsf_low
= rtl_read_dword(rtlpriv
, REG_TSFTR
);
543 start_time
= p2pinfo
->noa_start_time
[i
];
544 if (p2pinfo
->noa_count_type
[i
] != 1) {
545 while (start_time
<= (tsf_low
+ (50 * 1024))) {
546 start_time
+= p2pinfo
->noa_interval
[i
];
547 if (p2pinfo
->noa_count_type
[i
] != 255)
548 p2pinfo
->noa_count_type
[i
]--;
551 rtl_write_dword(rtlpriv
, 0x5E8, start_time
);
552 rtl_write_dword(rtlpriv
, 0x5EC,
553 p2pinfo
->noa_count_type
[i
]);
556 if ((p2pinfo
->opp_ps
== 1) ||
557 (p2pinfo
->noa_num
> 0)) {
558 /* rst p2p circuit */
559 rtl_write_byte(rtlpriv
, REG_DUAL_TSF_RST
, BIT(4));
561 p2p_ps_offload
->offload_en
= 1;
563 if (P2P_ROLE_GO
== rtlpriv
->mac80211
.p2p
) {
564 p2p_ps_offload
->role
= 1;
565 p2p_ps_offload
->allstasleep
= 0;
567 p2p_ps_offload
->role
= 0;
569 p2p_ps_offload
->discovery
= 0;
573 RT_TRACE(rtlpriv
, COMP_FW
, DBG_LOUD
, "P2P_PS_SCAN\n");
574 p2p_ps_offload
->discovery
= 1;
576 case P2P_PS_SCAN_DONE
:
577 RT_TRACE(rtlpriv
, COMP_FW
, DBG_LOUD
, "P2P_PS_SCAN_DONE\n");
578 p2p_ps_offload
->discovery
= 0;
579 p2pinfo
->p2p_ps_state
= P2P_PS_ENABLE
;
585 rtl8723be_fill_h2c_cmd(hw
, H2C_8723B_P2P_PS_OFFLOAD
, 1,
586 (u8
*)p2p_ps_offload
);
589 static void _rtl8723be_c2h_content_parsing(struct ieee80211_hw
*hw
,
591 u8 c2h_cmd_len
, u8
*tmp_buf
)
593 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
595 switch (c2h_cmd_id
) {
597 RT_TRACE(rtlpriv
, COMP_FW
, DBG_TRACE
,
598 "[C2H], C2H_8723BE_DBG!!\n");
600 case C2H_8723B_TX_REPORT
:
601 RT_TRACE(rtlpriv
, COMP_FW
, DBG_TRACE
,
602 "[C2H], C2H_8723BE_TX_REPORT!\n");
604 case C2H_8723B_BT_INFO
:
605 RT_TRACE(rtlpriv
, COMP_FW
, DBG_TRACE
,
606 "[C2H], C2H_8723BE_BT_INFO!!\n");
607 rtlpriv
->btcoexist
.btc_ops
->btc_btinfo_notify(rtlpriv
, tmp_buf
,
610 case C2H_8723B_BT_MP
:
611 RT_TRACE(rtlpriv
, COMP_FW
, DBG_TRACE
,
612 "[C2H], C2H_8723BE_BT_MP!!\n");
615 RT_TRACE(rtlpriv
, COMP_FW
, DBG_TRACE
,
616 "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id
);
621 void rtl8723be_c2h_packet_handler(struct ieee80211_hw
*hw
, u8
*buffer
, u8 len
)
623 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
624 u8 c2h_cmd_id
= 0, c2h_cmd_seq
= 0, c2h_cmd_len
= 0;
627 c2h_cmd_id
= buffer
[0];
628 c2h_cmd_seq
= buffer
[1];
629 c2h_cmd_len
= len
- 2;
630 tmp_buf
= buffer
+ 2;
632 RT_TRACE(rtlpriv
, COMP_FW
, DBG_TRACE
,
633 "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
634 c2h_cmd_id
, c2h_cmd_seq
, c2h_cmd_len
);
636 RT_PRINT_DATA(rtlpriv
, COMP_FW
, DBG_TRACE
,
637 "[C2H packet], Content Hex:\n", tmp_buf
, c2h_cmd_len
);
639 _rtl8723be_c2h_content_parsing(hw
, c2h_cmd_id
, c2h_cmd_len
, tmp_buf
);