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 pr_err("Write H2C fail because no trigger for FW INT!\n");
104 boxnum = rtlhal->last_hmeboxnum;
107 box_reg = REG_HMEBOX_0;
108 box_extreg = REG_HMEBOX_EXT_0;
111 box_reg = REG_HMEBOX_1;
112 box_extreg = REG_HMEBOX_EXT_1;
115 box_reg = REG_HMEBOX_2;
116 box_extreg = REG_HMEBOX_EXT_2;
119 box_reg = REG_HMEBOX_3;
120 box_extreg = REG_HMEBOX_EXT_3;
123 pr_err("switch case %#x not processed\n",
128 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, boxnum);
131 if (wait_h2c_limmit == 0) {
132 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
133 "Waiting too long for FW read clear HMEBox(%d)!\n",
140 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw,
142 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
143 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
144 "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
149 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
150 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
155 memset(boxcontent, 0, sizeof(boxcontent));
156 memset(boxextcontent, 0, sizeof(boxextcontent));
157 boxcontent[0] = element_id;
158 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
159 "Write element_id box_reg(%4x) = %2x\n",
160 box_reg, element_id);
166 /*boxcontent[0] &= ~(BIT(7));*/
167 memcpy((u8 *)(boxcontent) + 1,
168 p_cmdbuffer + buf_index, cmd_len);
170 for (idx = 0; idx < 4; idx++) {
171 rtl_write_byte(rtlpriv, box_reg + idx,
179 /*boxcontent[0] |= (BIT(7));*/
180 memcpy((u8 *)(boxextcontent),
181 p_cmdbuffer + buf_index+3, cmd_len-3);
182 memcpy((u8 *)(boxcontent) + 1,
183 p_cmdbuffer + buf_index, 3);
185 for (idx = 0; idx < 4; idx++) {
186 rtl_write_byte(rtlpriv, box_extreg + idx,
190 for (idx = 0; idx < 4; idx++) {
191 rtl_write_byte(rtlpriv, box_reg + idx,
196 pr_err("switch case %#x not processed\n",
201 bwrite_sucess = true;
203 rtlhal->last_hmeboxnum = boxnum + 1;
204 if (rtlhal->last_hmeboxnum == 4)
205 rtlhal->last_hmeboxnum = 0;
207 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
208 "pHalData->last_hmeboxnum = %d\n",
209 rtlhal->last_hmeboxnum);
212 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
213 rtlhal->h2c_setinprogress = false;
214 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
216 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
219 void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
220 u32 cmd_len, u8 *p_cmdbuffer)
222 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
225 if (!rtlhal->fw_ready) {
227 "rtl8723be: error H2C cmd because of Fw download fail!!!\n");
231 memset(tmp_cmdbuf, 0, 8);
232 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
233 _rtl8723be_fill_h2c_command(hw, element_id, cmd_len,
238 void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
240 struct rtl_priv *rtlpriv = rtl_priv(hw);
241 u8 u1_h2c_set_pwrmode[H2C_PWEMODE_LENGTH] = { 0 };
242 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
243 u8 rlbm, power_state = 0, byte5 = 0;
244 u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
245 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
246 bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
247 btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
248 bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
249 btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
252 mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
254 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
266 case FW_PS_DTIM_MODE:
268 awake_intvl = ppsc->reg_max_lps_awakeintvl;
269 /* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
270 * is only used in swlps.
279 if (rtlpriv->mac80211.p2p) {
284 if (mode == FW_PS_ACTIVE_MODE) {
286 power_state = FW_PWR_STATE_ACTIVE;
289 byte5 = btc_ops->btc_get_lps_val(rtlpriv);
290 power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
292 if ((rlbm == 2) && (byte5 & BIT(4))) {
293 /* Keep awake interval to 1 to prevent from
294 * decreasing coex performance
301 power_state = FW_PWR_STATE_RF_OFF;
305 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
306 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
307 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
308 bt_ctrl_lps ? 0 : ppsc->smart_ps);
309 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
311 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
312 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
313 SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
315 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
316 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
317 u1_h2c_set_pwrmode, H2C_PWEMODE_LENGTH);
318 if (rtlpriv->cfg->ops->get_btc_status())
319 btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
321 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_SETPWRMODE, H2C_PWEMODE_LENGTH,
325 void rtl8723be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
327 u8 parm[3] = { 0, 0, 0 };
328 /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
329 * bit1=0-->update Media Status to MACID
330 * bit1=1-->update Media Status from MACID to MACID_End
331 * parm[1]: MACID, if this is INFRA_STA, MacID = 0
334 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
335 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
337 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_MSRRPT, 3, parm);
340 #define BEACON_PG 0 /* ->1 */
343 #define PROBERSP_PG 4 /* ->5 */
344 #define QOS_NULL_PG 6
345 #define BT_QOS_NULL_PG 7
347 #define TOTAL_RESERVED_PKT_LEN 1024 /* can be up to 1280 (tx_bndy=245) */
349 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
351 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
352 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
353 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
356 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
357 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
358 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
359 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
360 0x09, 0x03, 0xFF, 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, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
364 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
365 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
366 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
369 0x00, 0x50, 0xF2, 0x02, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
382 0x00, 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,
387 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
388 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
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 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
406 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
407 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0x00, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
417 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
418 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422 /* page 4 probe_resp */
423 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
424 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
425 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
426 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
427 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
428 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
429 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
430 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
431 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
432 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
433 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
437 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 /* page 5 probe_resp */
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458 /* page 6 qos null data */
459 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
460 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
461 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 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 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
471 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476 /* page 7 BT-qos null data */
477 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
478 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
479 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
487 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496 void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
499 struct rtl_priv *rtlpriv = rtl_priv(hw);
500 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
501 struct sk_buff *skb = NULL;
505 u8 u1rsvdpageloc[5] = { 0 };
514 /*---------------------------------------------------------
516 *---------------------------------------------------------
518 beacon = &reserved_page_packet[BEACON_PG * 128];
519 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
520 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
522 /*-------------------------------------------------------
524 *-------------------------------------------------------
526 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
527 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
528 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
529 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
531 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
533 /*--------------------------------------------------------
535 *--------------------------------------------------------
537 nullfunc = &reserved_page_packet[NULL_PG * 128];
538 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
539 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
540 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
542 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
544 /*---------------------------------------------------------
546 *---------------------------------------------------------
548 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
549 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
550 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
551 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
553 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
555 /*---------------------------------------------------------
557 *---------------------------------------------------------
559 qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
560 SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
561 SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
562 SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
564 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
566 /*---------------------------------------------------------
568 *---------------------------------------------------------
570 btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
571 SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
572 SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
573 SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
575 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
577 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
579 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
580 "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
581 &reserved_page_packet[0], totalpacketlen);
582 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
583 "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
584 u1rsvdpageloc, sizeof(u1rsvdpageloc));
586 skb = dev_alloc_skb(totalpacketlen);
589 skb_put_data(skb, &reserved_page_packet, totalpacketlen);
591 rtstatus = rtl_cmd_send_packet(hw, skb);
597 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
598 "Set RSVD page location to Fw.\n");
599 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n",
600 u1rsvdpageloc, sizeof(u1rsvdpageloc));
601 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RSVDPAGE,
602 sizeof(u1rsvdpageloc), u1rsvdpageloc);
604 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
605 "Set RSVD page location to Fw FAIL!!!!!!.\n");
608 /*Should check FW support p2p or not.*/
609 static void rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
612 u8 u1_ctwindow_period[1] = { ctwindow};
614 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_CTW_CMD, 1,
618 void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw,
621 struct rtl_priv *rtlpriv = rtl_priv(hw);
622 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
623 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
624 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
625 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
628 u32 start_time, tsf_low;
630 switch (p2p_ps_state) {
632 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
633 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
636 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
637 /* update CTWindow value. */
638 if (p2pinfo->ctwindow > 0) {
639 p2p_ps_offload->ctwindow_en = 1;
640 ctwindow = p2pinfo->ctwindow;
641 rtl8723be_set_p2p_ctw_period_cmd(hw, ctwindow);
643 /* hw only support 2 set of NoA */
644 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
645 /* To control the register setting
648 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
650 p2p_ps_offload->noa0_en = 1;
652 p2p_ps_offload->noa1_en = 1;
654 /* config P2P NoA Descriptor Register */
655 rtl_write_dword(rtlpriv, 0x5E0,
656 p2pinfo->noa_duration[i]);
657 rtl_write_dword(rtlpriv, 0x5E4,
658 p2pinfo->noa_interval[i]);
660 /*Get Current TSF value */
661 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
663 start_time = p2pinfo->noa_start_time[i];
664 if (p2pinfo->noa_count_type[i] != 1) {
665 while (start_time <= (tsf_low + (50 * 1024))) {
666 start_time += p2pinfo->noa_interval[i];
667 if (p2pinfo->noa_count_type[i] != 255)
668 p2pinfo->noa_count_type[i]--;
671 rtl_write_dword(rtlpriv, 0x5E8, start_time);
672 rtl_write_dword(rtlpriv, 0x5EC,
673 p2pinfo->noa_count_type[i]);
676 if ((p2pinfo->opp_ps == 1) ||
677 (p2pinfo->noa_num > 0)) {
678 /* rst p2p circuit */
679 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
681 p2p_ps_offload->offload_en = 1;
683 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
684 p2p_ps_offload->role = 1;
685 p2p_ps_offload->allstasleep = 0;
687 p2p_ps_offload->role = 0;
689 p2p_ps_offload->discovery = 0;
693 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
694 p2p_ps_offload->discovery = 1;
696 case P2P_PS_SCAN_DONE:
697 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
698 p2p_ps_offload->discovery = 0;
699 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
705 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_OFFLOAD, 1,
706 (u8 *)p2p_ps_offload);
709 void rtl8723be_c2h_content_parsing(struct ieee80211_hw *hw,
711 u8 c2h_cmd_len, u8 *tmp_buf)
713 struct rtl_priv *rtlpriv = rtl_priv(hw);
714 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
716 switch (c2h_cmd_id) {
718 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
719 "[C2H], C2H_8723BE_DBG!!\n");
721 case C2H_8723B_TX_REPORT:
722 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
723 "[C2H], C2H_8723BE_TX_REPORT!\n");
724 rtl_tx_report_handler(hw, tmp_buf, c2h_cmd_len);
726 case C2H_8723B_BT_INFO:
727 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
728 "[C2H], C2H_8723BE_BT_INFO!!\n");
729 if (rtlpriv->cfg->ops->get_btc_status())
730 btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
733 case C2H_8723B_BT_MP:
734 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
735 "[C2H], C2H_8723BE_BT_MP!!\n");
736 if (rtlpriv->cfg->ops->get_btc_status())
737 btc_ops->btc_btmpinfo_notify(rtlpriv, tmp_buf,
741 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
742 "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
747 void rtl8723be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
749 struct rtl_priv *rtlpriv = rtl_priv(hw);
750 u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
753 c2h_cmd_id = buffer[0];
754 c2h_cmd_seq = buffer[1];
755 c2h_cmd_len = len - 2;
756 tmp_buf = buffer + 2;
758 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
759 "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
760 c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
762 RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
763 "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
765 switch (c2h_cmd_id) {
766 case C2H_8723B_BT_INFO:
767 case C2H_8723B_BT_MP:
768 rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
772 rtl8723be_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,