0001
0002
0003
0004 #include "../wifi.h"
0005 #include "../pci.h"
0006 #include "../base.h"
0007 #include "../efuse.h"
0008 #include "reg.h"
0009 #include "def.h"
0010 #include "fw.h"
0011 #include "sw.h"
0012
0013 static bool _rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv)
0014 {
0015 return (rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) ?
0016 true : false;
0017 }
0018
0019 static void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable)
0020 {
0021 struct rtl_priv *rtlpriv = rtl_priv(hw);
0022 u8 tmp;
0023
0024 if (enable) {
0025 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0026 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
0027 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
0028 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
0029 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
0030 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
0031 } else {
0032 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
0033 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
0034
0035
0036
0037
0038 }
0039 }
0040
0041 static void _rtl92d_write_fw(struct ieee80211_hw *hw,
0042 enum version_8192d version, u8 *buffer, u32 size)
0043 {
0044 struct rtl_priv *rtlpriv = rtl_priv(hw);
0045 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0046 u8 *bufferptr = buffer;
0047 u32 pagenums, remainsize;
0048 u32 page, offset;
0049
0050 rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
0051 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
0052 rtl_fill_dummy(bufferptr, &size);
0053 pagenums = size / FW_8192D_PAGE_SIZE;
0054 remainsize = size % FW_8192D_PAGE_SIZE;
0055 if (pagenums > 8)
0056 pr_err("Page numbers should not greater then 8\n");
0057 for (page = 0; page < pagenums; page++) {
0058 offset = page * FW_8192D_PAGE_SIZE;
0059 rtl_fw_page_write(hw, page, (bufferptr + offset),
0060 FW_8192D_PAGE_SIZE);
0061 }
0062 if (remainsize) {
0063 offset = pagenums * FW_8192D_PAGE_SIZE;
0064 page = pagenums;
0065 rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
0066 }
0067 }
0068
0069 static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
0070 {
0071 struct rtl_priv *rtlpriv = rtl_priv(hw);
0072 u32 counter = 0;
0073 u32 value32;
0074
0075 do {
0076 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
0077 } while ((counter++ < FW_8192D_POLLING_TIMEOUT_COUNT) &&
0078 (!(value32 & FWDL_CHKSUM_RPT)));
0079 if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) {
0080 pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n",
0081 value32);
0082 return -EIO;
0083 }
0084 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
0085 value32 |= MCUFWDL_RDY;
0086 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
0087 return 0;
0088 }
0089
0090 void rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
0091 {
0092 struct rtl_priv *rtlpriv = rtl_priv(hw);
0093 u8 u1b_tmp;
0094 u8 delay = 100;
0095
0096
0097 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
0098 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0099 while (u1b_tmp & BIT(2)) {
0100 delay--;
0101 if (delay == 0)
0102 break;
0103 udelay(50);
0104 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0105 }
0106 WARN_ONCE((delay <= 0), "rtl8192de: 8051 reset failed!\n");
0107 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0108 "=====> 8051 reset success (%d)\n", delay);
0109 }
0110
0111 static int _rtl92d_fw_init(struct ieee80211_hw *hw)
0112 {
0113 struct rtl_priv *rtlpriv = rtl_priv(hw);
0114 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0115 u32 counter;
0116
0117 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n");
0118
0119 counter = 0;
0120 do {
0121 if (rtlhal->interfaceindex == 0) {
0122 if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
0123 MAC0_READY) {
0124 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0125 "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
0126 rtl_read_byte(rtlpriv,
0127 FW_MAC0_READY));
0128 return 0;
0129 }
0130 udelay(5);
0131 } else {
0132 if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
0133 MAC1_READY) {
0134 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0135 "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
0136 rtl_read_byte(rtlpriv,
0137 FW_MAC1_READY));
0138 return 0;
0139 }
0140 udelay(5);
0141 }
0142 } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
0143
0144 if (rtlhal->interfaceindex == 0) {
0145 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0146 "Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n",
0147 rtl_read_byte(rtlpriv, FW_MAC0_READY));
0148 } else {
0149 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0150 "Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n",
0151 rtl_read_byte(rtlpriv, FW_MAC1_READY));
0152 }
0153 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0154 "Polling FW ready fail!! REG_MCUFWDL:0x%08x\n",
0155 rtl_read_dword(rtlpriv, REG_MCUFWDL));
0156 return -1;
0157 }
0158
0159 int rtl92d_download_fw(struct ieee80211_hw *hw)
0160 {
0161 struct rtl_priv *rtlpriv = rtl_priv(hw);
0162 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0163 u8 *pfwheader;
0164 u8 *pfwdata;
0165 u32 fwsize;
0166 int err;
0167 enum version_8192d version = rtlhal->version;
0168 u8 value;
0169 u32 count;
0170 bool fw_downloaded = false, fwdl_in_process = false;
0171 unsigned long flags;
0172
0173 if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
0174 return 1;
0175 fwsize = rtlhal->fwsize;
0176 pfwheader = rtlhal->pfirmware;
0177 pfwdata = rtlhal->pfirmware;
0178 rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
0179 rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
0180 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
0181 "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n",
0182 rtlhal->fw_version, rtlhal->fw_subversion,
0183 GET_FIRMWARE_HDR_SIGNATURE(pfwheader));
0184 if (IS_FW_HEADER_EXIST(pfwheader)) {
0185 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
0186 "Shift 32 bytes for FW header!!\n");
0187 pfwdata = pfwdata + 32;
0188 fwsize = fwsize - 32;
0189 }
0190
0191 spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
0192 fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
0193 if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
0194 fwdl_in_process = true;
0195 else
0196 fwdl_in_process = false;
0197 if (fw_downloaded) {
0198 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
0199 goto exit;
0200 } else if (fwdl_in_process) {
0201 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
0202 for (count = 0; count < 5000; count++) {
0203 udelay(500);
0204 spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
0205 fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
0206 if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
0207 fwdl_in_process = true;
0208 else
0209 fwdl_in_process = false;
0210 spin_unlock_irqrestore(&globalmutex_for_fwdownload,
0211 flags);
0212 if (fw_downloaded)
0213 goto exit;
0214 else if (!fwdl_in_process)
0215 break;
0216 else
0217 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0218 "Wait for another mac download fw\n");
0219 }
0220 spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
0221 value = rtl_read_byte(rtlpriv, 0x1f);
0222 value |= BIT(5);
0223 rtl_write_byte(rtlpriv, 0x1f, value);
0224 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
0225 } else {
0226 value = rtl_read_byte(rtlpriv, 0x1f);
0227 value |= BIT(5);
0228 rtl_write_byte(rtlpriv, 0x1f, value);
0229 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
0230 }
0231
0232
0233
0234
0235
0236 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
0237 rtl92d_firmware_selfreset(hw);
0238 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
0239 }
0240 _rtl92d_enable_fw_download(hw, true);
0241 _rtl92d_write_fw(hw, version, pfwdata, fwsize);
0242 _rtl92d_enable_fw_download(hw, false);
0243 spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
0244 err = _rtl92d_fw_free_to_go(hw);
0245
0246 value = rtl_read_byte(rtlpriv, 0x1f);
0247 value &= (~BIT(5));
0248 rtl_write_byte(rtlpriv, 0x1f, value);
0249 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
0250 if (err)
0251 pr_err("fw is not ready to run!\n");
0252 exit:
0253 err = _rtl92d_fw_init(hw);
0254 return err;
0255 }
0256
0257 static bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
0258 {
0259 struct rtl_priv *rtlpriv = rtl_priv(hw);
0260 u8 val_hmetfr;
0261 bool result = false;
0262
0263 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
0264 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
0265 result = true;
0266 return result;
0267 }
0268
0269 static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
0270 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
0271 {
0272 struct rtl_priv *rtlpriv = rtl_priv(hw);
0273 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0274 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
0275 u8 boxnum;
0276 u16 box_reg = 0, box_extreg = 0;
0277 u8 u1b_tmp;
0278 bool isfw_read = false;
0279 u8 buf_index = 0;
0280 bool bwrite_success = false;
0281 u8 wait_h2c_limmit = 100;
0282 u8 wait_writeh2c_limmit = 100;
0283 u8 boxcontent[4], boxextcontent[2];
0284 u32 h2c_waitcounter = 0;
0285 unsigned long flag;
0286 u8 idx;
0287
0288 if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
0289 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0290 "Return as RF is off!!!\n");
0291 return;
0292 }
0293 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
0294 while (true) {
0295 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
0296 if (rtlhal->h2c_setinprogress) {
0297 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0298 "H2C set in progress! Wait to set..element_id(%d)\n",
0299 element_id);
0300
0301 while (rtlhal->h2c_setinprogress) {
0302 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
0303 flag);
0304 h2c_waitcounter++;
0305 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0306 "Wait 100 us (%d times)...\n",
0307 h2c_waitcounter);
0308 udelay(100);
0309
0310 if (h2c_waitcounter > 1000)
0311 return;
0312
0313 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
0314 flag);
0315 }
0316 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0317 } else {
0318 rtlhal->h2c_setinprogress = true;
0319 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0320 break;
0321 }
0322 }
0323 while (!bwrite_success) {
0324 wait_writeh2c_limmit--;
0325 if (wait_writeh2c_limmit == 0) {
0326 pr_err("Write H2C fail because no trigger for FW INT!\n");
0327 break;
0328 }
0329 boxnum = rtlhal->last_hmeboxnum;
0330 switch (boxnum) {
0331 case 0:
0332 box_reg = REG_HMEBOX_0;
0333 box_extreg = REG_HMEBOX_EXT_0;
0334 break;
0335 case 1:
0336 box_reg = REG_HMEBOX_1;
0337 box_extreg = REG_HMEBOX_EXT_1;
0338 break;
0339 case 2:
0340 box_reg = REG_HMEBOX_2;
0341 box_extreg = REG_HMEBOX_EXT_2;
0342 break;
0343 case 3:
0344 box_reg = REG_HMEBOX_3;
0345 box_extreg = REG_HMEBOX_EXT_3;
0346 break;
0347 default:
0348 pr_err("switch case %#x not processed\n",
0349 boxnum);
0350 break;
0351 }
0352 isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
0353 while (!isfw_read) {
0354 wait_h2c_limmit--;
0355 if (wait_h2c_limmit == 0) {
0356 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0357 "Waiting too long for FW read clear HMEBox(%d)!\n",
0358 boxnum);
0359 break;
0360 }
0361 udelay(10);
0362 isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
0363 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
0364 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0365 "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
0366 boxnum, u1b_tmp);
0367 }
0368 if (!isfw_read) {
0369 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0370 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
0371 boxnum);
0372 break;
0373 }
0374 memset(boxcontent, 0, sizeof(boxcontent));
0375 memset(boxextcontent, 0, sizeof(boxextcontent));
0376 boxcontent[0] = element_id;
0377 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0378 "Write element_id box_reg(%4x) = %2x\n",
0379 box_reg, element_id);
0380 switch (cmd_len) {
0381 case 1:
0382 boxcontent[0] &= ~(BIT(7));
0383 memcpy(boxcontent + 1, cmdbuffer + buf_index, 1);
0384 for (idx = 0; idx < 4; idx++)
0385 rtl_write_byte(rtlpriv, box_reg + idx,
0386 boxcontent[idx]);
0387 break;
0388 case 2:
0389 boxcontent[0] &= ~(BIT(7));
0390 memcpy(boxcontent + 1, cmdbuffer + buf_index, 2);
0391 for (idx = 0; idx < 4; idx++)
0392 rtl_write_byte(rtlpriv, box_reg + idx,
0393 boxcontent[idx]);
0394 break;
0395 case 3:
0396 boxcontent[0] &= ~(BIT(7));
0397 memcpy(boxcontent + 1, cmdbuffer + buf_index, 3);
0398 for (idx = 0; idx < 4; idx++)
0399 rtl_write_byte(rtlpriv, box_reg + idx,
0400 boxcontent[idx]);
0401 break;
0402 case 4:
0403 boxcontent[0] |= (BIT(7));
0404 memcpy(boxextcontent, cmdbuffer + buf_index, 2);
0405 memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 2);
0406 for (idx = 0; idx < 2; idx++)
0407 rtl_write_byte(rtlpriv, box_extreg + idx,
0408 boxextcontent[idx]);
0409 for (idx = 0; idx < 4; idx++)
0410 rtl_write_byte(rtlpriv, box_reg + idx,
0411 boxcontent[idx]);
0412 break;
0413 case 5:
0414 boxcontent[0] |= (BIT(7));
0415 memcpy(boxextcontent, cmdbuffer + buf_index, 2);
0416 memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 3);
0417 for (idx = 0; idx < 2; idx++)
0418 rtl_write_byte(rtlpriv, box_extreg + idx,
0419 boxextcontent[idx]);
0420 for (idx = 0; idx < 4; idx++)
0421 rtl_write_byte(rtlpriv, box_reg + idx,
0422 boxcontent[idx]);
0423 break;
0424 default:
0425 pr_err("switch case %#x not processed\n",
0426 cmd_len);
0427 break;
0428 }
0429 bwrite_success = true;
0430 rtlhal->last_hmeboxnum = boxnum + 1;
0431 if (rtlhal->last_hmeboxnum == 4)
0432 rtlhal->last_hmeboxnum = 0;
0433 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0434 "pHalData->last_hmeboxnum = %d\n",
0435 rtlhal->last_hmeboxnum);
0436 }
0437 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
0438 rtlhal->h2c_setinprogress = false;
0439 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0440 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
0441 }
0442
0443 void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
0444 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
0445 {
0446 u32 tmp_cmdbuf[2];
0447
0448 memset(tmp_cmdbuf, 0, 8);
0449 memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
0450 _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
0451 return;
0452 }
0453
0454 static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,
0455 struct sk_buff *skb)
0456 {
0457 struct rtl_priv *rtlpriv = rtl_priv(hw);
0458 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
0459 struct rtl8192_tx_ring *ring;
0460 struct rtl_tx_desc *pdesc;
0461 u8 idx = 0;
0462 unsigned long flags;
0463 struct sk_buff *pskb;
0464
0465 ring = &rtlpci->tx_ring[BEACON_QUEUE];
0466 pskb = __skb_dequeue(&ring->queue);
0467 kfree_skb(pskb);
0468 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
0469 pdesc = &ring->desc[idx];
0470
0471 rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN);
0472 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
0473 __skb_queue_tail(&ring->queue, skb);
0474 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
0475 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
0476 return true;
0477 }
0478
0479 #define BEACON_PG 0
0480 #define PSPOLL_PG 2
0481 #define NULL_PG 3
0482 #define PROBERSP_PG 4
0483 #define TOTAL_RESERVED_PKT_LEN 768
0484
0485 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
0486
0487 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0488 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0489 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
0490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0491 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0492 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0493 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0494 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0495 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0496 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0497 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0500 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0501 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0503
0504
0505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0507 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0508 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0509 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0512 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0513 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0514 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0515 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0517 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
0518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0519 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0521
0522
0523 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
0524 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0525 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0528 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0529 0x00, 0x00, 0x00, 0x00, 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 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0537 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0539
0540
0541 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0542 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0543 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0545 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0547 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0555 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0557
0558
0559 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0560 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0561 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0562 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
0563 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0564 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0565 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0566 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0567 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0568 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0569 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0573 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0575
0576
0577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0593 };
0594
0595 void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
0596 {
0597 struct rtl_priv *rtlpriv = rtl_priv(hw);
0598 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0599 struct sk_buff *skb = NULL;
0600 u32 totalpacketlen;
0601 bool rtstatus;
0602 u8 u1rsvdpageloc[3] = { 0 };
0603 bool dlok = false;
0604 u8 *beacon;
0605 u8 *p_pspoll;
0606 u8 *nullfunc;
0607 u8 *p_probersp;
0608
0609
0610
0611 beacon = &reserved_page_packet[BEACON_PG * 128];
0612 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
0613 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
0614
0615
0616
0617 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
0618 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
0619 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
0620 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
0621 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
0622
0623
0624
0625 nullfunc = &reserved_page_packet[NULL_PG * 128];
0626 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
0627 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
0628 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
0629 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
0630
0631
0632
0633 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
0634 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
0635 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
0636 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
0637 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
0638 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
0639 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
0640 "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
0641 &reserved_page_packet[0], totalpacketlen);
0642 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
0643 "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
0644 u1rsvdpageloc, 3);
0645 skb = dev_alloc_skb(totalpacketlen);
0646 if (!skb) {
0647 dlok = false;
0648 } else {
0649 skb_put_data(skb, &reserved_page_packet, totalpacketlen);
0650 rtstatus = _rtl92d_cmd_send_packet(hw, skb);
0651
0652 if (rtstatus)
0653 dlok = true;
0654 }
0655 if (dlok) {
0656 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0657 "Set RSVD page location to Fw\n");
0658 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
0659 "H2C_RSVDPAGE", u1rsvdpageloc, 3);
0660 rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,
0661 sizeof(u1rsvdpageloc), u1rsvdpageloc);
0662 } else
0663 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
0664 "Set RSVD page location to Fw FAIL!!!!!!\n");
0665 }
0666
0667 void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
0668 {
0669 u8 u1_joinbssrpt_parm[1] = {0};
0670
0671 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
0672 rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
0673 }