1 /******************************************************************************
3 * Copyright(c) 2009-2010 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 *****************************************************************************/
30 #include <linux/firmware.h>
39 static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
41 struct rtl_priv *rtlpriv = rtl_priv(hw);
42 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
44 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) {
45 u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
47 value32 |= MCUFWDL_EN;
49 value32 &= ~MCUFWDL_EN;
50 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
51 } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) {
55 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
56 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
59 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
60 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
62 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
63 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
66 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
67 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
69 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
74 static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
75 const u8 *buffer, u32 size)
77 struct rtl_priv *rtlpriv = rtl_priv(hw);
78 u32 blockSize = sizeof(u32);
79 u8 *bufferPtr = (u8 *) buffer;
80 u32 *pu4BytePtr = (u32 *) buffer;
81 u32 i, offset, blockCount, remainSize;
83 blockCount = size / blockSize;
84 remainSize = size % blockSize;
86 for (i = 0; i < blockCount; i++) {
87 offset = i * blockSize;
88 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
93 offset = blockCount * blockSize;
95 for (i = 0; i < remainSize; i++) {
96 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
97 offset + i), *(bufferPtr + i));
102 static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
103 u32 page, const u8 *buffer, u32 size)
105 struct rtl_priv *rtlpriv = rtl_priv(hw);
107 u8 u8page = (u8) (page & 0x07);
109 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
111 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
112 _rtl92c_fw_block_write(hw, buffer, size);
115 static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
118 u8 remain = (u8) (fwlen % 4);
120 remain = (remain == 0) ? 0 : (4 - remain);
131 static void _rtl92c_write_fw(struct ieee80211_hw *hw,
132 enum version_8192c version, u8 *buffer, u32 size)
134 struct rtl_priv *rtlpriv = rtl_priv(hw);
135 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
136 u8 *bufferPtr = (u8 *) buffer;
138 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
140 if (IS_CHIP_VER_B(version)) {
141 u32 pageNums, remainSize;
144 if (IS_HARDWARE_TYPE_8192CE(rtlhal))
145 _rtl92c_fill_dummy(bufferPtr, &size);
147 pageNums = size / FW_8192C_PAGE_SIZE;
148 remainSize = size % FW_8192C_PAGE_SIZE;
151 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
152 ("Page numbers should not greater then 4\n"));
155 for (page = 0; page < pageNums; page++) {
156 offset = page * FW_8192C_PAGE_SIZE;
157 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
162 offset = pageNums * FW_8192C_PAGE_SIZE;
164 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
168 _rtl92c_fw_block_write(hw, buffer, size);
172 static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
174 struct rtl_priv *rtlpriv = rtl_priv(hw);
180 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
181 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
182 (!(value32 & FWDL_ChkSum_rpt)));
184 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
185 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
186 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
191 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
192 ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
194 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
195 value32 |= MCUFWDL_RDY;
196 value32 &= ~WINTINI_RDY;
197 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
202 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
203 if (value32 & WINTINI_RDY) {
204 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
205 ("Polling FW ready success!!"
206 " REG_MCUFWDL:0x%08x .\n",
212 mdelay(FW_8192C_POLLING_DELAY);
214 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
216 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
217 ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
223 int rtl92c_download_fw(struct ieee80211_hw *hw)
225 struct rtl_priv *rtlpriv = rtl_priv(hw);
226 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
227 struct rtl92c_firmware_header *pfwheader;
231 enum version_8192c version = rtlhal->version;
232 const struct firmware *firmware;
234 printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n",
235 rtlpriv->cfg->fw_name);
236 err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
239 printk(KERN_ERR "rtl8192cu: Firmware loading failed\n");
243 if (firmware->size > 0x4000) {
244 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
245 ("Firmware is too big!\n"));
246 release_firmware(firmware);
250 memcpy(rtlhal->pfirmware, firmware->data, firmware->size);
251 fwsize = firmware->size;
252 release_firmware(firmware);
254 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
255 pfwdata = (u8 *) rtlhal->pfirmware;
257 if (IS_FW_HEADER_EXIST(pfwheader)) {
258 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
259 ("Firmware Version(%d), Signature(%#x),Size(%d)\n",
260 pfwheader->version, pfwheader->signature,
261 (uint)sizeof(struct rtl92c_firmware_header)));
263 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
264 fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
267 _rtl92c_enable_fw_download(hw, true);
268 _rtl92c_write_fw(hw, version, pfwdata, fwsize);
269 _rtl92c_enable_fw_download(hw, false);
271 err = _rtl92c_fw_free_to_go(hw);
273 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
274 ("Firmware is not ready to run!\n"));
276 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
277 ("Firmware is ready to run!\n"));
283 static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
285 struct rtl_priv *rtlpriv = rtl_priv(hw);
286 u8 val_hmetfr, val_mcutst_1;
289 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
290 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
292 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
297 static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
298 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
300 struct rtl_priv *rtlpriv = rtl_priv(hw);
301 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
303 u16 box_reg, box_extreg;
305 bool isfw_read = false;
307 bool bwrite_sucess = false;
308 u8 wait_h2c_limmit = 100;
309 u8 wait_writeh2c_limmit = 100;
310 u8 boxcontent[4], boxextcontent[2];
311 u32 h2c_waitcounter = 0;
315 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
318 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
319 if (rtlhal->h2c_setinprogress) {
320 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
321 ("H2C set in progress! Wait to set.."
322 "element_id(%d).\n", element_id));
324 while (rtlhal->h2c_setinprogress) {
325 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
328 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
329 ("Wait 100 us (%d times)...\n",
333 if (h2c_waitcounter > 1000)
335 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
338 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
340 rtlhal->h2c_setinprogress = true;
341 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
346 while (!bwrite_sucess) {
347 wait_writeh2c_limmit--;
348 if (wait_writeh2c_limmit == 0) {
349 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
350 ("Write H2C fail because no trigger "
355 boxnum = rtlhal->last_hmeboxnum;
358 box_reg = REG_HMEBOX_0;
359 box_extreg = REG_HMEBOX_EXT_0;
362 box_reg = REG_HMEBOX_1;
363 box_extreg = REG_HMEBOX_EXT_1;
366 box_reg = REG_HMEBOX_2;
367 box_extreg = REG_HMEBOX_EXT_2;
370 box_reg = REG_HMEBOX_3;
371 box_extreg = REG_HMEBOX_EXT_3;
374 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
375 ("switch case not process\n"));
379 isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
383 if (wait_h2c_limmit == 0) {
384 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
385 ("Wating too long for FW read "
386 "clear HMEBox(%d)!\n", boxnum));
392 isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
393 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
394 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
395 ("Wating for FW read clear HMEBox(%d)!!! "
396 "0x1BF = %2x\n", boxnum, u1b_tmp));
400 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
401 ("Write H2C register BOX[%d] fail!!!!! "
402 "Fw do not read.\n", boxnum));
406 memset(boxcontent, 0, sizeof(boxcontent));
407 memset(boxextcontent, 0, sizeof(boxextcontent));
408 boxcontent[0] = element_id;
409 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
410 ("Write element_id box_reg(%4x) = %2x\n",
411 box_reg, element_id));
415 boxcontent[0] &= ~(BIT(7));
416 memcpy((u8 *) (boxcontent) + 1,
417 p_cmdbuffer + buf_index, 1);
419 for (idx = 0; idx < 4; idx++) {
420 rtl_write_byte(rtlpriv, box_reg + idx,
425 boxcontent[0] &= ~(BIT(7));
426 memcpy((u8 *) (boxcontent) + 1,
427 p_cmdbuffer + buf_index, 2);
429 for (idx = 0; idx < 4; idx++) {
430 rtl_write_byte(rtlpriv, box_reg + idx,
435 boxcontent[0] &= ~(BIT(7));
436 memcpy((u8 *) (boxcontent) + 1,
437 p_cmdbuffer + buf_index, 3);
439 for (idx = 0; idx < 4; idx++) {
440 rtl_write_byte(rtlpriv, box_reg + idx,
445 boxcontent[0] |= (BIT(7));
446 memcpy((u8 *) (boxextcontent),
447 p_cmdbuffer + buf_index, 2);
448 memcpy((u8 *) (boxcontent) + 1,
449 p_cmdbuffer + buf_index + 2, 2);
451 for (idx = 0; idx < 2; idx++) {
452 rtl_write_byte(rtlpriv, box_extreg + idx,
456 for (idx = 0; idx < 4; idx++) {
457 rtl_write_byte(rtlpriv, box_reg + idx,
462 boxcontent[0] |= (BIT(7));
463 memcpy((u8 *) (boxextcontent),
464 p_cmdbuffer + buf_index, 2);
465 memcpy((u8 *) (boxcontent) + 1,
466 p_cmdbuffer + buf_index + 2, 3);
468 for (idx = 0; idx < 2; idx++) {
469 rtl_write_byte(rtlpriv, box_extreg + idx,
473 for (idx = 0; idx < 4; idx++) {
474 rtl_write_byte(rtlpriv, box_reg + idx,
479 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
480 ("switch case not process\n"));
484 bwrite_sucess = true;
486 rtlhal->last_hmeboxnum = boxnum + 1;
487 if (rtlhal->last_hmeboxnum == 4)
488 rtlhal->last_hmeboxnum = 0;
490 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
491 ("pHalData->last_hmeboxnum = %d\n",
492 rtlhal->last_hmeboxnum));
495 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
496 rtlhal->h2c_setinprogress = false;
497 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
499 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
502 void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
503 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
505 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
508 if (rtlhal->fw_ready == false) {
509 RT_ASSERT(false, ("return H2C cmd because of Fw "
510 "download fail!!!\n"));
514 memset(tmp_cmdbuf, 0, 8);
515 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
516 _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
521 void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
525 struct rtl_priv *rtlpriv = rtl_priv(hw);
527 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
528 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
530 while (u1b_tmp & BIT(2)) {
533 RT_ASSERT(false, ("8051 reset fail.\n"));
537 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
541 void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
543 struct rtl_priv *rtlpriv = rtl_priv(hw);
544 u8 u1_h2c_set_pwrmode[3] = {0};
545 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
547 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
549 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
550 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
551 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
552 ppsc->reg_max_lps_awakeintvl);
554 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
555 "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
556 u1_h2c_set_pwrmode, 3);
557 rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
561 #define BEACON_PG 0 /*->1*/
564 #define PROBERSP_PG 4 /*->5*/
566 #define TOTAL_RESERVED_PKT_LEN 768
568 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
570 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
571 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
572 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
575 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
576 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
577 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
578 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
579 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
580 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
584 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
607 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
614 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
620 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
625 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
626 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
638 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 /* page 4 probe_resp */
642 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
643 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
644 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
645 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
646 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
647 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
648 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
649 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
650 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
651 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
652 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
656 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659 /* page 5 probe_resp */
660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678 void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
680 struct rtl_priv *rtlpriv = rtl_priv(hw);
681 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
682 struct sk_buff *skb = NULL;
686 u8 u1RsvdPageLoc[3] = {0};
693 /*---------------------------------------------------------
695 ---------------------------------------------------------*/
696 beacon = &reserved_page_packet[BEACON_PG * 128];
697 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
698 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
700 /*-------------------------------------------------------
702 --------------------------------------------------------*/
703 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
704 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
705 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
706 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
708 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
710 /*--------------------------------------------------------
712 ---------------------------------------------------------*/
713 nullfunc = &reserved_page_packet[NULL_PG * 128];
714 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
715 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
716 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
718 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
720 /*---------------------------------------------------------
722 ----------------------------------------------------------*/
723 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
724 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
725 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
726 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
728 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
730 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
732 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
733 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
734 &reserved_page_packet[0], totalpacketlen);
735 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
736 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
740 skb = dev_alloc_skb(totalpacketlen);
741 memcpy((u8 *) skb_put(skb, totalpacketlen),
742 &reserved_page_packet, totalpacketlen);
744 rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb);
750 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
751 ("Set RSVD page location to Fw.\n"));
752 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
755 rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
756 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
758 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
759 ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
762 void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
764 u8 u1_joinbssrpt_parm[1] = {0};
766 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
768 rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);