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 bool _rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv)
40 return (rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) ?
44 static void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable)
46 struct rtl_priv *rtlpriv = rtl_priv(hw);
50 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
51 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
52 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
53 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
54 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
55 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
57 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
58 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
59 /* Reserved for fw extension.
60 * 0x81[7] is used for mac0 status ,
61 * so don't write this reg here
62 * rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);*/
66 static void _rtl92d_fw_block_write(struct ieee80211_hw *hw,
67 const u8 *buffer, u32 size)
69 struct rtl_priv *rtlpriv = rtl_priv(hw);
70 u32 blocksize = sizeof(u32);
71 u8 *bufferptr = (u8 *) buffer;
72 u32 *pu4BytePtr = (u32 *) buffer;
73 u32 i, offset, blockCount, remainSize;
75 blockCount = size / blocksize;
76 remainSize = size % blocksize;
77 for (i = 0; i < blockCount; i++) {
78 offset = i * blocksize;
79 rtl_write_dword(rtlpriv, (FW_8192D_START_ADDRESS + offset),
83 offset = blockCount * blocksize;
85 for (i = 0; i < remainSize; i++) {
86 rtl_write_byte(rtlpriv, (FW_8192D_START_ADDRESS +
87 offset + i), *(bufferptr + i));
92 static void _rtl92d_fw_page_write(struct ieee80211_hw *hw,
93 u32 page, const u8 *buffer, u32 size)
95 struct rtl_priv *rtlpriv = rtl_priv(hw);
97 u8 u8page = (u8) (page & 0x07);
99 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
100 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
101 _rtl92d_fw_block_write(hw, buffer, size);
104 static void _rtl92d_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
107 u8 remain = (u8) (fwlen % 4);
109 remain = (remain == 0) ? 0 : (4 - remain);
118 static void _rtl92d_write_fw(struct ieee80211_hw *hw,
119 enum version_8192d version, u8 *buffer, u32 size)
121 struct rtl_priv *rtlpriv = rtl_priv(hw);
122 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
123 u8 *bufferPtr = buffer;
124 u32 pagenums, remainSize;
127 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
128 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
129 _rtl92d_fill_dummy(bufferPtr, &size);
130 pagenums = size / FW_8192D_PAGE_SIZE;
131 remainSize = size % FW_8192D_PAGE_SIZE;
133 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
134 "Page numbers should not greater then 8\n");
136 for (page = 0; page < pagenums; page++) {
137 offset = page * FW_8192D_PAGE_SIZE;
138 _rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
142 offset = pagenums * FW_8192D_PAGE_SIZE;
144 _rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
149 static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
151 struct rtl_priv *rtlpriv = rtl_priv(hw);
156 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
157 } while ((counter++ < FW_8192D_POLLING_TIMEOUT_COUNT) &&
158 (!(value32 & FWDL_ChkSum_rpt)));
159 if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) {
160 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
161 "chksum report faill ! REG_MCUFWDL:0x%08x\n",
165 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
166 "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32);
167 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
168 value32 |= MCUFWDL_RDY;
169 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
173 void rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
175 struct rtl_priv *rtlpriv = rtl_priv(hw);
179 /* Set (REG_HMETFR + 3) to 0x20 is reset 8051 */
180 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
181 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
182 while (u1b_tmp & BIT(2)) {
187 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
189 RT_ASSERT((delay > 0), "8051 reset failed!\n");
190 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
191 "=====> 8051 reset success (%d)\n", delay);
194 static int _rtl92d_fw_init(struct ieee80211_hw *hw)
196 struct rtl_priv *rtlpriv = rtl_priv(hw);
197 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
200 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n");
201 /* polling for FW ready */
204 if (rtlhal->interfaceindex == 0) {
205 if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
207 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
208 "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
209 rtl_read_byte(rtlpriv,
215 if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
217 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
218 "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
219 rtl_read_byte(rtlpriv,
225 } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
227 if (rtlhal->interfaceindex == 0) {
228 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
229 "Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n",
230 rtl_read_byte(rtlpriv, FW_MAC0_READY));
232 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
233 "Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n",
234 rtl_read_byte(rtlpriv, FW_MAC1_READY));
236 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
237 "Polling FW ready fail!! REG_MCUFWDL:0x%08ul\n",
238 rtl_read_dword(rtlpriv, REG_MCUFWDL));
242 int rtl92d_download_fw(struct ieee80211_hw *hw)
244 struct rtl_priv *rtlpriv = rtl_priv(hw);
245 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
250 enum version_8192d version = rtlhal->version;
253 bool fw_downloaded = false, fwdl_in_process = false;
256 if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
258 fwsize = rtlhal->fwsize;
259 pfwheader = rtlhal->pfirmware;
260 pfwdata = rtlhal->pfirmware;
261 rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
262 rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
263 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
264 "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n",
265 rtlhal->fw_version, rtlhal->fw_subversion,
266 GET_FIRMWARE_HDR_SIGNATURE(pfwheader));
267 if (IS_FW_HEADER_EXIST(pfwheader)) {
268 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
269 "Shift 32 bytes for FW header!!\n");
270 pfwdata = pfwdata + 32;
271 fwsize = fwsize - 32;
274 spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
275 fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
276 if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
277 fwdl_in_process = true;
279 fwdl_in_process = false;
281 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
283 } else if (fwdl_in_process) {
284 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
285 for (count = 0; count < 5000; count++) {
287 spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
288 fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
289 if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
290 fwdl_in_process = true;
292 fwdl_in_process = false;
293 spin_unlock_irqrestore(&globalmutex_for_fwdownload,
297 else if (!fwdl_in_process)
300 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
301 "Wait for another mac download fw\n");
303 spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
304 value = rtl_read_byte(rtlpriv, 0x1f);
306 rtl_write_byte(rtlpriv, 0x1f, value);
307 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
309 value = rtl_read_byte(rtlpriv, 0x1f);
311 rtl_write_byte(rtlpriv, 0x1f, value);
312 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
315 /* If 8051 is running in RAM code, driver should
316 * inform Fw to reset by itself, or it will cause
317 * download Fw fail.*/
319 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
320 rtl92d_firmware_selfreset(hw);
321 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
323 _rtl92d_enable_fw_download(hw, true);
324 _rtl92d_write_fw(hw, version, pfwdata, fwsize);
325 _rtl92d_enable_fw_download(hw, false);
326 spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
327 err = _rtl92d_fw_free_to_go(hw);
328 /* download fw over,clear 0x1f[5] */
329 value = rtl_read_byte(rtlpriv, 0x1f);
331 rtl_write_byte(rtlpriv, 0x1f, value);
332 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
334 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
335 "fw is not ready to run!\n");
338 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "fw is ready to run!\n");
341 err = _rtl92d_fw_init(hw);
345 static bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
347 struct rtl_priv *rtlpriv = rtl_priv(hw);
351 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
352 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
357 static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
358 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
360 struct rtl_priv *rtlpriv = rtl_priv(hw);
361 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
362 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
364 u16 box_reg = 0, box_extreg = 0;
366 bool isfw_read = false;
368 bool bwrite_sucess = false;
369 u8 wait_h2c_limmit = 100;
370 u8 wait_writeh2c_limmit = 100;
371 u8 boxcontent[4], boxextcontent[2];
372 u32 h2c_waitcounter = 0;
376 if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
377 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
378 "Return as RF is off!!!\n");
381 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
383 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
384 if (rtlhal->h2c_setinprogress) {
385 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
386 "H2C set in progress! Wait to set..element_id(%d)\n",
389 while (rtlhal->h2c_setinprogress) {
390 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
393 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
394 "Wait 100 us (%d times)...\n",
398 if (h2c_waitcounter > 1000)
401 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
404 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
406 rtlhal->h2c_setinprogress = true;
407 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
411 while (!bwrite_sucess) {
412 wait_writeh2c_limmit--;
413 if (wait_writeh2c_limmit == 0) {
414 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
415 "Write H2C fail because no trigger for FW INT!\n");
418 boxnum = rtlhal->last_hmeboxnum;
421 box_reg = REG_HMEBOX_0;
422 box_extreg = REG_HMEBOX_EXT_0;
425 box_reg = REG_HMEBOX_1;
426 box_extreg = REG_HMEBOX_EXT_1;
429 box_reg = REG_HMEBOX_2;
430 box_extreg = REG_HMEBOX_EXT_2;
433 box_reg = REG_HMEBOX_3;
434 box_extreg = REG_HMEBOX_EXT_3;
437 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
438 "switch case not processed\n");
441 isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
444 if (wait_h2c_limmit == 0) {
445 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
446 "Waiting too long for FW read clear HMEBox(%d)!\n",
451 isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
452 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
453 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
454 "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
458 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
459 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
463 memset(boxcontent, 0, sizeof(boxcontent));
464 memset(boxextcontent, 0, sizeof(boxextcontent));
465 boxcontent[0] = element_id;
466 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
467 "Write element_id box_reg(%4x) = %2x\n",
468 box_reg, element_id);
471 boxcontent[0] &= ~(BIT(7));
472 memcpy(boxcontent + 1, cmdbuffer + buf_index, 1);
473 for (idx = 0; idx < 4; idx++)
474 rtl_write_byte(rtlpriv, box_reg + idx,
478 boxcontent[0] &= ~(BIT(7));
479 memcpy(boxcontent + 1, cmdbuffer + buf_index, 2);
480 for (idx = 0; idx < 4; idx++)
481 rtl_write_byte(rtlpriv, box_reg + idx,
485 boxcontent[0] &= ~(BIT(7));
486 memcpy(boxcontent + 1, cmdbuffer + buf_index, 3);
487 for (idx = 0; idx < 4; idx++)
488 rtl_write_byte(rtlpriv, box_reg + idx,
492 boxcontent[0] |= (BIT(7));
493 memcpy(boxextcontent, cmdbuffer + buf_index, 2);
494 memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 2);
495 for (idx = 0; idx < 2; idx++)
496 rtl_write_byte(rtlpriv, box_extreg + idx,
498 for (idx = 0; idx < 4; idx++)
499 rtl_write_byte(rtlpriv, box_reg + idx,
503 boxcontent[0] |= (BIT(7));
504 memcpy(boxextcontent, cmdbuffer + buf_index, 2);
505 memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 3);
506 for (idx = 0; idx < 2; idx++)
507 rtl_write_byte(rtlpriv, box_extreg + idx,
509 for (idx = 0; idx < 4; idx++)
510 rtl_write_byte(rtlpriv, box_reg + idx,
514 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
515 "switch case not processed\n");
518 bwrite_sucess = true;
519 rtlhal->last_hmeboxnum = boxnum + 1;
520 if (rtlhal->last_hmeboxnum == 4)
521 rtlhal->last_hmeboxnum = 0;
522 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
523 "pHalData->last_hmeboxnum = %d\n",
524 rtlhal->last_hmeboxnum);
526 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
527 rtlhal->h2c_setinprogress = false;
528 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
529 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
532 void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
533 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
537 memset(tmp_cmdbuf, 0, 8);
538 memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
539 _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
543 void rtl92d_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);
550 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
551 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
552 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
553 ppsc->reg_max_lps_awakeintvl);
554 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
555 "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode",
556 u1_h2c_set_pwrmode, 3);
557 rtl92d_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
560 static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,
563 struct rtl_priv *rtlpriv = rtl_priv(hw);
564 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
565 struct rtl8192_tx_ring *ring;
566 struct rtl_tx_desc *pdesc;
569 struct sk_buff *pskb;
571 ring = &rtlpci->tx_ring[BEACON_QUEUE];
572 pskb = __skb_dequeue(&ring->queue);
574 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
575 pdesc = &ring->desc[idx];
576 /* discard output from call below */
577 rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
578 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
579 __skb_queue_tail(&ring->queue, skb);
580 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
581 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
585 #define BEACON_PG 0 /*->1 */
588 #define PROBERSP_PG 4 /*->5 */
589 #define TOTAL_RESERVED_PKT_LEN 768
591 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
593 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
594 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
595 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
598 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
599 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
600 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
601 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
602 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
603 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
607 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 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 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
630 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
643 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
648 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
649 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x00, 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 0x00, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
661 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664 /* page 4 probe_resp */
665 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
666 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
667 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
668 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
669 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
670 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
671 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
672 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
673 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
674 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
675 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
679 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682 /* page 5 probe_resp */
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,
690 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701 void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
703 struct rtl_priv *rtlpriv = rtl_priv(hw);
704 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
705 struct sk_buff *skb = NULL;
708 u8 u1RsvdPageLoc[3] = { 0 };
714 /*---------------------------------------------------------
716 ---------------------------------------------------------*/
717 beacon = &reserved_page_packet[BEACON_PG * 128];
718 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
719 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
720 /*-------------------------------------------------------
722 --------------------------------------------------------*/
723 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
724 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
725 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
726 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
727 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
728 /*--------------------------------------------------------
730 ---------------------------------------------------------*/
731 nullfunc = &reserved_page_packet[NULL_PG * 128];
732 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
733 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
734 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
735 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
736 /*---------------------------------------------------------
738 ----------------------------------------------------------*/
739 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
740 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
741 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
742 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
743 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
744 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
745 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
746 "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
747 &reserved_page_packet[0], totalpacketlen);
748 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
749 "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
751 skb = dev_alloc_skb(totalpacketlen);
755 memcpy((u8 *) skb_put(skb, totalpacketlen),
756 &reserved_page_packet, totalpacketlen);
757 rtstatus = _rtl92d_cmd_send_packet(hw, skb);
763 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
764 "Set RSVD page location to Fw\n");
765 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
766 "H2C_RSVDPAGE", u1RsvdPageLoc, 3);
767 rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,
768 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
770 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
771 "Set RSVD page location to Fw FAIL!!!!!!\n");
774 void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
776 u8 u1_joinbssrpt_parm[1] = {0};
778 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
779 rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);