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>
34 #include "../rtl8192ce/reg.h"
35 #include "../rtl8192ce/def.h"
36 #include "fw_common.h"
38 static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
40 struct rtl_priv *rtlpriv = rtl_priv(hw);
41 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
43 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) {
44 u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
46 value32 |= MCUFWDL_EN;
48 value32 &= ~MCUFWDL_EN;
49 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
50 } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) {
54 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
55 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
58 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
59 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
61 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
62 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
65 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
66 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
68 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
73 static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
74 const u8 *buffer, u32 size)
76 struct rtl_priv *rtlpriv = rtl_priv(hw);
77 u32 blockSize = sizeof(u32);
78 u8 *bufferPtr = (u8 *) buffer;
79 u32 *pu4BytePtr = (u32 *) buffer;
80 u32 i, offset, blockCount, remainSize;
82 blockCount = size / blockSize;
83 remainSize = size % blockSize;
85 for (i = 0; i < blockCount; i++) {
86 offset = i * blockSize;
87 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
92 offset = blockCount * blockSize;
94 for (i = 0; i < remainSize; i++) {
95 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
96 offset + i), *(bufferPtr + i));
101 static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
102 u32 page, const u8 *buffer, u32 size)
104 struct rtl_priv *rtlpriv = rtl_priv(hw);
106 u8 u8page = (u8) (page & 0x07);
108 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
110 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
111 _rtl92c_fw_block_write(hw, buffer, size);
114 static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
117 u8 remain = (u8) (fwlen % 4);
119 remain = (remain == 0) ? 0 : (4 - remain);
130 static void _rtl92c_write_fw(struct ieee80211_hw *hw,
131 enum version_8192c version, u8 *buffer, u32 size)
133 struct rtl_priv *rtlpriv = rtl_priv(hw);
134 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
135 u8 *bufferPtr = (u8 *) buffer;
137 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
139 if (IS_CHIP_VER_B(version)) {
140 u32 pageNums, remainSize;
143 if (IS_HARDWARE_TYPE_8192CE(rtlhal))
144 _rtl92c_fill_dummy(bufferPtr, &size);
146 pageNums = size / FW_8192C_PAGE_SIZE;
147 remainSize = size % FW_8192C_PAGE_SIZE;
150 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
151 ("Page numbers should not greater then 4\n"));
154 for (page = 0; page < pageNums; page++) {
155 offset = page * FW_8192C_PAGE_SIZE;
156 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
161 offset = pageNums * FW_8192C_PAGE_SIZE;
163 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
167 _rtl92c_fw_block_write(hw, buffer, size);
171 static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
173 struct rtl_priv *rtlpriv = rtl_priv(hw);
179 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
180 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
181 (!(value32 & FWDL_ChkSum_rpt)));
183 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
184 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
185 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
190 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
191 ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
193 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
194 value32 |= MCUFWDL_RDY;
195 value32 &= ~WINTINI_RDY;
196 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
201 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
202 if (value32 & WINTINI_RDY) {
203 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
204 ("Polling FW ready success!!"
205 " REG_MCUFWDL:0x%08x .\n",
211 mdelay(FW_8192C_POLLING_DELAY);
213 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
215 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
216 ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
222 int rtl92c_download_fw(struct ieee80211_hw *hw)
224 struct rtl_priv *rtlpriv = rtl_priv(hw);
225 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
226 struct rtl92c_firmware_header *pfwheader;
230 enum version_8192c version = rtlhal->version;
231 const struct firmware *firmware;
233 printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n",
234 rtlpriv->cfg->fw_name);
235 err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
238 printk(KERN_ERR "rtl8192cu: Firmware loading failed\n");
242 if (firmware->size > 0x4000) {
243 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
244 ("Firmware is too big!\n"));
245 release_firmware(firmware);
249 memcpy(rtlhal->pfirmware, firmware->data, firmware->size);
250 fwsize = firmware->size;
251 release_firmware(firmware);
253 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
254 pfwdata = (u8 *) rtlhal->pfirmware;
256 if (IS_FW_HEADER_EXIST(pfwheader)) {
257 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
258 ("Firmware Version(%d), Signature(%#x),Size(%d)\n",
259 pfwheader->version, pfwheader->signature,
260 (uint)sizeof(struct rtl92c_firmware_header)));
262 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
263 fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
266 _rtl92c_enable_fw_download(hw, true);
267 _rtl92c_write_fw(hw, version, pfwdata, fwsize);
268 _rtl92c_enable_fw_download(hw, false);
270 err = _rtl92c_fw_free_to_go(hw);
272 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
273 ("Firmware is not ready to run!\n"));
275 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
276 ("Firmware is ready to run!\n"));
281 EXPORT_SYMBOL(rtl92c_download_fw);
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);
520 EXPORT_SYMBOL(rtl92c_fill_h2c_cmd);
522 void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
526 struct rtl_priv *rtlpriv = rtl_priv(hw);
528 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
529 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
531 while (u1b_tmp & BIT(2)) {
534 RT_ASSERT(false, ("8051 reset fail.\n"));
538 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
541 EXPORT_SYMBOL(rtl92c_firmware_selfreset);
543 void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
545 struct rtl_priv *rtlpriv = rtl_priv(hw);
546 u8 u1_h2c_set_pwrmode[3] = {0};
547 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
549 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
551 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
552 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
553 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
554 ppsc->reg_max_lps_awakeintvl);
556 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
557 "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
558 u1_h2c_set_pwrmode, 3);
559 rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
562 EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd);
564 #define BEACON_PG 0 /*->1*/
567 #define PROBERSP_PG 4 /*->5*/
569 #define TOTAL_RESERVED_PKT_LEN 768
571 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
573 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
574 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
575 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
578 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
579 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
580 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
581 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
582 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
583 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
587 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 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 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 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
610 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
623 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
628 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
629 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 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 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 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
641 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 /* page 4 probe_resp */
645 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
646 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
647 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
648 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
649 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
650 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
651 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
652 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
653 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
654 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
655 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
659 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662 /* page 5 probe_resp */
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,
676 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681 void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
683 struct rtl_priv *rtlpriv = rtl_priv(hw);
684 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
685 struct sk_buff *skb = NULL;
689 u8 u1RsvdPageLoc[3] = {0};
696 /*---------------------------------------------------------
698 ---------------------------------------------------------*/
699 beacon = &reserved_page_packet[BEACON_PG * 128];
700 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
701 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
703 /*-------------------------------------------------------
705 --------------------------------------------------------*/
706 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
707 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
708 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
709 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
711 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
713 /*--------------------------------------------------------
715 ---------------------------------------------------------*/
716 nullfunc = &reserved_page_packet[NULL_PG * 128];
717 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
718 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
719 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
721 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
723 /*---------------------------------------------------------
725 ----------------------------------------------------------*/
726 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
727 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
728 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
729 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
731 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
733 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
735 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
736 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
737 &reserved_page_packet[0], totalpacketlen);
738 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
739 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
743 skb = dev_alloc_skb(totalpacketlen);
744 memcpy((u8 *) skb_put(skb, totalpacketlen),
745 &reserved_page_packet, totalpacketlen);
747 rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb);
753 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
754 ("Set RSVD page location to Fw.\n"));
755 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
758 rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
759 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
761 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
762 ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
764 EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt);
766 void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
768 u8 u1_joinbssrpt_parm[1] = {0};
770 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
772 rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
774 EXPORT_SYMBOL(rtl92c_set_fw_joinbss_report_cmd);