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 rtl_block_fw_writeN(struct ieee80211_hw *hw, const u8 *buffer,
79 struct rtl_priv *rtlpriv = rtl_priv(hw);
80 u32 blockSize = REALTEK_USB_VENQT_MAX_BUF_SIZE - 20;
81 u8 *bufferPtr = (u8 *) buffer;
82 u32 i, offset, blockCount, remainSize;
84 blockCount = size / blockSize;
85 remainSize = size % blockSize;
87 for (i = 0; i < blockCount; i++) {
88 offset = i * blockSize;
89 rtlpriv->io.writeN_sync(rtlpriv,
90 (FW_8192C_START_ADDRESS + offset),
91 (void *)(bufferPtr + offset),
96 offset = blockCount * blockSize;
97 rtlpriv->io.writeN_sync(rtlpriv,
98 (FW_8192C_START_ADDRESS + offset),
99 (void *)(bufferPtr + offset),
104 static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
105 const u8 *buffer, u32 size)
107 struct rtl_priv *rtlpriv = rtl_priv(hw);
108 u32 blockSize = sizeof(u32);
109 u8 *bufferPtr = (u8 *) buffer;
110 u32 *pu4BytePtr = (u32 *) buffer;
111 u32 i, offset, blockCount, remainSize;
114 if (rtlpriv->io.writeN_sync) {
115 rtl_block_fw_writeN(hw, buffer, size);
118 blockCount = size / blockSize;
119 remainSize = size % blockSize;
121 /* the last word is < 4 bytes - pad it with zeros */
122 for (i = 0; i < 4 - remainSize; i++)
123 *(bufferPtr + size + i) = 0;
127 for (i = 0; i < blockCount; i++) {
128 offset = i * blockSize;
129 /* for big-endian platforms, the firmware data need to be byte
130 * swapped as it was read as a byte string and will be written
131 * as 32-bit dwords and byte swapped when written
133 data = le32_to_cpu(*(__le32 *)(pu4BytePtr + i));
134 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
139 static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
140 u32 page, const u8 *buffer, u32 size)
142 struct rtl_priv *rtlpriv = rtl_priv(hw);
144 u8 u8page = (u8) (page & 0x07);
146 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
148 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
149 _rtl92c_fw_block_write(hw, buffer, size);
152 static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
155 u8 remain = (u8) (fwlen % 4);
157 remain = (remain == 0) ? 0 : (4 - remain);
168 static void _rtl92c_write_fw(struct ieee80211_hw *hw,
169 enum version_8192c version, u8 *buffer, u32 size)
171 struct rtl_priv *rtlpriv = rtl_priv(hw);
172 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
173 u8 *bufferPtr = (u8 *) buffer;
175 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
177 if (IS_CHIP_VER_B(version)) {
178 u32 pageNums, remainSize;
181 if (IS_HARDWARE_TYPE_8192CE(rtlhal))
182 _rtl92c_fill_dummy(bufferPtr, &size);
184 pageNums = size / FW_8192C_PAGE_SIZE;
185 remainSize = size % FW_8192C_PAGE_SIZE;
188 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
189 ("Page numbers should not greater then 4\n"));
192 for (page = 0; page < pageNums; page++) {
193 offset = page * FW_8192C_PAGE_SIZE;
194 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
199 offset = pageNums * FW_8192C_PAGE_SIZE;
201 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
205 _rtl92c_fw_block_write(hw, buffer, size);
209 static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
211 struct rtl_priv *rtlpriv = rtl_priv(hw);
216 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
217 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
218 (!(value32 & FWDL_ChkSum_rpt)));
220 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
221 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
222 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
227 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
228 ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
230 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
231 value32 |= MCUFWDL_RDY;
232 value32 &= ~WINTINI_RDY;
233 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
238 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
239 if (value32 & WINTINI_RDY) {
240 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
241 ("Polling FW ready success!!"
242 " REG_MCUFWDL:0x%08x .\n",
247 mdelay(FW_8192C_POLLING_DELAY);
249 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
251 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
252 ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
256 int rtl92c_download_fw(struct ieee80211_hw *hw)
258 struct rtl_priv *rtlpriv = rtl_priv(hw);
259 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
260 struct rtl92c_firmware_header *pfwheader;
263 enum version_8192c version = rtlhal->version;
265 pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
266 if (!rtlhal->pfirmware)
269 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
270 pfwdata = (u8 *) rtlhal->pfirmware;
271 fwsize = rtlhal->fwsize;
273 if (IS_FW_HEADER_EXIST(pfwheader)) {
274 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
275 ("Firmware Version(%d), Signature(%#x),Size(%d)\n",
276 le16_to_cpu(pfwheader->version),
277 le16_to_cpu(pfwheader->signature),
278 (uint)sizeof(struct rtl92c_firmware_header)));
280 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
281 fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
284 _rtl92c_enable_fw_download(hw, true);
285 _rtl92c_write_fw(hw, version, pfwdata, fwsize);
286 _rtl92c_enable_fw_download(hw, false);
288 if (_rtl92c_fw_free_to_go(hw)) {
289 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
290 ("Firmware is not ready to run!\n"));
292 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
293 ("Firmware is ready to run!\n"));
298 EXPORT_SYMBOL(rtl92c_download_fw);
300 static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
302 struct rtl_priv *rtlpriv = rtl_priv(hw);
303 u8 val_hmetfr, val_mcutst_1;
306 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
307 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
309 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
314 static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
315 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
317 struct rtl_priv *rtlpriv = rtl_priv(hw);
318 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
320 u16 box_reg = 0, box_extreg = 0;
322 bool isfw_read = false;
323 bool bwrite_sucess = false;
324 u8 wait_h2c_limmit = 100;
325 u8 wait_writeh2c_limmit = 100;
326 u8 boxcontent[4], boxextcontent[2];
327 u32 h2c_waitcounter = 0;
331 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
334 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
335 if (rtlhal->h2c_setinprogress) {
336 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
337 ("H2C set in progress! Wait to set.."
338 "element_id(%d).\n", element_id));
340 while (rtlhal->h2c_setinprogress) {
341 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
344 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
345 ("Wait 100 us (%d times)...\n",
349 if (h2c_waitcounter > 1000)
351 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
354 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
356 rtlhal->h2c_setinprogress = true;
357 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
362 while (!bwrite_sucess) {
363 wait_writeh2c_limmit--;
364 if (wait_writeh2c_limmit == 0) {
365 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
366 ("Write H2C fail because no trigger "
371 boxnum = rtlhal->last_hmeboxnum;
374 box_reg = REG_HMEBOX_0;
375 box_extreg = REG_HMEBOX_EXT_0;
378 box_reg = REG_HMEBOX_1;
379 box_extreg = REG_HMEBOX_EXT_1;
382 box_reg = REG_HMEBOX_2;
383 box_extreg = REG_HMEBOX_EXT_2;
386 box_reg = REG_HMEBOX_3;
387 box_extreg = REG_HMEBOX_EXT_3;
390 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
391 ("switch case not process\n"));
395 isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
399 if (wait_h2c_limmit == 0) {
400 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
401 ("Wating too long for FW read "
402 "clear HMEBox(%d)!\n", boxnum));
408 isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
409 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
410 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
411 ("Wating for FW read clear HMEBox(%d)!!! "
412 "0x1BF = %2x\n", boxnum, u1b_tmp));
416 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
417 ("Write H2C register BOX[%d] fail!!!!! "
418 "Fw do not read.\n", boxnum));
422 memset(boxcontent, 0, sizeof(boxcontent));
423 memset(boxextcontent, 0, sizeof(boxextcontent));
424 boxcontent[0] = element_id;
425 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
426 ("Write element_id box_reg(%4x) = %2x\n",
427 box_reg, element_id));
431 boxcontent[0] &= ~(BIT(7));
432 memcpy((u8 *) (boxcontent) + 1,
435 for (idx = 0; idx < 4; idx++) {
436 rtl_write_byte(rtlpriv, box_reg + idx,
441 boxcontent[0] &= ~(BIT(7));
442 memcpy((u8 *) (boxcontent) + 1,
445 for (idx = 0; idx < 4; idx++) {
446 rtl_write_byte(rtlpriv, box_reg + idx,
451 boxcontent[0] &= ~(BIT(7));
452 memcpy((u8 *) (boxcontent) + 1,
455 for (idx = 0; idx < 4; idx++) {
456 rtl_write_byte(rtlpriv, box_reg + idx,
461 boxcontent[0] |= (BIT(7));
462 memcpy((u8 *) (boxextcontent),
464 memcpy((u8 *) (boxcontent) + 1,
467 for (idx = 0; idx < 2; idx++) {
468 rtl_write_byte(rtlpriv, box_extreg + idx,
472 for (idx = 0; idx < 4; idx++) {
473 rtl_write_byte(rtlpriv, box_reg + idx,
478 boxcontent[0] |= (BIT(7));
479 memcpy((u8 *) (boxextcontent),
481 memcpy((u8 *) (boxcontent) + 1,
484 for (idx = 0; idx < 2; idx++) {
485 rtl_write_byte(rtlpriv, box_extreg + idx,
489 for (idx = 0; idx < 4; idx++) {
490 rtl_write_byte(rtlpriv, box_reg + idx,
495 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
496 ("switch case not process\n"));
500 bwrite_sucess = true;
502 rtlhal->last_hmeboxnum = boxnum + 1;
503 if (rtlhal->last_hmeboxnum == 4)
504 rtlhal->last_hmeboxnum = 0;
506 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
507 ("pHalData->last_hmeboxnum = %d\n",
508 rtlhal->last_hmeboxnum));
511 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
512 rtlhal->h2c_setinprogress = false;
513 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
515 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
518 void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
519 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
521 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
524 if (rtlhal->fw_ready == false) {
525 RT_ASSERT(false, ("return H2C cmd because of Fw "
526 "download fail!!!\n"));
530 memset(tmp_cmdbuf, 0, 8);
531 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
532 _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
536 EXPORT_SYMBOL(rtl92c_fill_h2c_cmd);
538 void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
542 struct rtl_priv *rtlpriv = rtl_priv(hw);
544 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
545 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
547 while (u1b_tmp & BIT(2)) {
550 RT_ASSERT(false, ("8051 reset fail.\n"));
554 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
557 EXPORT_SYMBOL(rtl92c_firmware_selfreset);
559 void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
561 struct rtl_priv *rtlpriv = rtl_priv(hw);
562 u8 u1_h2c_set_pwrmode[3] = {0};
563 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
565 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
567 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
568 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
569 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
570 ppsc->reg_max_lps_awakeintvl);
572 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
573 "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
574 u1_h2c_set_pwrmode, 3);
575 rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
578 EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd);
580 static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
583 struct rtl_priv *rtlpriv = rtl_priv(hw);
584 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
585 struct rtl8192_tx_ring *ring;
586 struct rtl_tx_desc *pdesc;
588 struct sk_buff *pskb = NULL;
590 ring = &rtlpci->tx_ring[BEACON_QUEUE];
592 pskb = __skb_dequeue(&ring->queue);
596 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
598 pdesc = &ring->desc[0];
600 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
602 __skb_queue_tail(&ring->queue, skb);
604 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
606 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
611 #define BEACON_PG 0 /*->1*/
614 #define PROBERSP_PG 4 /*->5*/
616 #define TOTAL_RESERVED_PKT_LEN 768
618 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
620 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
621 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
622 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
625 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
626 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
627 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
628 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
629 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
630 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
634 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 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,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
657 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
670 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
675 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
676 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 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 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
688 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691 /* page 4 probe_resp */
692 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
693 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
694 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
695 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
696 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
697 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
698 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
699 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
700 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
701 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
702 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
706 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709 /* page 5 probe_resp */
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
721 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728 void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
730 struct rtl_priv *rtlpriv = rtl_priv(hw);
731 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
732 struct sk_buff *skb = NULL;
736 u8 u1RsvdPageLoc[3] = {0};
743 /*---------------------------------------------------------
745 ---------------------------------------------------------*/
746 beacon = &reserved_page_packet[BEACON_PG * 128];
747 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
748 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
750 /*-------------------------------------------------------
752 --------------------------------------------------------*/
753 pspoll = &reserved_page_packet[PSPOLL_PG * 128];
754 SET_80211_PS_POLL_AID(pspoll, (mac->assoc_id | 0xc000));
755 SET_80211_PS_POLL_BSSID(pspoll, mac->bssid);
756 SET_80211_PS_POLL_TA(pspoll, mac->mac_addr);
758 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
760 /*--------------------------------------------------------
762 ---------------------------------------------------------*/
763 nullfunc = &reserved_page_packet[NULL_PG * 128];
764 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
765 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
766 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
768 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
770 /*---------------------------------------------------------
772 ----------------------------------------------------------*/
773 probersp = &reserved_page_packet[PROBERSP_PG * 128];
774 SET_80211_HDR_ADDRESS1(probersp, mac->bssid);
775 SET_80211_HDR_ADDRESS2(probersp, mac->mac_addr);
776 SET_80211_HDR_ADDRESS3(probersp, mac->bssid);
778 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
780 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
782 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
783 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
784 &reserved_page_packet[0], totalpacketlen);
785 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
786 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
790 skb = dev_alloc_skb(totalpacketlen);
791 memcpy((u8 *) skb_put(skb, totalpacketlen),
792 &reserved_page_packet, totalpacketlen);
794 rtstatus = _rtl92c_cmd_send_packet(hw, skb);
800 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
801 ("Set RSVD page location to Fw.\n"));
802 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
805 rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
806 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
808 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
809 ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
811 EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt);
813 void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
815 u8 u1_joinbssrpt_parm[1] = {0};
817 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
819 rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
821 EXPORT_SYMBOL(rtl92c_set_fw_joinbss_report_cmd);