1 /******************************************************************************
3 * Copyright(c) 2009-2012 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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
26 * Larry Finger <Larry.Finger@lwfinger.net>
28 ****************************************************************************
38 static void _rtl8723ae_enable_fw_download(struct ieee80211_hw *hw, bool enable)
40 struct rtl_priv *rtlpriv = rtl_priv(hw);
43 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
44 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
46 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
47 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
49 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
50 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
52 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
53 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
55 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
59 static void _rtl8723ae_fw_block_write(struct ieee80211_hw *hw,
60 const u8 *buffer, u32 size)
62 struct rtl_priv *rtlpriv = rtl_priv(hw);
63 u32 blockSize = sizeof(u32);
64 u8 *bufferPtr = (u8 *) buffer;
65 u32 *pu4BytePtr = (u32 *) buffer;
66 u32 i, offset, blockCount, remainSize;
68 blockCount = size / blockSize;
69 remainSize = size % blockSize;
71 for (i = 0; i < blockCount; i++) {
72 offset = i * blockSize;
73 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
78 offset = blockCount * blockSize;
80 for (i = 0; i < remainSize; i++) {
81 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
82 offset + i), *(bufferPtr + i));
87 static void _rtl8723ae_fw_page_write(struct ieee80211_hw *hw,
88 u32 page, const u8 *buffer, u32 size)
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
92 u8 u8page = (u8) (page & 0x07);
94 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
96 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
97 _rtl8723ae_fw_block_write(hw, buffer, size);
100 static void _rtl8723ae_write_fw(struct ieee80211_hw *hw,
101 enum version_8723e version, u8 *buffer,
104 struct rtl_priv *rtlpriv = rtl_priv(hw);
105 u8 *bufferPtr = (u8 *) buffer;
106 u32 page_nums, remain_size;
109 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
111 page_nums = size / FW_8192C_PAGE_SIZE;
112 remain_size = size % FW_8192C_PAGE_SIZE;
115 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
116 "Page numbers should not be greater then 6\n");
119 for (page = 0; page < page_nums; page++) {
120 offset = page * FW_8192C_PAGE_SIZE;
121 _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset),
126 offset = page_nums * FW_8192C_PAGE_SIZE;
128 _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset),
132 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n");
135 static int _rtl8723ae_fw_free_to_go(struct ieee80211_hw *hw)
137 struct rtl_priv *rtlpriv = rtl_priv(hw);
143 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
144 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
145 (!(value32 & FWDL_ChkSum_rpt)));
147 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
148 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
149 "chksum report faill ! REG_MCUFWDL:0x%08x .\n",
154 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
155 "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32);
157 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
158 value32 |= MCUFWDL_RDY;
159 value32 &= ~WINTINI_RDY;
160 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
165 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
166 if (value32 & WINTINI_RDY) {
167 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
168 "Polling FW ready success!! REG_MCUFWDL:0x%08x .\n",
174 mdelay(FW_8192C_POLLING_DELAY);
176 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
178 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
179 "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32);
185 int rtl8723ae_download_fw(struct ieee80211_hw *hw)
187 struct rtl_priv *rtlpriv = rtl_priv(hw);
188 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
189 struct rtl8723ae_firmware_header *pfwheader;
193 enum version_8723e version = rtlhal->version;
195 if (!rtlhal->pfirmware)
198 pfwheader = (struct rtl8723ae_firmware_header *)rtlhal->pfirmware;
199 pfwdata = (u8 *) rtlhal->pfirmware;
200 fwsize = rtlhal->fwsize;
202 if (IS_FW_HEADER_EXIST(pfwheader)) {
203 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
204 "Firmware Version(%d), Signature(%#x),Size(%d)\n",
205 pfwheader->version, pfwheader->signature,
206 (int)sizeof(struct rtl8723ae_firmware_header));
208 pfwdata = pfwdata + sizeof(struct rtl8723ae_firmware_header);
209 fwsize = fwsize - sizeof(struct rtl8723ae_firmware_header);
212 if (rtl_read_byte(rtlpriv, REG_MCUFWDL)&BIT(7)) {
213 rtl8723ae_firmware_selfreset(hw);
214 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
216 _rtl8723ae_enable_fw_download(hw, true);
217 _rtl8723ae_write_fw(hw, version, pfwdata, fwsize);
218 _rtl8723ae_enable_fw_download(hw, false);
220 err = _rtl8723ae_fw_free_to_go(hw);
222 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
223 "Firmware is not ready to run!\n");
225 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
226 "Firmware is ready to run!\n");
231 static bool rtl8723ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
233 struct rtl_priv *rtlpriv = rtl_priv(hw);
234 u8 val_hmetfr, val_mcutst_1;
237 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
238 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
240 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
245 static void _rtl8723ae_fill_h2c_command(struct ieee80211_hw *hw,
246 u8 element_id, u32 cmd_len,
249 struct rtl_priv *rtlpriv = rtl_priv(hw);
250 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
252 u16 box_reg = 0, box_extreg = 0;
254 bool isfw_rd = false;
255 bool bwrite_success = false;
256 u8 wait_h2c_limmit = 100;
257 u8 wait_writeh2c_limmit = 100;
258 u8 boxcontent[4], boxextcontent[2];
259 u32 h2c_waitcounter = 0;
263 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
266 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
267 if (rtlhal->h2c_setinprogress) {
268 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
269 "H2C set in progress! Wait to set..element_id(%d).\n",
272 while (rtlhal->h2c_setinprogress) {
273 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
276 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
277 "Wait 100 us (%d times)...\n",
281 if (h2c_waitcounter > 1000)
283 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
286 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
288 rtlhal->h2c_setinprogress = true;
289 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
294 while (!bwrite_success) {
295 wait_writeh2c_limmit--;
296 if (wait_writeh2c_limmit == 0) {
297 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
298 "Write H2C fail because no trigger "
303 boxnum = rtlhal->last_hmeboxnum;
306 box_reg = REG_HMEBOX_0;
307 box_extreg = REG_HMEBOX_EXT_0;
310 box_reg = REG_HMEBOX_1;
311 box_extreg = REG_HMEBOX_EXT_1;
314 box_reg = REG_HMEBOX_2;
315 box_extreg = REG_HMEBOX_EXT_2;
318 box_reg = REG_HMEBOX_3;
319 box_extreg = REG_HMEBOX_EXT_3;
322 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
323 "switch case not processed\n");
327 isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum);
331 if (wait_h2c_limmit == 0) {
332 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
333 "Wating too long for FW read clear HMEBox(%d)!\n",
340 isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum);
341 u1tmp = rtl_read_byte(rtlpriv, 0x1BF);
342 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
343 "Wating for FW read clear HMEBox(%d)!!! "
344 "0x1BF = %2x\n", boxnum, u1tmp);
348 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
349 "Write H2C register BOX[%d] fail!!!!! "
350 "Fw do not read.\n", boxnum);
354 memset(boxcontent, 0, sizeof(boxcontent));
355 memset(boxextcontent, 0, sizeof(boxextcontent));
356 boxcontent[0] = element_id;
357 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
358 "Write element_id box_reg(%4x) = %2x\n",
359 box_reg, element_id);
363 boxcontent[0] &= ~(BIT(7));
364 memcpy((u8 *) (boxcontent) + 1,
367 for (idx = 0; idx < 4; idx++) {
368 rtl_write_byte(rtlpriv, box_reg + idx,
373 boxcontent[0] &= ~(BIT(7));
374 memcpy((u8 *) (boxcontent) + 1,
377 for (idx = 0; idx < 4; idx++) {
378 rtl_write_byte(rtlpriv, box_reg + idx,
383 boxcontent[0] &= ~(BIT(7));
384 memcpy((u8 *) (boxcontent) + 1,
387 for (idx = 0; idx < 4; idx++) {
388 rtl_write_byte(rtlpriv, box_reg + idx,
393 boxcontent[0] |= (BIT(7));
394 memcpy((u8 *) (boxextcontent),
396 memcpy((u8 *) (boxcontent) + 1,
399 for (idx = 0; idx < 2; idx++) {
400 rtl_write_byte(rtlpriv, box_extreg + idx,
404 for (idx = 0; idx < 4; idx++) {
405 rtl_write_byte(rtlpriv, box_reg + idx,
410 boxcontent[0] |= (BIT(7));
411 memcpy((u8 *) (boxextcontent),
413 memcpy((u8 *) (boxcontent) + 1,
416 for (idx = 0; idx < 2; idx++) {
417 rtl_write_byte(rtlpriv, box_extreg + idx,
421 for (idx = 0; idx < 4; idx++) {
422 rtl_write_byte(rtlpriv, box_reg + idx,
427 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
428 "switch case not process\n");
432 bwrite_success = true;
434 rtlhal->last_hmeboxnum = boxnum + 1;
435 if (rtlhal->last_hmeboxnum == 4)
436 rtlhal->last_hmeboxnum = 0;
438 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
439 "pHalData->last_hmeboxnum = %d\n",
440 rtlhal->last_hmeboxnum);
443 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
444 rtlhal->h2c_setinprogress = false;
445 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
447 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
450 void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw,
451 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
453 struct rtl_priv *rtlpriv = rtl_priv(hw);
454 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
456 if (rtlhal->fw_ready == false) {
458 "return H2C cmd because of Fw download fail!!!\n");
462 _rtl8723ae_fill_h2c_command(hw, element_id, cmd_len, p_cmdbuffer);
466 void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw)
470 struct rtl_priv *rtlpriv = rtl_priv(hw);
472 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
473 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
475 while (u1tmp & BIT(2)) {
480 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
483 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
484 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1tmp&(~BIT(2)));
488 void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
490 struct rtl_priv *rtlpriv = rtl_priv(hw);
491 u8 u1_h2c_set_pwrmode[3] = { 0 };
492 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
494 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
496 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
497 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
498 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
499 ppsc->reg_max_lps_awakeintvl);
501 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
502 "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
503 u1_h2c_set_pwrmode, 3);
504 rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
508 static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw,
511 struct rtl_priv *rtlpriv = rtl_priv(hw);
512 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
513 struct rtl8192_tx_ring *ring;
514 struct rtl_tx_desc *pdesc;
516 struct sk_buff *pskb = NULL;
518 ring = &rtlpci->tx_ring[BEACON_QUEUE];
520 pskb = __skb_dequeue(&ring->queue);
524 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
526 pdesc = &ring->desc[0];
528 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
530 __skb_queue_tail(&ring->queue, skb);
532 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
534 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
539 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
541 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
542 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
543 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
546 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
547 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
548 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
549 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
550 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
551 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
555 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
578 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
591 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
596 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
597 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
609 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 /* page 4 probe_resp */
613 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
614 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
615 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
616 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
617 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
618 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
619 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
620 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
621 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
622 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
623 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
627 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 /* page 5 probe_resp */
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
651 struct rtl_priv *rtlpriv = rtl_priv(hw);
652 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
653 struct sk_buff *skb = NULL;
657 u8 u1RsvdPageLoc[3] = { 0 };
664 /*---------------------------------------------------------
666 ---------------------------------------------------------
668 beacon = &reserved_page_packet[BEACON_PG * 128];
669 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
670 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
672 /*-------------------------------------------------------
674 --------------------------------------------------------
676 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
677 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
678 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
679 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
681 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
683 /*--------------------------------------------------------
685 ---------------------------------------------------------i
687 nullfunc = &reserved_page_packet[NULL_PG * 128];
688 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
689 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
690 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
692 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
694 /*---------------------------------------------------------
696 ----------------------------------------------------------
698 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
699 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
700 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
701 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
703 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
705 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
707 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
708 "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
709 &reserved_page_packet[0], totalpacketlen);
710 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
711 "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
714 skb = dev_alloc_skb(totalpacketlen);
715 memcpy((u8 *) skb_put(skb, totalpacketlen),
716 &reserved_page_packet, totalpacketlen);
718 rtstatus = _rtl8723ae_cmd_send_packet(hw, skb);
724 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
725 "Set RSVD page location to Fw.\n");
726 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
729 rtl8723ae_fill_h2c_cmd(hw, H2C_RSVDPAGE,
730 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
732 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
733 "Set RSVD page location to Fw FAIL!!!!!!.\n");
736 void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
738 u8 u1_joinbssrpt_parm[1] = { 0 };
740 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
742 rtl8723ae_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);