rtlwifi: Eliminate udelay calls with too large values
[deliverable/linux.git] / drivers / net / wireless / rtlwifi / rtl8192ce / fw.c
CommitLineData
0c817338
LF
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
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.
8 *
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
12 * more details.
13 *
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
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include <linux/firmware.h>
31#include "../wifi.h"
32#include "../pci.h"
33#include "../base.h"
5c405b5c
JL
34#include "reg.h"
35#include "def.h"
36#include "fw.h"
37#include "table.h"
0c817338
LF
38
39static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
40{
41 struct rtl_priv *rtlpriv = rtl_priv(hw);
42 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
43
44 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) {
45 u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
46 if (enable)
47 value32 |= MCUFWDL_EN;
48 else
49 value32 &= ~MCUFWDL_EN;
50 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
51 } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) {
52 u8 tmp;
53 if (enable) {
54
55 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
56 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
57 tmp | 0x04);
58
59 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
60 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
61
62 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
63 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
64 } else {
65
66 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
67 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
68
69 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
70 }
71 }
72}
73
74static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
75 const u8 *buffer, u32 size)
76{
77 struct rtl_priv *rtlpriv = rtl_priv(hw);
78 u32 blockSize = sizeof(u32);
79 u8 *bufferPtr = (u8 *) buffer;
80 u32 *pu4BytePtr = (u32 *) buffer;
81 u32 i, offset, blockCount, remainSize;
82
83 blockCount = size / blockSize;
84 remainSize = size % blockSize;
85
86 for (i = 0; i < blockCount; i++) {
87 offset = i * blockSize;
88 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
89 *(pu4BytePtr + i));
90 }
91
92 if (remainSize) {
93 offset = blockCount * blockSize;
94 bufferPtr += offset;
95 for (i = 0; i < remainSize; i++) {
96 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
97 offset + i), *(bufferPtr + i));
98 }
99 }
100}
101
102static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
103 u32 page, const u8 *buffer, u32 size)
104{
105 struct rtl_priv *rtlpriv = rtl_priv(hw);
106 u8 value8;
107 u8 u8page = (u8) (page & 0x07);
108
109 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
110
111 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
112 _rtl92c_fw_block_write(hw, buffer, size);
113}
114
115static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
116{
117 u32 fwlen = *pfwlen;
118 u8 remain = (u8) (fwlen % 4);
119
120 remain = (remain == 0) ? 0 : (4 - remain);
121
122 while (remain > 0) {
123 pfwbuf[fwlen] = 0;
124 fwlen++;
125 remain--;
126 }
127
128 *pfwlen = fwlen;
129}
130
131static void _rtl92c_write_fw(struct ieee80211_hw *hw,
132 enum version_8192c version, u8 *buffer, u32 size)
133{
134 struct rtl_priv *rtlpriv = rtl_priv(hw);
135 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0c817338
LF
136 u8 *bufferPtr = (u8 *) buffer;
137
138 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
139
25b2bc30 140 if (IS_CHIP_VER_B(version)) {
0c817338
LF
141 u32 pageNums, remainSize;
142 u32 page, offset;
143
25b2bc30 144 if (IS_HARDWARE_TYPE_8192CE(rtlhal))
0c817338
LF
145 _rtl92c_fill_dummy(bufferPtr, &size);
146
147 pageNums = size / FW_8192C_PAGE_SIZE;
148 remainSize = size % FW_8192C_PAGE_SIZE;
149
150 if (pageNums > 4) {
151 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
152 ("Page numbers should not greater then 4\n"));
153 }
154
155 for (page = 0; page < pageNums; page++) {
156 offset = page * FW_8192C_PAGE_SIZE;
157 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
158 FW_8192C_PAGE_SIZE);
159 }
160
161 if (remainSize) {
162 offset = pageNums * FW_8192C_PAGE_SIZE;
163 page = pageNums;
164 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
165 remainSize);
166 }
167 } else {
168 _rtl92c_fw_block_write(hw, buffer, size);
169 }
170}
171
172static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
173{
174 struct rtl_priv *rtlpriv = rtl_priv(hw);
175 int err = -EIO;
176 u32 counter = 0;
177 u32 value32;
178
179 do {
180 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
181 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
182 (!(value32 & FWDL_ChkSum_rpt)));
183
184 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
185 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
186 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
187 value32));
188 goto exit;
189 }
190
191 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
192 ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
193
194 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
195 value32 |= MCUFWDL_RDY;
196 value32 &= ~WINTINI_RDY;
197 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
198
199 counter = 0;
200
201 do {
202 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
203 if (value32 & WINTINI_RDY) {
204 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
205 ("Polling FW ready success!!"
206 " REG_MCUFWDL:0x%08x .\n",
207 value32));
208 err = 0;
209 goto exit;
210 }
211
212 mdelay(FW_8192C_POLLING_DELAY);
213
214 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
215
216 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
217 ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
218
219exit:
220 return err;
221}
222
223int rtl92c_download_fw(struct ieee80211_hw *hw)
224{
225 struct rtl_priv *rtlpriv = rtl_priv(hw);
226 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
227 struct rtl92c_firmware_header *pfwheader;
228 u8 *pfwdata;
229 u32 fwsize;
230 int err;
231 enum version_8192c version = rtlhal->version;
25b2bc30 232 const struct firmware *firmware;
0c817338 233
25b2bc30
LF
234 printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n",
235 rtlpriv->cfg->fw_name);
0c817338
LF
236 err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
237 rtlpriv->io.dev);
238 if (err) {
25b2bc30 239 printk(KERN_ERR "rtl8192cu: Firmware loading failed\n");
0c817338
LF
240 return 1;
241 }
242
243 if (firmware->size > 0x4000) {
244 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
245 ("Firmware is too big!\n"));
246 release_firmware(firmware);
247 return 1;
248 }
249
250 memcpy(rtlhal->pfirmware, firmware->data, firmware->size);
251 fwsize = firmware->size;
252 release_firmware(firmware);
253
254 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
255 pfwdata = (u8 *) rtlhal->pfirmware;
256
257 if (IS_FW_HEADER_EXIST(pfwheader)) {
258 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
259 ("Firmware Version(%d), Signature(%#x),Size(%d)\n",
260 pfwheader->version, pfwheader->signature,
261 (uint)sizeof(struct rtl92c_firmware_header)));
262
263 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
264 fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
265 }
266
267 _rtl92c_enable_fw_download(hw, true);
268 _rtl92c_write_fw(hw, version, pfwdata, fwsize);
269 _rtl92c_enable_fw_download(hw, false);
270
271 err = _rtl92c_fw_free_to_go(hw);
272 if (err) {
273 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
274 ("Firmware is not ready to run!\n"));
275 } else {
276 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
277 ("Firmware is ready to run!\n"));
278 }
279
280 return 0;
281}
282
283static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
284{
285 struct rtl_priv *rtlpriv = rtl_priv(hw);
286 u8 val_hmetfr, val_mcutst_1;
287 bool result = false;
288
289 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
290 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
291
292 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
293 result = true;
294 return result;
295}
296
297static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
298 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
299{
300 struct rtl_priv *rtlpriv = rtl_priv(hw);
301 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
302 u8 boxnum;
303 u16 box_reg, box_extreg;
304 u8 u1b_tmp;
305 bool isfw_read = false;
306 u8 buf_index;
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;
312 unsigned long flag;
313 u8 idx;
314
315 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
316
317 while (true) {
318 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
7ea47240 319 if (rtlhal->h2c_setinprogress) {
0c817338
LF
320 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
321 ("H2C set in progress! Wait to set.."
322 "element_id(%d).\n", element_id));
323
7ea47240 324 while (rtlhal->h2c_setinprogress) {
0c817338
LF
325 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
326 flag);
327 h2c_waitcounter++;
328 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
329 ("Wait 100 us (%d times)...\n",
330 h2c_waitcounter));
331 udelay(100);
332
333 if (h2c_waitcounter > 1000)
334 return;
335 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
336 flag);
337 }
338 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
339 } else {
7ea47240 340 rtlhal->h2c_setinprogress = true;
0c817338
LF
341 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
342 break;
343 }
344 }
345
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 "
351 "for FW INT!\n"));
352 break;
353 }
354
355 boxnum = rtlhal->last_hmeboxnum;
356 switch (boxnum) {
357 case 0:
358 box_reg = REG_HMEBOX_0;
359 box_extreg = REG_HMEBOX_EXT_0;
360 break;
361 case 1:
362 box_reg = REG_HMEBOX_1;
363 box_extreg = REG_HMEBOX_EXT_1;
364 break;
365 case 2:
366 box_reg = REG_HMEBOX_2;
367 box_extreg = REG_HMEBOX_EXT_2;
368 break;
369 case 3:
370 box_reg = REG_HMEBOX_3;
371 box_extreg = REG_HMEBOX_EXT_3;
372 break;
373 default:
374 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
375 ("switch case not process\n"));
376 break;
377 }
378
379 isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
380 while (!isfw_read) {
381
382 wait_h2c_limmit--;
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));
387 break;
388 }
389
390 udelay(10);
391
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));
397 }
398
399 if (!isfw_read) {
400 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
401 ("Write H2C register BOX[%d] fail!!!!! "
402 "Fw do not read.\n", boxnum));
403 break;
404 }
405
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));
412
413 switch (cmd_len) {
414 case 1:
415 boxcontent[0] &= ~(BIT(7));
416 memcpy((u8 *) (boxcontent) + 1,
417 p_cmdbuffer + buf_index, 1);
418
419 for (idx = 0; idx < 4; idx++) {
420 rtl_write_byte(rtlpriv, box_reg + idx,
421 boxcontent[idx]);
422 }
423 break;
424 case 2:
425 boxcontent[0] &= ~(BIT(7));
426 memcpy((u8 *) (boxcontent) + 1,
427 p_cmdbuffer + buf_index, 2);
428
429 for (idx = 0; idx < 4; idx++) {
430 rtl_write_byte(rtlpriv, box_reg + idx,
431 boxcontent[idx]);
432 }
433 break;
434 case 3:
435 boxcontent[0] &= ~(BIT(7));
436 memcpy((u8 *) (boxcontent) + 1,
437 p_cmdbuffer + buf_index, 3);
438
439 for (idx = 0; idx < 4; idx++) {
440 rtl_write_byte(rtlpriv, box_reg + idx,
441 boxcontent[idx]);
442 }
443 break;
444 case 4:
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);
450
451 for (idx = 0; idx < 2; idx++) {
452 rtl_write_byte(rtlpriv, box_extreg + idx,
453 boxextcontent[idx]);
454 }
455
456 for (idx = 0; idx < 4; idx++) {
457 rtl_write_byte(rtlpriv, box_reg + idx,
458 boxcontent[idx]);
459 }
460 break;
461 case 5:
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);
467
468 for (idx = 0; idx < 2; idx++) {
469 rtl_write_byte(rtlpriv, box_extreg + idx,
470 boxextcontent[idx]);
471 }
472
473 for (idx = 0; idx < 4; idx++) {
474 rtl_write_byte(rtlpriv, box_reg + idx,
475 boxcontent[idx]);
476 }
477 break;
478 default:
479 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
480 ("switch case not process\n"));
481 break;
482 }
483
484 bwrite_sucess = true;
485
486 rtlhal->last_hmeboxnum = boxnum + 1;
487 if (rtlhal->last_hmeboxnum == 4)
488 rtlhal->last_hmeboxnum = 0;
489
490 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
491 ("pHalData->last_hmeboxnum = %d\n",
492 rtlhal->last_hmeboxnum));
493 }
494
495 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
7ea47240 496 rtlhal->h2c_setinprogress = false;
0c817338
LF
497 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
498
499 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
500}
501
502void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
503 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
504{
505 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
506 u32 tmp_cmdbuf[2];
507
7ea47240 508 if (rtlhal->fw_ready == false) {
0c817338
LF
509 RT_ASSERT(false, ("return H2C cmd because of Fw "
510 "download fail!!!\n"));
511 return;
512 }
513
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);
517
518 return;
519}
520
521void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
522{
523 u8 u1b_tmp;
524 u8 delay = 100;
525 struct rtl_priv *rtlpriv = rtl_priv(hw);
526
527 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
528 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
529
530 while (u1b_tmp & BIT(2)) {
531 delay--;
532 if (delay == 0) {
533 RT_ASSERT(false, ("8051 reset fail.\n"));
534 break;
535 }
536 udelay(50);
537 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
538 }
539}
540
541void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
542{
543 struct rtl_priv *rtlpriv = rtl_priv(hw);
544 u8 u1_h2c_set_pwrmode[3] = {0};
545 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
546
547 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
548
549 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
550 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
551 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
552 ppsc->reg_max_lps_awakeintvl);
553
554 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
555 "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
556 u1_h2c_set_pwrmode, 3);
557 rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
558
559}
560
0c817338
LF
561#define BEACON_PG 0 /*->1*/
562#define PSPOLL_PG 2
563#define NULL_PG 3
564#define PROBERSP_PG 4 /*->5*/
565
566#define TOTAL_RESERVED_PKT_LEN 768
567
568static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
569 /* page 0 beacon */
570 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
571 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
572 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
575 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
576 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
577 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
578 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
579 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
580 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
584 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586
587 /* page 1 beacon */
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 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 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604
605 /* page 2 ps-poll */
606 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
607 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
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 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 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
620 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622
623 /* page 3 null */
624 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
625 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
626 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 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 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 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
638 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640
641 /* page 4 probe_resp */
642 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
643 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
644 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
645 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
646 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
647 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
648 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
649 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
650 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
651 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
652 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
656 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658
659 /* page 5 probe_resp */
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 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};
677
678void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
679{
680 struct rtl_priv *rtlpriv = rtl_priv(hw);
681 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
682 struct sk_buff *skb = NULL;
683
684 u32 totalpacketlen;
685 bool rtstatus;
686 u8 u1RsvdPageLoc[3] = {0};
687 bool b_dlok = false;
688
689 u8 *beacon;
690 u8 *p_pspoll;
691 u8 *nullfunc;
692 u8 *p_probersp;
693 /*---------------------------------------------------------
694 (1) beacon
695 ---------------------------------------------------------*/
696 beacon = &reserved_page_packet[BEACON_PG * 128];
697 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
698 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
699
700 /*-------------------------------------------------------
701 (2) ps-poll
702 --------------------------------------------------------*/
703 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
704 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
705 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
706 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
707
708 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
709
710 /*--------------------------------------------------------
711 (3) null data
712 ---------------------------------------------------------*/
713 nullfunc = &reserved_page_packet[NULL_PG * 128];
714 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
715 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
716 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
717
718 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
719
720 /*---------------------------------------------------------
721 (4) probe response
722 ----------------------------------------------------------*/
723 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
724 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
725 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
726 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
727
728 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
729
730 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
731
732 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
733 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
734 &reserved_page_packet[0], totalpacketlen);
735 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
736 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
737 u1RsvdPageLoc, 3);
738
739
740 skb = dev_alloc_skb(totalpacketlen);
741 memcpy((u8 *) skb_put(skb, totalpacketlen),
742 &reserved_page_packet, totalpacketlen);
743
25b2bc30 744 rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb);
0c817338
LF
745
746 if (rtstatus)
747 b_dlok = true;
748
749 if (b_dlok) {
750 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
751 ("Set RSVD page location to Fw.\n"));
752 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
753 "H2C_RSVDPAGE:\n",
754 u1RsvdPageLoc, 3);
755 rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
756 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
757 } else
758 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
759 ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
760}
761
762void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
763{
764 u8 u1_joinbssrpt_parm[1] = {0};
765
766 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
767
768 rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
769}
This page took 0.083298 seconds and 5 git commands to generate.