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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
32 #include <linux/firmware.h>
33 #include <linux/export.h>
37 #include "../rtl8192ce/reg.h"
38 #include "../rtl8192ce/def.h"
39 #include "fw_common.h"
41 static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
43 struct rtl_priv *rtlpriv = rtl_priv(hw);
44 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
46 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) {
47 u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
49 value32 |= MCUFWDL_EN;
51 value32 &= ~MCUFWDL_EN;
52 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
53 } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) {
57 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
58 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
61 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
62 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
64 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
65 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
68 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
69 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
71 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
76 static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
77 const u8 *buffer, u32 size)
79 struct rtl_priv *rtlpriv = rtl_priv(hw);
80 u32 blockSize = sizeof(u32);
81 u8 *bufferPtr = (u8 *) buffer;
82 u32 *pu4BytePtr = (u32 *) buffer;
83 u32 i, offset, blockCount, remainSize;
85 blockCount = size / blockSize;
86 remainSize = size % blockSize;
88 for (i = 0; i < blockCount; i++) {
89 offset = i * blockSize;
90 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
95 offset = blockCount * blockSize;
97 for (i = 0; i < remainSize; i++) {
98 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
99 offset + i), *(bufferPtr + i));
104 static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
105 u32 page, const u8 *buffer, u32 size)
107 struct rtl_priv *rtlpriv = rtl_priv(hw);
109 u8 u8page = (u8) (page & 0x07);
111 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
113 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
114 _rtl92c_fw_block_write(hw, buffer, size);
117 static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
120 u8 remain = (u8) (fwlen % 4);
122 remain = (remain == 0) ? 0 : (4 - remain);
133 static void _rtl92c_write_fw(struct ieee80211_hw *hw,
134 enum version_8192c version, u8 *buffer, u32 size)
136 struct rtl_priv *rtlpriv = rtl_priv(hw);
137 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
138 u8 *bufferPtr = (u8 *) buffer;
140 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
142 if (IS_CHIP_VER_B(version)) {
143 u32 pageNums, remainSize;
146 if (IS_HARDWARE_TYPE_8192CE(rtlhal))
147 _rtl92c_fill_dummy(bufferPtr, &size);
149 pageNums = size / FW_8192C_PAGE_SIZE;
150 remainSize = size % FW_8192C_PAGE_SIZE;
153 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
154 ("Page numbers should not greater then 4\n"));
157 for (page = 0; page < pageNums; page++) {
158 offset = page * FW_8192C_PAGE_SIZE;
159 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
164 offset = pageNums * FW_8192C_PAGE_SIZE;
166 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
170 _rtl92c_fw_block_write(hw, buffer, size);
174 static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
176 struct rtl_priv *rtlpriv = rtl_priv(hw);
181 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
182 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
183 (!(value32 & FWDL_ChkSum_rpt)));
185 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
186 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
187 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
192 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
193 ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
195 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
196 value32 |= MCUFWDL_RDY;
197 value32 &= ~WINTINI_RDY;
198 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
203 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
204 if (value32 & WINTINI_RDY) {
205 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
206 ("Polling FW ready success!!"
207 " 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));
221 int rtl92c_download_fw(struct ieee80211_hw *hw)
223 struct rtl_priv *rtlpriv = rtl_priv(hw);
224 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
225 struct rtl92c_firmware_header *pfwheader;
228 enum version_8192c version = rtlhal->version;
230 pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
231 if (!rtlhal->pfirmware)
234 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
235 pfwdata = (u8 *) rtlhal->pfirmware;
236 fwsize = rtlhal->fwsize;
238 if (IS_FW_HEADER_EXIST(pfwheader)) {
239 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
240 ("Firmware Version(%d), Signature(%#x),Size(%d)\n",
241 pfwheader->version, pfwheader->signature,
242 (uint)sizeof(struct rtl92c_firmware_header)));
244 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
245 fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
248 _rtl92c_enable_fw_download(hw, true);
249 _rtl92c_write_fw(hw, version, pfwdata, fwsize);
250 _rtl92c_enable_fw_download(hw, false);
252 if (_rtl92c_fw_free_to_go(hw)) {
253 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
254 ("Firmware is not ready to run!\n"));
256 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
257 ("Firmware is ready to run!\n"));
262 EXPORT_SYMBOL(rtl92c_download_fw);
264 static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
266 struct rtl_priv *rtlpriv = rtl_priv(hw);
267 u8 val_hmetfr, val_mcutst_1;
270 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
271 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
273 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
278 static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
279 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
281 struct rtl_priv *rtlpriv = rtl_priv(hw);
282 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
284 u16 box_reg = 0, box_extreg = 0;
286 bool isfw_read = false;
287 bool bwrite_sucess = false;
288 u8 wait_h2c_limmit = 100;
289 u8 wait_writeh2c_limmit = 100;
290 u8 boxcontent[4], boxextcontent[2];
291 u32 h2c_waitcounter = 0;
295 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
298 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
299 if (rtlhal->h2c_setinprogress) {
300 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
301 ("H2C set in progress! Wait to set.."
302 "element_id(%d).\n", element_id));
304 while (rtlhal->h2c_setinprogress) {
305 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
308 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
309 ("Wait 100 us (%d times)...\n",
313 if (h2c_waitcounter > 1000)
315 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
318 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
320 rtlhal->h2c_setinprogress = true;
321 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
326 while (!bwrite_sucess) {
327 wait_writeh2c_limmit--;
328 if (wait_writeh2c_limmit == 0) {
329 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
330 ("Write H2C fail because no trigger "
335 boxnum = rtlhal->last_hmeboxnum;
338 box_reg = REG_HMEBOX_0;
339 box_extreg = REG_HMEBOX_EXT_0;
342 box_reg = REG_HMEBOX_1;
343 box_extreg = REG_HMEBOX_EXT_1;
346 box_reg = REG_HMEBOX_2;
347 box_extreg = REG_HMEBOX_EXT_2;
350 box_reg = REG_HMEBOX_3;
351 box_extreg = REG_HMEBOX_EXT_3;
354 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
355 ("switch case not process\n"));
359 isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
363 if (wait_h2c_limmit == 0) {
364 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
365 ("Wating too long for FW read "
366 "clear HMEBox(%d)!\n", boxnum));
372 isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
373 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
374 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
375 ("Wating for FW read clear HMEBox(%d)!!! "
376 "0x1BF = %2x\n", boxnum, u1b_tmp));
380 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
381 ("Write H2C register BOX[%d] fail!!!!! "
382 "Fw do not read.\n", boxnum));
386 memset(boxcontent, 0, sizeof(boxcontent));
387 memset(boxextcontent, 0, sizeof(boxextcontent));
388 boxcontent[0] = element_id;
389 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
390 ("Write element_id box_reg(%4x) = %2x\n",
391 box_reg, element_id));
395 boxcontent[0] &= ~(BIT(7));
396 memcpy((u8 *) (boxcontent) + 1,
399 for (idx = 0; idx < 4; idx++) {
400 rtl_write_byte(rtlpriv, box_reg + idx,
405 boxcontent[0] &= ~(BIT(7));
406 memcpy((u8 *) (boxcontent) + 1,
409 for (idx = 0; idx < 4; idx++) {
410 rtl_write_byte(rtlpriv, box_reg + idx,
415 boxcontent[0] &= ~(BIT(7));
416 memcpy((u8 *) (boxcontent) + 1,
419 for (idx = 0; idx < 4; idx++) {
420 rtl_write_byte(rtlpriv, box_reg + idx,
425 boxcontent[0] |= (BIT(7));
426 memcpy((u8 *) (boxextcontent),
428 memcpy((u8 *) (boxcontent) + 1,
431 for (idx = 0; idx < 2; idx++) {
432 rtl_write_byte(rtlpriv, box_extreg + idx,
436 for (idx = 0; idx < 4; idx++) {
437 rtl_write_byte(rtlpriv, box_reg + idx,
442 boxcontent[0] |= (BIT(7));
443 memcpy((u8 *) (boxextcontent),
445 memcpy((u8 *) (boxcontent) + 1,
448 for (idx = 0; idx < 2; idx++) {
449 rtl_write_byte(rtlpriv, box_extreg + idx,
453 for (idx = 0; idx < 4; idx++) {
454 rtl_write_byte(rtlpriv, box_reg + idx,
459 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
460 ("switch case not process\n"));
464 bwrite_sucess = true;
466 rtlhal->last_hmeboxnum = boxnum + 1;
467 if (rtlhal->last_hmeboxnum == 4)
468 rtlhal->last_hmeboxnum = 0;
470 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
471 ("pHalData->last_hmeboxnum = %d\n",
472 rtlhal->last_hmeboxnum));
475 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
476 rtlhal->h2c_setinprogress = false;
477 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
479 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
482 void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
483 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
485 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
488 if (rtlhal->fw_ready == false) {
489 RT_ASSERT(false, ("return H2C cmd because of Fw "
490 "download fail!!!\n"));
494 memset(tmp_cmdbuf, 0, 8);
495 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
496 _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
500 EXPORT_SYMBOL(rtl92c_fill_h2c_cmd);
502 void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
506 struct rtl_priv *rtlpriv = rtl_priv(hw);
508 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
509 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
511 while (u1b_tmp & BIT(2)) {
514 RT_ASSERT(false, ("8051 reset fail.\n"));
518 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
521 EXPORT_SYMBOL(rtl92c_firmware_selfreset);
523 void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
525 struct rtl_priv *rtlpriv = rtl_priv(hw);
526 u8 u1_h2c_set_pwrmode[3] = {0};
527 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
529 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
531 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
532 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
533 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
534 ppsc->reg_max_lps_awakeintvl);
536 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
537 "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
538 u1_h2c_set_pwrmode, 3);
539 rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
542 EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd);
544 static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
547 struct rtl_priv *rtlpriv = rtl_priv(hw);
548 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
549 struct rtl8192_tx_ring *ring;
550 struct rtl_tx_desc *pdesc;
552 struct sk_buff *pskb = NULL;
554 ring = &rtlpci->tx_ring[BEACON_QUEUE];
556 pskb = __skb_dequeue(&ring->queue);
560 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
562 pdesc = &ring->desc[0];
564 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
566 __skb_queue_tail(&ring->queue, skb);
568 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
570 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
575 #define BEACON_PG 0 /*->1*/
578 #define PROBERSP_PG 4 /*->5*/
580 #define TOTAL_RESERVED_PKT_LEN 768
582 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
584 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
585 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
586 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
589 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
590 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
591 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
592 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
593 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
594 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
598 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599 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 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 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
615 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
621 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0x00, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
634 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
639 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
640 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 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,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
652 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655 /* page 4 probe_resp */
656 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
657 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
658 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
659 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
660 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
661 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
662 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
663 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
664 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
665 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
666 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
670 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 /* page 5 probe_resp */
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,
679 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
694 struct rtl_priv *rtlpriv = rtl_priv(hw);
695 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
696 struct sk_buff *skb = NULL;
700 u8 u1RsvdPageLoc[3] = {0};
707 /*---------------------------------------------------------
709 ---------------------------------------------------------*/
710 beacon = &reserved_page_packet[BEACON_PG * 128];
711 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
712 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
714 /*-------------------------------------------------------
716 --------------------------------------------------------*/
717 pspoll = &reserved_page_packet[PSPOLL_PG * 128];
718 SET_80211_PS_POLL_AID(pspoll, (mac->assoc_id | 0xc000));
719 SET_80211_PS_POLL_BSSID(pspoll, mac->bssid);
720 SET_80211_PS_POLL_TA(pspoll, mac->mac_addr);
722 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
724 /*--------------------------------------------------------
726 ---------------------------------------------------------*/
727 nullfunc = &reserved_page_packet[NULL_PG * 128];
728 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
729 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
730 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
732 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
734 /*---------------------------------------------------------
736 ----------------------------------------------------------*/
737 probersp = &reserved_page_packet[PROBERSP_PG * 128];
738 SET_80211_HDR_ADDRESS1(probersp, mac->bssid);
739 SET_80211_HDR_ADDRESS2(probersp, mac->mac_addr);
740 SET_80211_HDR_ADDRESS3(probersp, mac->bssid);
742 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
744 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
746 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
747 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
748 &reserved_page_packet[0], totalpacketlen);
749 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
750 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
754 skb = dev_alloc_skb(totalpacketlen);
755 memcpy((u8 *) skb_put(skb, totalpacketlen),
756 &reserved_page_packet, totalpacketlen);
758 rtstatus = _rtl92c_cmd_send_packet(hw, skb);
764 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
765 ("Set RSVD page location to Fw.\n"));
766 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
769 rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
770 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
772 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
773 ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
775 EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt);
777 void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
779 u8 u1_joinbssrpt_parm[1] = {0};
781 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
783 rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
785 EXPORT_SYMBOL(rtl92c_set_fw_joinbss_report_cmd);