0001
0002
0003
0004 #include "../wifi.h"
0005 #include "../pci.h"
0006 #include "../base.h"
0007 #include "../core.h"
0008 #include "reg.h"
0009 #include "def.h"
0010 #include "fw.h"
0011 #include "../rtl8723com/fw_common.h"
0012
0013 static bool _rtl8723be_check_fw_read_last_h2c(struct ieee80211_hw *hw,
0014 u8 boxnum)
0015 {
0016 struct rtl_priv *rtlpriv = rtl_priv(hw);
0017 u8 val_hmetfr;
0018 bool result = false;
0019
0020 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
0021 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
0022 result = true;
0023 return result;
0024 }
0025
0026 static void _rtl8723be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
0027 u32 cmd_len, u8 *p_cmdbuffer)
0028 {
0029 struct rtl_priv *rtlpriv = rtl_priv(hw);
0030 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0031 u8 boxnum;
0032 u16 box_reg = 0, box_extreg = 0;
0033 u8 u1b_tmp;
0034 bool isfw_read = false;
0035 u8 buf_index = 0;
0036 bool bwrite_sucess = false;
0037 u8 wait_h2c_limmit = 100;
0038 u8 wait_writeh2c_limmit = 100;
0039 u8 boxcontent[4], boxextcontent[4];
0040 u32 h2c_waitcounter = 0;
0041 unsigned long flag;
0042 u8 idx;
0043
0044 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
0045
0046 while (true) {
0047 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
0048 if (rtlhal->h2c_setinprogress) {
0049 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0050 "H2C set in progress! Wait to set..element_id(%d).\n",
0051 element_id);
0052
0053 while (rtlhal->h2c_setinprogress) {
0054 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
0055 flag);
0056 h2c_waitcounter++;
0057 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0058 "Wait 100 us (%d times)...\n",
0059 h2c_waitcounter);
0060 udelay(100);
0061
0062 if (h2c_waitcounter > 1000)
0063 return;
0064 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
0065 flag);
0066 }
0067 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0068 } else {
0069 rtlhal->h2c_setinprogress = true;
0070 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0071 break;
0072 }
0073 }
0074
0075 while (!bwrite_sucess) {
0076 wait_writeh2c_limmit--;
0077 if (wait_writeh2c_limmit == 0) {
0078 pr_err("Write H2C fail because no trigger for FW INT!\n");
0079 break;
0080 }
0081
0082 boxnum = rtlhal->last_hmeboxnum;
0083 switch (boxnum) {
0084 case 0:
0085 box_reg = REG_HMEBOX_0;
0086 box_extreg = REG_HMEBOX_EXT_0;
0087 break;
0088 case 1:
0089 box_reg = REG_HMEBOX_1;
0090 box_extreg = REG_HMEBOX_EXT_1;
0091 break;
0092 case 2:
0093 box_reg = REG_HMEBOX_2;
0094 box_extreg = REG_HMEBOX_EXT_2;
0095 break;
0096 case 3:
0097 box_reg = REG_HMEBOX_3;
0098 box_extreg = REG_HMEBOX_EXT_3;
0099 break;
0100 default:
0101 pr_err("switch case %#x not processed\n",
0102 boxnum);
0103 break;
0104 }
0105
0106 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, boxnum);
0107 while (!isfw_read) {
0108 wait_h2c_limmit--;
0109 if (wait_h2c_limmit == 0) {
0110 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0111 "Waiting too long for FW read clear HMEBox(%d)!\n",
0112 boxnum);
0113 break;
0114 }
0115
0116 udelay(10);
0117
0118 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw,
0119 boxnum);
0120 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
0121 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0122 "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
0123 boxnum, u1b_tmp);
0124 }
0125
0126 if (!isfw_read) {
0127 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0128 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
0129 boxnum);
0130 break;
0131 }
0132
0133 memset(boxcontent, 0, sizeof(boxcontent));
0134 memset(boxextcontent, 0, sizeof(boxextcontent));
0135 boxcontent[0] = element_id;
0136 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0137 "Write element_id box_reg(%4x) = %2x\n",
0138 box_reg, element_id);
0139
0140 switch (cmd_len) {
0141 case 1:
0142 case 2:
0143 case 3:
0144
0145 memcpy((u8 *)(boxcontent) + 1,
0146 p_cmdbuffer + buf_index, cmd_len);
0147
0148 for (idx = 0; idx < 4; idx++) {
0149 rtl_write_byte(rtlpriv, box_reg + idx,
0150 boxcontent[idx]);
0151 }
0152 break;
0153 case 4:
0154 case 5:
0155 case 6:
0156 case 7:
0157
0158 memcpy((u8 *)(boxextcontent),
0159 p_cmdbuffer + buf_index+3, cmd_len-3);
0160 memcpy((u8 *)(boxcontent) + 1,
0161 p_cmdbuffer + buf_index, 3);
0162
0163 for (idx = 0; idx < 4; idx++) {
0164 rtl_write_byte(rtlpriv, box_extreg + idx,
0165 boxextcontent[idx]);
0166 }
0167
0168 for (idx = 0; idx < 4; idx++) {
0169 rtl_write_byte(rtlpriv, box_reg + idx,
0170 boxcontent[idx]);
0171 }
0172 break;
0173 default:
0174 pr_err("switch case %#x not processed\n",
0175 cmd_len);
0176 break;
0177 }
0178
0179 bwrite_sucess = true;
0180
0181 rtlhal->last_hmeboxnum = boxnum + 1;
0182 if (rtlhal->last_hmeboxnum == 4)
0183 rtlhal->last_hmeboxnum = 0;
0184
0185 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0186 "pHalData->last_hmeboxnum = %d\n",
0187 rtlhal->last_hmeboxnum);
0188 }
0189
0190 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
0191 rtlhal->h2c_setinprogress = false;
0192 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0193
0194 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
0195 }
0196
0197 void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
0198 u32 cmd_len, u8 *p_cmdbuffer)
0199 {
0200 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0201 u32 tmp_cmdbuf[2];
0202
0203 if (!rtlhal->fw_ready) {
0204 WARN_ONCE(true,
0205 "rtl8723be: error H2C cmd because of Fw download fail!!!\n");
0206 return;
0207 }
0208
0209 memset(tmp_cmdbuf, 0, 8);
0210 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
0211 _rtl8723be_fill_h2c_command(hw, element_id, cmd_len,
0212 (u8 *)&tmp_cmdbuf);
0213 return;
0214 }
0215
0216 void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
0217 {
0218 struct rtl_priv *rtlpriv = rtl_priv(hw);
0219 u8 u1_h2c_set_pwrmode[H2C_PWEMODE_LENGTH] = { 0 };
0220 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
0221 u8 rlbm, power_state = 0, byte5 = 0;
0222 u8 awake_intvl;
0223 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
0224 bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
0225 btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
0226 bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
0227 btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
0228
0229 if (bt_ctrl_lps)
0230 mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
0231
0232 rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
0233 mode, bt_ctrl_lps);
0234
0235 switch (mode) {
0236 case FW_PS_MIN_MODE:
0237 rlbm = 0;
0238 awake_intvl = 2;
0239 break;
0240 case FW_PS_MAX_MODE:
0241 rlbm = 1;
0242 awake_intvl = 2;
0243 break;
0244 case FW_PS_DTIM_MODE:
0245 rlbm = 2;
0246 awake_intvl = ppsc->reg_max_lps_awakeintvl;
0247
0248
0249
0250 break;
0251 default:
0252 rlbm = 2;
0253 awake_intvl = 4;
0254 break;
0255 }
0256
0257 if (rtlpriv->mac80211.p2p) {
0258 awake_intvl = 2;
0259 rlbm = 1;
0260 }
0261
0262 if (mode == FW_PS_ACTIVE_MODE) {
0263 byte5 = 0x40;
0264 power_state = FW_PWR_STATE_ACTIVE;
0265 } else {
0266 if (bt_ctrl_lps) {
0267 byte5 = btc_ops->btc_get_lps_val(rtlpriv);
0268 power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
0269
0270 if ((rlbm == 2) && (byte5 & BIT(4))) {
0271
0272
0273
0274 awake_intvl = 2;
0275 rlbm = 2;
0276 }
0277 } else {
0278 byte5 = 0x40;
0279 power_state = FW_PWR_STATE_RF_OFF;
0280 }
0281 }
0282
0283 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
0284 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
0285 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
0286 bt_ctrl_lps ? 0 : ppsc->smart_ps);
0287 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
0288 awake_intvl);
0289 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
0290 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
0291 SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
0292
0293 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
0294 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
0295 u1_h2c_set_pwrmode, H2C_PWEMODE_LENGTH);
0296 if (rtlpriv->cfg->ops->get_btc_status())
0297 btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
0298 H2C_PWEMODE_LENGTH);
0299 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_SETPWRMODE, H2C_PWEMODE_LENGTH,
0300 u1_h2c_set_pwrmode);
0301 }
0302
0303 void rtl8723be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
0304 {
0305 u8 parm[3] = { 0, 0, 0 };
0306
0307
0308
0309
0310
0311
0312 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
0313 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
0314
0315 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_MSRRPT, 3, parm);
0316 }
0317
0318 #define BEACON_PG 0
0319 #define PSPOLL_PG 2
0320 #define NULL_PG 3
0321 #define PROBERSP_PG 4
0322 #define QOS_NULL_PG 6
0323 #define BT_QOS_NULL_PG 7
0324
0325 #define TOTAL_RESERVED_PKT_LEN 1024
0326
0327 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
0328
0329 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0330 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
0331 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
0332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0333 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
0334 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
0335 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
0336 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
0337 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
0338 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0341 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
0342 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
0343 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
0344 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
0345
0346
0347 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
0348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0358 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0359 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
0360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0363
0364
0365 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
0366 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
0367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0376 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0377 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0380 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0381
0382
0383 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
0384 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
0385 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
0386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0394 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0395 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0398 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0399
0400
0401 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0402 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0403 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0404 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
0405 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0406 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0407 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0408 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0409 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0410 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0411 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0414 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0415 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0417
0418
0419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0430 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0431 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0434 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0435
0436
0437 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0438 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0439 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0445 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0448 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0449 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
0450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0452 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0453
0454
0455 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0456 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0457 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0469 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0470 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0471
0472 };
0473
0474 void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
0475 bool b_dl_finished)
0476 {
0477 struct rtl_priv *rtlpriv = rtl_priv(hw);
0478 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0479 struct sk_buff *skb = NULL;
0480
0481 u32 totalpacketlen;
0482 bool rtstatus;
0483 u8 u1rsvdpageloc[5] = { 0 };
0484 bool b_dlok = false;
0485
0486 u8 *beacon;
0487 u8 *p_pspoll;
0488 u8 *nullfunc;
0489 u8 *p_probersp;
0490 u8 *qosnull;
0491 u8 *btqosnull;
0492
0493
0494
0495
0496 beacon = &reserved_page_packet[BEACON_PG * 128];
0497 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
0498 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
0499
0500
0501
0502
0503
0504 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
0505 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
0506 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
0507 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
0508
0509 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
0510
0511
0512
0513
0514
0515 nullfunc = &reserved_page_packet[NULL_PG * 128];
0516 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
0517 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
0518 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
0519
0520 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
0521
0522
0523
0524
0525
0526 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
0527 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
0528 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
0529 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
0530
0531 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
0532
0533
0534
0535
0536
0537 qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
0538 SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
0539 SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
0540 SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
0541
0542 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
0543
0544
0545
0546
0547
0548 btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
0549 SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
0550 SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
0551 SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
0552
0553 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
0554
0555 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
0556
0557 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
0558 "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
0559 &reserved_page_packet[0], totalpacketlen);
0560 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
0561 "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
0562 u1rsvdpageloc, sizeof(u1rsvdpageloc));
0563
0564 skb = dev_alloc_skb(totalpacketlen);
0565 if (!skb)
0566 return;
0567 skb_put_data(skb, &reserved_page_packet, totalpacketlen);
0568
0569 rtstatus = rtl_cmd_send_packet(hw, skb);
0570
0571 if (rtstatus)
0572 b_dlok = true;
0573
0574 if (b_dlok) {
0575 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0576 "Set RSVD page location to Fw.\n");
0577 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n",
0578 u1rsvdpageloc, sizeof(u1rsvdpageloc));
0579 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RSVDPAGE,
0580 sizeof(u1rsvdpageloc), u1rsvdpageloc);
0581 } else
0582 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
0583 "Set RSVD page location to Fw FAIL!!!!!!.\n");
0584 }
0585
0586
0587 static void rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
0588 u8 ctwindow)
0589 {
0590 u8 u1_ctwindow_period[1] = { ctwindow};
0591
0592 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_CTW_CMD, 1,
0593 u1_ctwindow_period);
0594 }
0595
0596 void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw,
0597 u8 p2p_ps_state)
0598 {
0599 struct rtl_priv *rtlpriv = rtl_priv(hw);
0600 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
0601 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0602 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
0603 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
0604 u8 i;
0605 u16 ctwindow;
0606 u32 start_time, tsf_low;
0607
0608 switch (p2p_ps_state) {
0609 case P2P_PS_DISABLE:
0610 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
0611 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
0612 break;
0613 case P2P_PS_ENABLE:
0614 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
0615
0616 if (p2pinfo->ctwindow > 0) {
0617 p2p_ps_offload->ctwindow_en = 1;
0618 ctwindow = p2pinfo->ctwindow;
0619 rtl8723be_set_p2p_ctw_period_cmd(hw, ctwindow);
0620 }
0621
0622 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
0623
0624
0625
0626 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
0627 if (i == 0)
0628 p2p_ps_offload->noa0_en = 1;
0629 else
0630 p2p_ps_offload->noa1_en = 1;
0631
0632
0633 rtl_write_dword(rtlpriv, 0x5E0,
0634 p2pinfo->noa_duration[i]);
0635 rtl_write_dword(rtlpriv, 0x5E4,
0636 p2pinfo->noa_interval[i]);
0637
0638
0639 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
0640
0641 start_time = p2pinfo->noa_start_time[i];
0642 if (p2pinfo->noa_count_type[i] != 1) {
0643 while (start_time <= (tsf_low + (50 * 1024))) {
0644 start_time += p2pinfo->noa_interval[i];
0645 if (p2pinfo->noa_count_type[i] != 255)
0646 p2pinfo->noa_count_type[i]--;
0647 }
0648 }
0649 rtl_write_dword(rtlpriv, 0x5E8, start_time);
0650 rtl_write_dword(rtlpriv, 0x5EC,
0651 p2pinfo->noa_count_type[i]);
0652 }
0653
0654 if ((p2pinfo->opp_ps == 1) ||
0655 (p2pinfo->noa_num > 0)) {
0656
0657 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
0658
0659 p2p_ps_offload->offload_en = 1;
0660
0661 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
0662 p2p_ps_offload->role = 1;
0663 p2p_ps_offload->allstasleep = 0;
0664 } else {
0665 p2p_ps_offload->role = 0;
0666 }
0667 p2p_ps_offload->discovery = 0;
0668 }
0669 break;
0670 case P2P_PS_SCAN:
0671 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
0672 p2p_ps_offload->discovery = 1;
0673 break;
0674 case P2P_PS_SCAN_DONE:
0675 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
0676 p2p_ps_offload->discovery = 0;
0677 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
0678 break;
0679 default:
0680 break;
0681 }
0682
0683 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_OFFLOAD, 1,
0684 (u8 *)p2p_ps_offload);
0685 }