0001
0002
0003
0004 #include "../wifi.h"
0005 #include "../pci.h"
0006 #include "../base.h"
0007 #include "../core.h"
0008 #include "../efuse.h"
0009 #include "reg.h"
0010 #include "def.h"
0011 #include "fw.h"
0012 #include "dm.h"
0013
0014 static void _rtl92ee_enable_fw_download(struct ieee80211_hw *hw, bool enable)
0015 {
0016 struct rtl_priv *rtlpriv = rtl_priv(hw);
0017 u8 tmp;
0018
0019 if (enable) {
0020 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x05);
0021
0022 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
0023 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
0024 } else {
0025 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
0026 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
0027 }
0028 }
0029
0030 static void _rtl92ee_write_fw(struct ieee80211_hw *hw,
0031 enum version_8192e version,
0032 u8 *buffer, u32 size)
0033 {
0034 struct rtl_priv *rtlpriv = rtl_priv(hw);
0035 u8 *bufferptr = (u8 *)buffer;
0036 u32 pagenums, remainsize;
0037 u32 page, offset;
0038
0039 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
0040
0041 rtl_fill_dummy(bufferptr, &size);
0042
0043 pagenums = size / FW_8192C_PAGE_SIZE;
0044 remainsize = size % FW_8192C_PAGE_SIZE;
0045
0046 if (pagenums > 8)
0047 pr_err("Page numbers should not greater then 8\n");
0048
0049 for (page = 0; page < pagenums; page++) {
0050 offset = page * FW_8192C_PAGE_SIZE;
0051 rtl_fw_page_write(hw, page, (bufferptr + offset),
0052 FW_8192C_PAGE_SIZE);
0053 udelay(2);
0054 }
0055
0056 if (remainsize) {
0057 offset = pagenums * FW_8192C_PAGE_SIZE;
0058 page = pagenums;
0059 rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
0060 }
0061 }
0062
0063 static int _rtl92ee_fw_free_to_go(struct ieee80211_hw *hw)
0064 {
0065 struct rtl_priv *rtlpriv = rtl_priv(hw);
0066 int err = -EIO;
0067 u32 counter = 0;
0068 u32 value32;
0069
0070 do {
0071 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
0072 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
0073 (!(value32 & FWDL_CHKSUM_RPT)));
0074
0075 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
0076 pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n",
0077 value32);
0078 goto exit;
0079 }
0080 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
0081 value32 |= MCUFWDL_RDY;
0082 value32 &= ~WINTINI_RDY;
0083 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
0084
0085 rtl92ee_firmware_selfreset(hw);
0086 counter = 0;
0087
0088 do {
0089 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
0090 if (value32 & WINTINI_RDY)
0091 return 0;
0092
0093 udelay(FW_8192C_POLLING_DELAY*10);
0094
0095 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
0096
0097 pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x. count = %d\n",
0098 value32, counter);
0099
0100 exit:
0101 return err;
0102 }
0103
0104 int rtl92ee_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw)
0105 {
0106 struct rtl_priv *rtlpriv = rtl_priv(hw);
0107 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0108 struct rtlwifi_firmware_header *pfwheader;
0109 u8 *pfwdata;
0110 u32 fwsize;
0111 enum version_8192e version = rtlhal->version;
0112
0113 if (!rtlhal->pfirmware)
0114 return 1;
0115
0116 pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware;
0117 rtlhal->fw_version = le16_to_cpu(pfwheader->version);
0118 rtlhal->fw_subversion = pfwheader->subversion;
0119 pfwdata = (u8 *)rtlhal->pfirmware;
0120 fwsize = rtlhal->fwsize;
0121 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0122 "normal Firmware SIZE %d\n", fwsize);
0123
0124 if (IS_FW_HEADER_EXIST(pfwheader)) {
0125 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0126 "Firmware Version(%d), Signature(%#x),Size(%d)\n",
0127 pfwheader->version, pfwheader->signature,
0128 (int)sizeof(struct rtlwifi_firmware_header));
0129
0130 pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header);
0131 fwsize = fwsize - sizeof(struct rtlwifi_firmware_header);
0132 } else {
0133 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0134 "Firmware no Header, Signature(%#x)\n",
0135 pfwheader->signature);
0136 }
0137
0138 if (rtlhal->mac_func_enable) {
0139 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
0140 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
0141 rtl92ee_firmware_selfreset(hw);
0142 }
0143 }
0144 _rtl92ee_enable_fw_download(hw, true);
0145 _rtl92ee_write_fw(hw, version, pfwdata, fwsize);
0146 _rtl92ee_enable_fw_download(hw, false);
0147
0148 return _rtl92ee_fw_free_to_go(hw);
0149 }
0150
0151 static bool _rtl92ee_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
0152 {
0153 struct rtl_priv *rtlpriv = rtl_priv(hw);
0154 u8 val_hmetfr;
0155 bool result = false;
0156
0157 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
0158 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
0159 result = true;
0160 return result;
0161 }
0162
0163 static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
0164 u32 cmd_len, u8 *cmdbuffer)
0165 {
0166 struct rtl_priv *rtlpriv = rtl_priv(hw);
0167 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0168 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
0169 u8 boxnum;
0170 u16 box_reg = 0, box_extreg = 0;
0171 u8 u1b_tmp;
0172 bool isfw_read = false;
0173 u8 buf_index = 0;
0174 bool bwrite_sucess = false;
0175 u8 wait_h2c_limmit = 100;
0176 u8 boxcontent[4], boxextcontent[4];
0177 u32 h2c_waitcounter = 0;
0178 unsigned long flag;
0179 u8 idx;
0180
0181 if (ppsc->dot11_psmode != EACTIVE ||
0182 ppsc->inactive_pwrstate == ERFOFF) {
0183 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0184 "FillH2CCommand8192E(): Return because RF is off!!!\n");
0185 return;
0186 }
0187
0188 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
0189
0190
0191
0192
0193 while (true) {
0194 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
0195 if (rtlhal->h2c_setinprogress) {
0196 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0197 "H2C set in progress! Wait to set..element_id(%d).\n",
0198 element_id);
0199
0200 while (rtlhal->h2c_setinprogress) {
0201 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
0202 flag);
0203 h2c_waitcounter++;
0204 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0205 "Wait 100 us (%d times)...\n",
0206 h2c_waitcounter);
0207 udelay(100);
0208
0209 if (h2c_waitcounter > 1000)
0210 return;
0211 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
0212 flag);
0213 }
0214 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0215 } else {
0216 rtlhal->h2c_setinprogress = true;
0217 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0218 break;
0219 }
0220 }
0221
0222 while (!bwrite_sucess) {
0223
0224 boxnum = rtlhal->last_hmeboxnum;
0225 switch (boxnum) {
0226 case 0:
0227 box_reg = REG_HMEBOX_0;
0228 box_extreg = REG_HMEBOX_EXT_0;
0229 break;
0230 case 1:
0231 box_reg = REG_HMEBOX_1;
0232 box_extreg = REG_HMEBOX_EXT_1;
0233 break;
0234 case 2:
0235 box_reg = REG_HMEBOX_2;
0236 box_extreg = REG_HMEBOX_EXT_2;
0237 break;
0238 case 3:
0239 box_reg = REG_HMEBOX_3;
0240 box_extreg = REG_HMEBOX_EXT_3;
0241 break;
0242 default:
0243 rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
0244 "switch case %#x not processed\n", boxnum);
0245 break;
0246 }
0247
0248
0249 isfw_read = false;
0250 u1b_tmp = rtl_read_byte(rtlpriv, REG_CR);
0251
0252 if (u1b_tmp != 0xea) {
0253 isfw_read = true;
0254 } else {
0255 if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS) == 0xea ||
0256 rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY) == 0xea)
0257 rtl_write_byte(rtlpriv, REG_SYS_CFG1 + 3, 0xff);
0258 }
0259
0260 if (isfw_read) {
0261 wait_h2c_limmit = 100;
0262 isfw_read = _rtl92ee_check_fw_read_last_h2c(hw, boxnum);
0263 while (!isfw_read) {
0264 wait_h2c_limmit--;
0265 if (wait_h2c_limmit == 0) {
0266 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0267 "Waiting too long for FW read clear HMEBox(%d)!!!\n",
0268 boxnum);
0269 break;
0270 }
0271 udelay(10);
0272 isfw_read =
0273 _rtl92ee_check_fw_read_last_h2c(hw, boxnum);
0274 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
0275 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0276 "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
0277 boxnum, u1b_tmp);
0278 }
0279 }
0280
0281
0282
0283
0284 if (!isfw_read) {
0285 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0286 "Write H2C reg BOX[%d] fail,Fw don't read.\n",
0287 boxnum);
0288 break;
0289 }
0290
0291 memset(boxcontent, 0, sizeof(boxcontent));
0292 memset(boxextcontent, 0, sizeof(boxextcontent));
0293 boxcontent[0] = element_id;
0294 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0295 "Write element_id box_reg(%4x) = %2x\n",
0296 box_reg, element_id);
0297
0298 switch (cmd_len) {
0299 case 1:
0300 case 2:
0301 case 3:
0302
0303 memcpy((u8 *)(boxcontent) + 1,
0304 cmdbuffer + buf_index, cmd_len);
0305
0306 for (idx = 0; idx < 4; idx++) {
0307 rtl_write_byte(rtlpriv, box_reg + idx,
0308 boxcontent[idx]);
0309 }
0310 break;
0311 case 4:
0312 case 5:
0313 case 6:
0314 case 7:
0315
0316 memcpy((u8 *)(boxextcontent),
0317 cmdbuffer + buf_index+3, cmd_len-3);
0318 memcpy((u8 *)(boxcontent) + 1,
0319 cmdbuffer + buf_index, 3);
0320
0321 for (idx = 0; idx < 4; idx++) {
0322 rtl_write_byte(rtlpriv, box_extreg + idx,
0323 boxextcontent[idx]);
0324 }
0325
0326 for (idx = 0; idx < 4; idx++) {
0327 rtl_write_byte(rtlpriv, box_reg + idx,
0328 boxcontent[idx]);
0329 }
0330 break;
0331 default:
0332 rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
0333 "switch case %#x not processed\n", cmd_len);
0334 break;
0335 }
0336
0337 bwrite_sucess = true;
0338
0339 rtlhal->last_hmeboxnum = boxnum + 1;
0340 if (rtlhal->last_hmeboxnum == 4)
0341 rtlhal->last_hmeboxnum = 0;
0342
0343 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0344 "pHalData->last_hmeboxnum = %d\n",
0345 rtlhal->last_hmeboxnum);
0346 }
0347
0348 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
0349 rtlhal->h2c_setinprogress = false;
0350 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0351
0352 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
0353 }
0354
0355 void rtl92ee_fill_h2c_cmd(struct ieee80211_hw *hw,
0356 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
0357 {
0358 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0359 u32 tmp_cmdbuf[2];
0360
0361 if (!rtlhal->fw_ready) {
0362 WARN_ONCE(true,
0363 "rtl8192ee: error H2C cmd because of Fw download fail!!!\n");
0364 return;
0365 }
0366
0367 memset(tmp_cmdbuf, 0, 8);
0368 memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
0369 _rtl92ee_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
0370 }
0371
0372 void rtl92ee_firmware_selfreset(struct ieee80211_hw *hw)
0373 {
0374 u8 u1b_tmp;
0375 struct rtl_priv *rtlpriv = rtl_priv(hw);
0376
0377 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
0378 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
0379
0380 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0381 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
0382
0383 udelay(50);
0384
0385 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
0386 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0)));
0387
0388 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0389 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2)));
0390
0391 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
0392 " _8051Reset92E(): 8051 reset success .\n");
0393 }
0394
0395 void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
0396 {
0397 struct rtl_priv *rtlpriv = rtl_priv(hw);
0398 u8 u1_h2c_set_pwrmode[H2C_92E_PWEMODE_LENGTH] = { 0 };
0399 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
0400 u8 rlbm, power_state = 0, byte5 = 0;
0401 u8 awake_intvl;
0402 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
0403 bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
0404 btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
0405 bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
0406 btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
0407
0408 if (bt_ctrl_lps)
0409 mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
0410
0411 rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
0412 mode, bt_ctrl_lps);
0413
0414 switch (mode) {
0415 case FW_PS_MIN_MODE:
0416 rlbm = 0;
0417 awake_intvl = 2;
0418 break;
0419 case FW_PS_MAX_MODE:
0420 rlbm = 1;
0421 awake_intvl = 2;
0422 break;
0423 case FW_PS_DTIM_MODE:
0424 rlbm = 2;
0425 awake_intvl = ppsc->reg_max_lps_awakeintvl;
0426
0427
0428
0429 break;
0430 default:
0431 rlbm = 2;
0432 awake_intvl = 4;
0433 break;
0434 }
0435
0436 if (rtlpriv->mac80211.p2p) {
0437 awake_intvl = 2;
0438 rlbm = 1;
0439 }
0440
0441 if (mode == FW_PS_ACTIVE_MODE) {
0442 byte5 = 0x40;
0443 power_state = FW_PWR_STATE_ACTIVE;
0444 } else {
0445 if (bt_ctrl_lps) {
0446 byte5 = btc_ops->btc_get_lps_val(rtlpriv);
0447 power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
0448
0449 if ((rlbm == 2) && (byte5 & BIT(4))) {
0450
0451
0452
0453 awake_intvl = 2;
0454 rlbm = 2;
0455 }
0456 } else {
0457 byte5 = 0x40;
0458 power_state = FW_PWR_STATE_RF_OFF;
0459 }
0460 }
0461
0462 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
0463 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
0464 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
0465 bt_ctrl_lps ? 0 :
0466 ((rtlpriv->mac80211.p2p) ?
0467 ppsc->smart_ps : 1));
0468 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
0469 awake_intvl);
0470 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
0471 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
0472 SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
0473
0474 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
0475 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
0476 u1_h2c_set_pwrmode, H2C_92E_PWEMODE_LENGTH);
0477 if (rtlpriv->cfg->ops->get_btc_status())
0478 btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
0479 H2C_92E_PWEMODE_LENGTH);
0480 rtl92ee_fill_h2c_cmd(hw, H2C_92E_SETPWRMODE, H2C_92E_PWEMODE_LENGTH,
0481 u1_h2c_set_pwrmode);
0482 }
0483
0484 void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
0485 {
0486 u8 parm[3] = { 0 , 0 , 0 };
0487
0488
0489
0490
0491
0492
0493
0494 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
0495 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
0496
0497 rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm);
0498 }
0499
0500 #define BEACON_PG 0
0501 #define PSPOLL_PG 2
0502 #define NULL_PG 3
0503 #define PROBERSP_PG 4
0504 #define QOS_NULL_PG 6
0505 #define BT_QOS_NULL_PG 7
0506
0507 #define TOTAL_RESERVED_PKT_LEN 1024
0508
0509 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
0510
0511 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0512 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
0513 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
0514 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0515 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
0516 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
0517 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
0518 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
0519 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
0520 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0521 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0522 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0523 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
0524 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
0525 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
0526 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
0527
0528
0529 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
0530 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0531 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0534 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0540 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0541 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
0542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0545
0546
0547 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
0548 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
0549 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0551 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0553 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0558 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0559 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0562 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0563
0564
0565 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
0566 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
0567 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
0568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0576 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0577 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0580 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0581
0582
0583 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0584 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0585 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0586 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
0587 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0588 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0589 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0590 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0591 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0592 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0593 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0596 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0597 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0599
0600
0601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0608 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0609 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0611 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0612 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0613
0614
0615 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0616 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0617 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0626 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0627 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
0628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0630 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0631
0632
0633 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0634 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0635 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0653 };
0654
0655 void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
0656 {
0657 struct rtl_priv *rtlpriv = rtl_priv(hw);
0658 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0659 struct sk_buff *skb = NULL;
0660 bool rtstatus;
0661 u32 totalpacketlen;
0662 u8 u1rsvdpageloc[5] = { 0 };
0663 bool b_dlok = false;
0664
0665 u8 *beacon;
0666 u8 *p_pspoll;
0667 u8 *nullfunc;
0668 u8 *p_probersp;
0669 u8 *qosnull;
0670 u8 *btqosnull;
0671
0672
0673
0674
0675 beacon = &reserved_page_packet[BEACON_PG * 128];
0676 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
0677 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
0678
0679
0680
0681
0682
0683 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
0684 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
0685 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
0686 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
0687
0688 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
0689
0690
0691
0692
0693
0694 nullfunc = &reserved_page_packet[NULL_PG * 128];
0695 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
0696 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
0697 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
0698
0699 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
0700
0701
0702
0703
0704
0705 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
0706 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
0707 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
0708 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
0709
0710 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
0711
0712
0713
0714
0715
0716 qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
0717 SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
0718 SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
0719 SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
0720
0721 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
0722
0723
0724
0725
0726
0727 btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
0728 SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
0729 SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
0730 SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
0731
0732 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
0733
0734 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
0735
0736 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
0737 "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
0738 &reserved_page_packet[0], totalpacketlen);
0739 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
0740 "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
0741 u1rsvdpageloc, 3);
0742
0743 skb = dev_alloc_skb(totalpacketlen);
0744 if (!skb)
0745 return;
0746 skb_put_data(skb, &reserved_page_packet, totalpacketlen);
0747
0748 rtstatus = rtl_cmd_send_packet(hw, skb);
0749 if (rtstatus)
0750 b_dlok = true;
0751
0752 if (b_dlok) {
0753 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0754 "Set RSVD page location to Fw.\n");
0755 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
0756 "H2C_RSVDPAGE:\n", u1rsvdpageloc, 3);
0757 rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSVDPAGE,
0758 sizeof(u1rsvdpageloc), u1rsvdpageloc);
0759 } else {
0760 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
0761 "Set RSVD page location to Fw FAIL!!!!!!.\n");
0762 }
0763 }
0764
0765
0766 static void rtl92ee_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
0767 {
0768 u8 u1_ctwindow_period[1] = {ctwindow};
0769
0770 rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
0771 }
0772
0773 void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
0774 {
0775 struct rtl_priv *rtlpriv = rtl_priv(hw);
0776 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
0777 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0778 struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
0779 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
0780 u8 i;
0781 u16 ctwindow;
0782 u32 start_time, tsf_low;
0783
0784 switch (p2p_ps_state) {
0785 case P2P_PS_DISABLE:
0786 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
0787 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
0788 break;
0789 case P2P_PS_ENABLE:
0790 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
0791
0792 if (p2pinfo->ctwindow > 0) {
0793 p2p_ps_offload->ctwindow_en = 1;
0794 ctwindow = p2pinfo->ctwindow;
0795 rtl92ee_set_p2p_ctw_period_cmd(hw, ctwindow);
0796 }
0797
0798 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
0799
0800 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
0801 if (i == 0)
0802 p2p_ps_offload->noa0_en = 1;
0803 else
0804 p2p_ps_offload->noa1_en = 1;
0805
0806 rtl_write_dword(rtlpriv, 0x5E0,
0807 p2pinfo->noa_duration[i]);
0808 rtl_write_dword(rtlpriv, 0x5E4,
0809 p2pinfo->noa_interval[i]);
0810
0811
0812 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
0813
0814 start_time = p2pinfo->noa_start_time[i];
0815 if (p2pinfo->noa_count_type[i] != 1) {
0816 while (start_time <= (tsf_low + (50 * 1024))) {
0817 start_time += p2pinfo->noa_interval[i];
0818 if (p2pinfo->noa_count_type[i] != 255)
0819 p2pinfo->noa_count_type[i]--;
0820 }
0821 }
0822 rtl_write_dword(rtlpriv, 0x5E8, start_time);
0823 rtl_write_dword(rtlpriv, 0x5EC,
0824 p2pinfo->noa_count_type[i]);
0825 }
0826 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
0827
0828 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
0829 p2p_ps_offload->offload_en = 1;
0830
0831 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
0832 p2p_ps_offload->role = 1;
0833 p2p_ps_offload->allstasleep = 0;
0834 } else {
0835 p2p_ps_offload->role = 0;
0836 }
0837 p2p_ps_offload->discovery = 0;
0838 }
0839 break;
0840 case P2P_PS_SCAN:
0841 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
0842 p2p_ps_offload->discovery = 1;
0843 break;
0844 case P2P_PS_SCAN_DONE:
0845 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
0846 p2p_ps_offload->discovery = 0;
0847 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
0848 break;
0849 default:
0850 break;
0851 }
0852 rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_OFFLOAD, 1,
0853 (u8 *)p2p_ps_offload);
0854 }
0855
0856 void rtl92ee_c2h_ra_report_handler(struct ieee80211_hw *hw,
0857 u8 *cmd_buf, u8 cmd_len)
0858 {
0859 u8 rate = cmd_buf[0] & 0x3F;
0860 bool collision_state = cmd_buf[3] & BIT(0);
0861
0862 rtl92ee_dm_dynamic_arfb_select(hw, rate, collision_state);
0863 }