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_sucess
= 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_sucess
) {
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_sucess
= 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
;
517 struct sk_buff
*pskb
= NULL
;
519 ring
= &rtlpci
->tx_ring
[BEACON_QUEUE
];
521 pskb
= __skb_dequeue(&ring
->queue
);
525 spin_lock_irqsave(&rtlpriv
->locks
.irq_th_lock
, flags
);
527 pdesc
= &ring
->desc
[0];
528 own
= (u8
) rtlpriv
->cfg
->ops
->get_desc((u8
*) pdesc
, true, HW_DESC_OWN
);
530 rtlpriv
->cfg
->ops
->fill_tx_cmddesc(hw
, (u8
*) pdesc
, 1, 1, skb
);
532 __skb_queue_tail(&ring
->queue
, skb
);
534 spin_unlock_irqrestore(&rtlpriv
->locks
.irq_th_lock
, flags
);
536 rtlpriv
->cfg
->ops
->tx_polling(hw
, BEACON_QUEUE
);
541 static u8 reserved_page_packet
[TOTAL_RESERVED_PKT_LEN
] = {
543 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
544 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
545 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
548 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
549 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
550 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
551 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
552 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
553 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
557 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
580 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
593 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
598 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
599 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
611 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
614 /* page 4 probe_resp */
615 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
616 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
617 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
618 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
619 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
620 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
621 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
622 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
623 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
624 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
625 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
629 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 /* page 5 probe_resp */
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,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw
*hw
, bool dl_finished
)
653 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
654 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
655 struct sk_buff
*skb
= NULL
;
659 u8 u1RsvdPageLoc
[3] = { 0 };
666 /*---------------------------------------------------------
668 ---------------------------------------------------------
670 beacon
= &reserved_page_packet
[BEACON_PG
* 128];
671 SET_80211_HDR_ADDRESS2(beacon
, mac
->mac_addr
);
672 SET_80211_HDR_ADDRESS3(beacon
, mac
->bssid
);
674 /*-------------------------------------------------------
676 --------------------------------------------------------
678 p_pspoll
= &reserved_page_packet
[PSPOLL_PG
* 128];
679 SET_80211_PS_POLL_AID(p_pspoll
, (mac
->assoc_id
| 0xc000));
680 SET_80211_PS_POLL_BSSID(p_pspoll
, mac
->bssid
);
681 SET_80211_PS_POLL_TA(p_pspoll
, mac
->mac_addr
);
683 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc
, PSPOLL_PG
);
685 /*--------------------------------------------------------
687 ---------------------------------------------------------i
689 nullfunc
= &reserved_page_packet
[NULL_PG
* 128];
690 SET_80211_HDR_ADDRESS1(nullfunc
, mac
->bssid
);
691 SET_80211_HDR_ADDRESS2(nullfunc
, mac
->mac_addr
);
692 SET_80211_HDR_ADDRESS3(nullfunc
, mac
->bssid
);
694 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc
, NULL_PG
);
696 /*---------------------------------------------------------
698 ----------------------------------------------------------
700 p_probersp
= &reserved_page_packet
[PROBERSP_PG
* 128];
701 SET_80211_HDR_ADDRESS1(p_probersp
, mac
->bssid
);
702 SET_80211_HDR_ADDRESS2(p_probersp
, mac
->mac_addr
);
703 SET_80211_HDR_ADDRESS3(p_probersp
, mac
->bssid
);
705 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc
, PROBERSP_PG
);
707 totalpacketlen
= TOTAL_RESERVED_PKT_LEN
;
709 RT_PRINT_DATA(rtlpriv
, COMP_CMD
, DBG_LOUD
,
710 "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
711 &reserved_page_packet
[0], totalpacketlen
);
712 RT_PRINT_DATA(rtlpriv
, COMP_CMD
, DBG_DMESG
,
713 "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
716 skb
= dev_alloc_skb(totalpacketlen
);
717 memcpy((u8
*) skb_put(skb
, totalpacketlen
),
718 &reserved_page_packet
, totalpacketlen
);
720 rtstatus
= _rtl8723ae_cmd_send_packet(hw
, skb
);
726 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
727 "Set RSVD page location to Fw.\n");
728 RT_PRINT_DATA(rtlpriv
, COMP_CMD
, DBG_DMESG
,
731 rtl8723ae_fill_h2c_cmd(hw
, H2C_RSVDPAGE
,
732 sizeof(u1RsvdPageLoc
), u1RsvdPageLoc
);
734 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_WARNING
,
735 "Set RSVD page location to Fw FAIL!!!!!!.\n");
738 void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw
*hw
, u8 mstatus
)
740 u8 u1_joinbssrpt_parm
[1] = { 0 };
742 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm
, mstatus
);
744 rtl8723ae_fill_h2c_cmd(hw
, H2C_JOINBSSRPT
, 1, u1_joinbssrpt_parm
);