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 _rtl8723e_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, val_mcutst_1;
0018 bool result = false;
0019
0020 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
0021 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
0022
0023 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
0024 result = true;
0025 return result;
0026 }
0027
0028 static void _rtl8723e_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
0029 u32 cmd_len, u8 *cmdbuffer)
0030 {
0031 struct rtl_priv *rtlpriv = rtl_priv(hw);
0032 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0033 u8 boxnum;
0034 u16 box_reg = 0, box_extreg = 0;
0035 u8 u1b_tmp;
0036 bool isfw_read = false;
0037 u8 buf_index = 0;
0038 bool bwrite_sucess = false;
0039 u8 wait_h2c_limmit = 100;
0040 u8 wait_writeh2c_limmit = 100;
0041 u8 boxcontent[4], boxextcontent[2];
0042 u32 h2c_waitcounter = 0;
0043 unsigned long flag;
0044 u8 idx;
0045
0046 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
0047
0048 while (true) {
0049 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
0050 if (rtlhal->h2c_setinprogress) {
0051 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0052 "H2C set in progress! Wait to set..element_id(%d).\n",
0053 element_id);
0054
0055 while (rtlhal->h2c_setinprogress) {
0056 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
0057 flag);
0058 h2c_waitcounter++;
0059 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0060 "Wait 100 us (%d times)...\n",
0061 h2c_waitcounter);
0062 udelay(100);
0063
0064 if (h2c_waitcounter > 1000)
0065 return;
0066 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
0067 flag);
0068 }
0069 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0070 } else {
0071 rtlhal->h2c_setinprogress = true;
0072 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0073 break;
0074 }
0075 }
0076
0077 while (!bwrite_sucess) {
0078 wait_writeh2c_limmit--;
0079 if (wait_writeh2c_limmit == 0) {
0080 pr_err("Write H2C fail because no trigger for FW INT!\n");
0081 break;
0082 }
0083
0084 boxnum = rtlhal->last_hmeboxnum;
0085 switch (boxnum) {
0086 case 0:
0087 box_reg = REG_HMEBOX_0;
0088 box_extreg = REG_HMEBOX_EXT_0;
0089 break;
0090 case 1:
0091 box_reg = REG_HMEBOX_1;
0092 box_extreg = REG_HMEBOX_EXT_1;
0093 break;
0094 case 2:
0095 box_reg = REG_HMEBOX_2;
0096 box_extreg = REG_HMEBOX_EXT_2;
0097 break;
0098 case 3:
0099 box_reg = REG_HMEBOX_3;
0100 box_extreg = REG_HMEBOX_EXT_3;
0101 break;
0102 default:
0103 pr_err("switch case %#x not processed\n",
0104 boxnum);
0105 break;
0106 }
0107
0108 isfw_read = _rtl8723e_check_fw_read_last_h2c(hw, boxnum);
0109 while (!isfw_read) {
0110
0111 wait_h2c_limmit--;
0112 if (wait_h2c_limmit == 0) {
0113 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0114 "Waiting too long for FW read clear HMEBox(%d)!\n",
0115 boxnum);
0116 break;
0117 }
0118
0119 udelay(10);
0120
0121 isfw_read = _rtl8723e_check_fw_read_last_h2c(hw,
0122 boxnum);
0123 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
0124 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0125 "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
0126 boxnum, u1b_tmp);
0127 }
0128
0129 if (!isfw_read) {
0130 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0131 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
0132 boxnum);
0133 break;
0134 }
0135
0136 memset(boxcontent, 0, sizeof(boxcontent));
0137 memset(boxextcontent, 0, sizeof(boxextcontent));
0138 boxcontent[0] = element_id;
0139 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0140 "Write element_id box_reg(%4x) = %2x\n",
0141 box_reg, element_id);
0142
0143 switch (cmd_len) {
0144 case 1:
0145 boxcontent[0] &= ~(BIT(7));
0146 memcpy((u8 *)(boxcontent) + 1,
0147 cmdbuffer + buf_index, 1);
0148
0149 for (idx = 0; idx < 4; idx++) {
0150 rtl_write_byte(rtlpriv, box_reg + idx,
0151 boxcontent[idx]);
0152 }
0153 break;
0154 case 2:
0155 boxcontent[0] &= ~(BIT(7));
0156 memcpy((u8 *)(boxcontent) + 1,
0157 cmdbuffer + buf_index, 2);
0158
0159 for (idx = 0; idx < 4; idx++) {
0160 rtl_write_byte(rtlpriv, box_reg + idx,
0161 boxcontent[idx]);
0162 }
0163 break;
0164 case 3:
0165 boxcontent[0] &= ~(BIT(7));
0166 memcpy((u8 *)(boxcontent) + 1,
0167 cmdbuffer + buf_index, 3);
0168
0169 for (idx = 0; idx < 4; idx++) {
0170 rtl_write_byte(rtlpriv, box_reg + idx,
0171 boxcontent[idx]);
0172 }
0173 break;
0174 case 4:
0175 boxcontent[0] |= (BIT(7));
0176 memcpy((u8 *)(boxextcontent),
0177 cmdbuffer + buf_index, 2);
0178 memcpy((u8 *)(boxcontent) + 1,
0179 cmdbuffer + buf_index + 2, 2);
0180
0181 for (idx = 0; idx < 2; idx++) {
0182 rtl_write_byte(rtlpriv, box_extreg + idx,
0183 boxextcontent[idx]);
0184 }
0185
0186 for (idx = 0; idx < 4; idx++) {
0187 rtl_write_byte(rtlpriv, box_reg + idx,
0188 boxcontent[idx]);
0189 }
0190 break;
0191 case 5:
0192 boxcontent[0] |= (BIT(7));
0193 memcpy((u8 *)(boxextcontent),
0194 cmdbuffer + buf_index, 2);
0195 memcpy((u8 *)(boxcontent) + 1,
0196 cmdbuffer + buf_index + 2, 3);
0197
0198 for (idx = 0; idx < 2; idx++) {
0199 rtl_write_byte(rtlpriv, box_extreg + idx,
0200 boxextcontent[idx]);
0201 }
0202
0203 for (idx = 0; idx < 4; idx++) {
0204 rtl_write_byte(rtlpriv, box_reg + idx,
0205 boxcontent[idx]);
0206 }
0207 break;
0208 default:
0209 pr_err("switch case %#x not processed\n",
0210 cmd_len);
0211 break;
0212 }
0213
0214 bwrite_sucess = true;
0215
0216 rtlhal->last_hmeboxnum = boxnum + 1;
0217 if (rtlhal->last_hmeboxnum == 4)
0218 rtlhal->last_hmeboxnum = 0;
0219
0220 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0221 "pHalData->last_hmeboxnum = %d\n",
0222 rtlhal->last_hmeboxnum);
0223 }
0224
0225 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
0226 rtlhal->h2c_setinprogress = false;
0227 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0228
0229 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
0230 }
0231
0232 void rtl8723e_fill_h2c_cmd(struct ieee80211_hw *hw,
0233 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
0234 {
0235 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0236 u32 tmp_cmdbuf[2];
0237
0238 if (!rtlhal->fw_ready) {
0239 WARN_ONCE(true,
0240 "rtl8723ae: error H2C cmd because of Fw download fail!!!\n");
0241 return;
0242 }
0243 memset(tmp_cmdbuf, 0, 8);
0244 memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
0245 _rtl8723e_fill_h2c_command(hw, element_id, cmd_len,
0246 (u8 *)&tmp_cmdbuf);
0247 }
0248
0249 void rtl8723e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
0250 {
0251 struct rtl_priv *rtlpriv = rtl_priv(hw);
0252 u8 u1_h2c_set_pwrmode[3] = { 0 };
0253 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
0254
0255 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
0256
0257 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
0258 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
0259 (rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1);
0260 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
0261 ppsc->reg_max_lps_awakeintvl);
0262
0263 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
0264 "rtl8723e_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
0265 u1_h2c_set_pwrmode, 3);
0266 rtl8723e_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
0267 }
0268
0269 #define BEACON_PG 0
0270 #define PSPOLL_PG 2
0271 #define NULL_PG 3
0272 #define PROBERSP_PG 4
0273
0274 #define TOTAL_RESERVED_PKT_LEN 768
0275
0276 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
0277
0278 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0279 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0280 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
0281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0282 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0283 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0284 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0285 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0286 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0287 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0288 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0291 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0292 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0294
0295
0296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0308 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
0309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0310 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0312
0313
0314 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
0315 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0326 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0328 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0330
0331
0332 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0333 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0334 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0338 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0344 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0346 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0348
0349
0350 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0351 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0352 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0353 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
0354 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0355 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0356 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0357 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0358 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0359 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0360 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0364 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0366
0367
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0384 };
0385
0386 void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
0387 {
0388 struct rtl_priv *rtlpriv = rtl_priv(hw);
0389 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0390 struct sk_buff *skb = NULL;
0391 u32 totalpacketlen;
0392 bool rtstatus;
0393 u8 u1rsvdpageloc[3] = { 0 };
0394 bool b_dlok = false;
0395 u8 *beacon;
0396 u8 *p_pspoll;
0397 u8 *nullfunc;
0398 u8 *p_probersp;
0399
0400
0401
0402
0403
0404 beacon = &reserved_page_packet[BEACON_PG * 128];
0405 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
0406 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
0407
0408
0409
0410
0411
0412 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
0413 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
0414 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
0415 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
0416
0417 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
0418
0419
0420
0421
0422
0423 nullfunc = &reserved_page_packet[NULL_PG * 128];
0424 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
0425 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
0426 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
0427
0428 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
0429
0430
0431
0432
0433
0434 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
0435 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
0436 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
0437 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
0438
0439 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
0440
0441 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
0442
0443 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
0444 "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
0445 &reserved_page_packet[0], totalpacketlen);
0446 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
0447 "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
0448 u1rsvdpageloc, 3);
0449
0450 skb = dev_alloc_skb(totalpacketlen);
0451 if (!skb)
0452 return;
0453 skb_put_data(skb, &reserved_page_packet, totalpacketlen);
0454
0455 rtstatus = rtl_cmd_send_packet(hw, skb);
0456
0457 if (rtstatus)
0458 b_dlok = true;
0459
0460 if (b_dlok) {
0461 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0462 "Set RSVD page location to Fw.\n");
0463 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
0464 "H2C_RSVDPAGE:\n",
0465 u1rsvdpageloc, 3);
0466 rtl8723e_fill_h2c_cmd(hw, H2C_RSVDPAGE,
0467 sizeof(u1rsvdpageloc), u1rsvdpageloc);
0468 } else
0469 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
0470 "Set RSVD page location to Fw FAIL!!!!!!.\n");
0471 }
0472
0473 void rtl8723e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
0474 {
0475 u8 u1_joinbssrpt_parm[1] = { 0 };
0476
0477 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
0478
0479 rtl8723e_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
0480 }
0481
0482 static void rtl8723e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
0483 u8 ctwindow)
0484 {
0485 u8 u1_ctwindow_period[1] = { ctwindow};
0486
0487 rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
0488
0489 }
0490
0491 void rtl8723e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
0492 {
0493 struct rtl_priv *rtlpriv = rtl_priv(hw);
0494 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
0495 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0496 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
0497 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
0498 u8 i;
0499 u16 ctwindow;
0500 u32 start_time, tsf_low;
0501
0502 switch (p2p_ps_state) {
0503 case P2P_PS_DISABLE:
0504 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
0505 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
0506 break;
0507 case P2P_PS_ENABLE:
0508 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
0509
0510 if (p2pinfo->ctwindow > 0) {
0511 p2p_ps_offload->ctwindow_en = 1;
0512 ctwindow = p2pinfo->ctwindow;
0513 rtl8723e_set_p2p_ctw_period_cmd(hw, ctwindow);
0514 }
0515
0516
0517 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
0518
0519 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
0520 if (i == 0)
0521 p2p_ps_offload->noa0_en = 1;
0522 else
0523 p2p_ps_offload->noa1_en = 1;
0524
0525
0526 rtl_write_dword(rtlpriv, 0x5E0,
0527 p2pinfo->noa_duration[i]);
0528 rtl_write_dword(rtlpriv, 0x5E4,
0529 p2pinfo->noa_interval[i]);
0530
0531
0532 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
0533
0534 start_time = p2pinfo->noa_start_time[i];
0535 if (p2pinfo->noa_count_type[i] != 1) {
0536 while (start_time <=
0537 (tsf_low+(50*1024))) {
0538 start_time +=
0539 p2pinfo->noa_interval[i];
0540 if (p2pinfo->noa_count_type[i] != 255)
0541 p2pinfo->noa_count_type[i]--;
0542 }
0543 }
0544 rtl_write_dword(rtlpriv, 0x5E8, start_time);
0545 rtl_write_dword(rtlpriv, 0x5EC,
0546 p2pinfo->noa_count_type[i]);
0547
0548 }
0549
0550 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
0551
0552 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
0553
0554 p2p_ps_offload->offload_en = 1;
0555
0556 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
0557 p2p_ps_offload->role = 1;
0558 p2p_ps_offload->allstasleep = 0;
0559 } else {
0560 p2p_ps_offload->role = 0;
0561 }
0562
0563 p2p_ps_offload->discovery = 0;
0564 }
0565 break;
0566 case P2P_PS_SCAN:
0567 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
0568 p2p_ps_offload->discovery = 1;
0569 break;
0570 case P2P_PS_SCAN_DONE:
0571 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
0572 p2p_ps_offload->discovery = 0;
0573 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
0574 break;
0575 default:
0576 break;
0577 }
0578
0579 rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
0580
0581 }