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);
178
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
179
} while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
180
(!(value32 & FWDL_ChkSum_rpt)));
182
if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
183
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
184
("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
189
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
190
("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
192
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
193
value32 |= MCUFWDL_RDY;
194
value32 &= ~WINTINI_RDY;
195
rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
200
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
201
if (value32 & WINTINI_RDY) {
202
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
203
("Polling FW ready success!!"
204
" REG_MCUFWDL:0x%08x .\n",
209
mdelay(FW_8192C_POLLING_DELAY);
211
} while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
213
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
214
("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
218
int rtl92c_download_fw(struct ieee80211_hw *hw)
220
struct rtl_priv *rtlpriv = rtl_priv(hw);
221
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
222
struct rtl92c_firmware_header *pfwheader;
225
enum version_8192c version = rtlhal->version;
227
printk(KERN_INFO "rtl8192c: Loading firmware file %s\n",
228
rtlpriv->cfg->fw_name);
229
if (!rtlhal->pfirmware)
232
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
233
pfwdata = (u8 *) rtlhal->pfirmware;
234
fwsize = rtlhal->fwsize;
236
if (IS_FW_HEADER_EXIST(pfwheader)) {
237
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
238
("Firmware Version(%d), Signature(%#x),Size(%d)\n",
239
pfwheader->version, pfwheader->signature,
240
(uint)sizeof(struct rtl92c_firmware_header)));
242
pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
243
fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
246
_rtl92c_enable_fw_download(hw, true);
247
_rtl92c_write_fw(hw, version, pfwdata, fwsize);
248
_rtl92c_enable_fw_download(hw, false);
250
if (_rtl92c_fw_free_to_go(hw)) {
251
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
252
("Firmware is not ready to run!\n"));
254
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
255
("Firmware is ready to run!\n"));
260
EXPORT_SYMBOL(rtl92c_download_fw);
262
static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
264
struct rtl_priv *rtlpriv = rtl_priv(hw);
265
u8 val_hmetfr, val_mcutst_1;
268
val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
269
val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
271
if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
276
static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
277
u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
279
struct rtl_priv *rtlpriv = rtl_priv(hw);
280
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
282
u16 box_reg = 0, box_extreg = 0;
284
bool isfw_read = false;
285
bool bwrite_sucess = false;
286
u8 wait_h2c_limmit = 100;
287
u8 wait_writeh2c_limmit = 100;
288
u8 boxcontent[4], boxextcontent[2];
289
u32 h2c_waitcounter = 0;
293
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
296
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
297
if (rtlhal->h2c_setinprogress) {
298
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
299
("H2C set in progress! Wait to set.."
300
"element_id(%d).\n", element_id));
302
while (rtlhal->h2c_setinprogress) {
303
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
306
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
307
("Wait 100 us (%d times)...\n",
311
if (h2c_waitcounter > 1000)
313
spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
316
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
318
rtlhal->h2c_setinprogress = true;
319
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
324
while (!bwrite_sucess) {
325
wait_writeh2c_limmit--;
326
if (wait_writeh2c_limmit == 0) {
327
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
328
("Write H2C fail because no trigger "
333
boxnum = rtlhal->last_hmeboxnum;
336
box_reg = REG_HMEBOX_0;
337
box_extreg = REG_HMEBOX_EXT_0;
340
box_reg = REG_HMEBOX_1;
341
box_extreg = REG_HMEBOX_EXT_1;
344
box_reg = REG_HMEBOX_2;
345
box_extreg = REG_HMEBOX_EXT_2;
348
box_reg = REG_HMEBOX_3;
349
box_extreg = REG_HMEBOX_EXT_3;
352
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
353
("switch case not process\n"));
357
isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
361
if (wait_h2c_limmit == 0) {
362
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
363
("Wating too long for FW read "
364
"clear HMEBox(%d)!\n", boxnum));
370
isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
371
u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
372
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
373
("Wating for FW read clear HMEBox(%d)!!! "
374
"0x1BF = %2x\n", boxnum, u1b_tmp));
378
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
379
("Write H2C register BOX[%d] fail!!!!! "
380
"Fw do not read.\n", boxnum));
384
memset(boxcontent, 0, sizeof(boxcontent));
385
memset(boxextcontent, 0, sizeof(boxextcontent));
386
boxcontent[0] = element_id;
387
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
388
("Write element_id box_reg(%4x) = %2x\n",
389
box_reg, element_id));
393
boxcontent[0] &= ~(BIT(7));
394
memcpy((u8 *) (boxcontent) + 1,
397
for (idx = 0; idx < 4; idx++) {
398
rtl_write_byte(rtlpriv, box_reg + idx,
403
boxcontent[0] &= ~(BIT(7));
404
memcpy((u8 *) (boxcontent) + 1,
407
for (idx = 0; idx < 4; idx++) {
408
rtl_write_byte(rtlpriv, box_reg + idx,
413
boxcontent[0] &= ~(BIT(7));
414
memcpy((u8 *) (boxcontent) + 1,
417
for (idx = 0; idx < 4; idx++) {
418
rtl_write_byte(rtlpriv, box_reg + idx,
423
boxcontent[0] |= (BIT(7));
424
memcpy((u8 *) (boxextcontent),
426
memcpy((u8 *) (boxcontent) + 1,
429
for (idx = 0; idx < 2; idx++) {
430
rtl_write_byte(rtlpriv, box_extreg + idx,
434
for (idx = 0; idx < 4; idx++) {
435
rtl_write_byte(rtlpriv, box_reg + idx,
440
boxcontent[0] |= (BIT(7));
441
memcpy((u8 *) (boxextcontent),
443
memcpy((u8 *) (boxcontent) + 1,
446
for (idx = 0; idx < 2; idx++) {
447
rtl_write_byte(rtlpriv, box_extreg + idx,
451
for (idx = 0; idx < 4; idx++) {
452
rtl_write_byte(rtlpriv, box_reg + idx,
457
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
458
("switch case not process\n"));
462
bwrite_sucess = true;
464
rtlhal->last_hmeboxnum = boxnum + 1;
465
if (rtlhal->last_hmeboxnum == 4)
466
rtlhal->last_hmeboxnum = 0;
468
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
469
("pHalData->last_hmeboxnum = %d\n",
470
rtlhal->last_hmeboxnum));
473
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
474
rtlhal->h2c_setinprogress = false;
475
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
477
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
480
void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
481
u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
483
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
486
if (rtlhal->fw_ready == false) {
487
RT_ASSERT(false, ("return H2C cmd because of Fw "
488
"download fail!!!\n"));
492
memset(tmp_cmdbuf, 0, 8);
493
memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
494
_rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
498
EXPORT_SYMBOL(rtl92c_fill_h2c_cmd);
500
void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
504
struct rtl_priv *rtlpriv = rtl_priv(hw);
506
rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
507
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
509
while (u1b_tmp & BIT(2)) {
512
RT_ASSERT(false, ("8051 reset fail.\n"));
516
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
519
EXPORT_SYMBOL(rtl92c_firmware_selfreset);
521
void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
523
struct rtl_priv *rtlpriv = rtl_priv(hw);
524
u8 u1_h2c_set_pwrmode[3] = {0};
525
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
527
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
529
SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
530
SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
531
SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
532
ppsc->reg_max_lps_awakeintvl);
534
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
535
"rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
536
u1_h2c_set_pwrmode, 3);
537
rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
540
EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd);
542
static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
545
struct rtl_priv *rtlpriv = rtl_priv(hw);
546
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
547
struct rtl8192_tx_ring *ring;
548
struct rtl_tx_desc *pdesc;
551
struct sk_buff *pskb = NULL;
553
ring = &rtlpci->tx_ring[BEACON_QUEUE];
555
pskb = __skb_dequeue(&ring->queue);
559
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
561
pdesc = &ring->desc[0];
562
own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
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);