blob: b627151d06bbf84d6e2d2c2fbf9a5899d1fba3bd [file] [log] [blame]
Larry Finger0c817332010-12-08 11:12:31 -06001/******************************************************************************
2 *
Larry Fingerfc616852012-01-07 20:46:43 -06003 * Copyright(c) 2009-2012 Realtek Corporation.
Larry Finger0c817332010-12-08 11:12:31 -06004 *
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
Larry Finger0c817332010-12-08 11:12:31 -060030#include "../wifi.h"
31#include "../pci.h"
32#include "../base.h"
Larry Finger1472d3a2011-02-23 10:24:58 -060033#include "../rtl8192ce/reg.h"
34#include "../rtl8192ce/def.h"
35#include "fw_common.h"
Larry Fingerd273bb22012-01-27 13:59:25 -060036#include <linux/export.h>
Larry Fingerf11bbfd2012-04-13 13:57:43 -050037#include <linux/kmemleak.h>
Larry Finger0c817332010-12-08 11:12:31 -060038
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
Larry Fingerff6ff962011-11-17 12:14:43 -060074static void rtl_block_fw_writeN(struct ieee80211_hw *hw, const u8 *buffer,
75 u32 size)
76{
77 struct rtl_priv *rtlpriv = rtl_priv(hw);
78 u32 blockSize = REALTEK_USB_VENQT_MAX_BUF_SIZE - 20;
79 u8 *bufferPtr = (u8 *) buffer;
80 u32 i, offset, blockCount, remainSize;
81
82 blockCount = size / blockSize;
83 remainSize = size % blockSize;
84
85 for (i = 0; i < blockCount; i++) {
86 offset = i * blockSize;
87 rtlpriv->io.writeN_sync(rtlpriv,
88 (FW_8192C_START_ADDRESS + offset),
89 (void *)(bufferPtr + offset),
90 blockSize);
91 }
92
93 if (remainSize) {
94 offset = blockCount * blockSize;
95 rtlpriv->io.writeN_sync(rtlpriv,
96 (FW_8192C_START_ADDRESS + offset),
97 (void *)(bufferPtr + offset),
98 remainSize);
99 }
100}
101
Larry Finger0c817332010-12-08 11:12:31 -0600102static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
103 const u8 *buffer, u32 size)
104{
105 struct rtl_priv *rtlpriv = rtl_priv(hw);
106 u32 blockSize = sizeof(u32);
107 u8 *bufferPtr = (u8 *) buffer;
108 u32 *pu4BytePtr = (u32 *) buffer;
109 u32 i, offset, blockCount, remainSize;
Larry Fingerabfabc92011-11-17 12:14:44 -0600110 u32 data;
Larry Finger0c817332010-12-08 11:12:31 -0600111
Larry Fingerff6ff962011-11-17 12:14:43 -0600112 if (rtlpriv->io.writeN_sync) {
113 rtl_block_fw_writeN(hw, buffer, size);
114 return;
115 }
Larry Finger0c817332010-12-08 11:12:31 -0600116 blockCount = size / blockSize;
117 remainSize = size % blockSize;
Larry Fingerabfabc92011-11-17 12:14:44 -0600118 if (remainSize) {
119 /* the last word is < 4 bytes - pad it with zeros */
120 for (i = 0; i < 4 - remainSize; i++)
121 *(bufferPtr + size + i) = 0;
122 blockCount++;
123 }
Larry Finger0c817332010-12-08 11:12:31 -0600124
125 for (i = 0; i < blockCount; i++) {
126 offset = i * blockSize;
Larry Fingerabfabc92011-11-17 12:14:44 -0600127 /* for big-endian platforms, the firmware data need to be byte
128 * swapped as it was read as a byte string and will be written
129 * as 32-bit dwords and byte swapped when written
130 */
131 data = le32_to_cpu(*(__le32 *)(pu4BytePtr + i));
Larry Finger0c817332010-12-08 11:12:31 -0600132 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
Larry Fingerabfabc92011-11-17 12:14:44 -0600133 data);
Larry Finger0c817332010-12-08 11:12:31 -0600134 }
135}
136
137static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
138 u32 page, const u8 *buffer, u32 size)
139{
140 struct rtl_priv *rtlpriv = rtl_priv(hw);
141 u8 value8;
142 u8 u8page = (u8) (page & 0x07);
143
144 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
145
146 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
147 _rtl92c_fw_block_write(hw, buffer, size);
148}
149
150static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
151{
152 u32 fwlen = *pfwlen;
153 u8 remain = (u8) (fwlen % 4);
154
155 remain = (remain == 0) ? 0 : (4 - remain);
156
157 while (remain > 0) {
158 pfwbuf[fwlen] = 0;
159 fwlen++;
160 remain--;
161 }
162
163 *pfwlen = fwlen;
164}
165
166static void _rtl92c_write_fw(struct ieee80211_hw *hw,
167 enum version_8192c version, u8 *buffer, u32 size)
168{
169 struct rtl_priv *rtlpriv = rtl_priv(hw);
170 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Joe Perches2c208892012-06-04 12:44:17 +0000171 u8 *bufferPtr = buffer;
Larry Finger0c817332010-12-08 11:12:31 -0600172
Joe Perchesf30d7502012-01-04 19:40:41 -0800173 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes\n", size);
Larry Finger0c817332010-12-08 11:12:31 -0600174
Larry Finger25b2bc32011-02-11 14:34:03 -0600175 if (IS_CHIP_VER_B(version)) {
Larry Finger0c817332010-12-08 11:12:31 -0600176 u32 pageNums, remainSize;
177 u32 page, offset;
178
Larry Finger25b2bc32011-02-11 14:34:03 -0600179 if (IS_HARDWARE_TYPE_8192CE(rtlhal))
Larry Finger0c817332010-12-08 11:12:31 -0600180 _rtl92c_fill_dummy(bufferPtr, &size);
181
182 pageNums = size / FW_8192C_PAGE_SIZE;
183 remainSize = size % FW_8192C_PAGE_SIZE;
184
185 if (pageNums > 4) {
186 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -0800187 "Page numbers should not greater then 4\n");
Larry Finger0c817332010-12-08 11:12:31 -0600188 }
189
190 for (page = 0; page < pageNums; page++) {
191 offset = page * FW_8192C_PAGE_SIZE;
192 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
193 FW_8192C_PAGE_SIZE);
194 }
195
196 if (remainSize) {
197 offset = pageNums * FW_8192C_PAGE_SIZE;
198 page = pageNums;
199 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
200 remainSize);
201 }
202 } else {
203 _rtl92c_fw_block_write(hw, buffer, size);
204 }
205}
206
207static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
208{
209 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger0c817332010-12-08 11:12:31 -0600210 u32 counter = 0;
211 u32 value32;
212
213 do {
214 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
215 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
216 (!(value32 & FWDL_ChkSum_rpt)));
217
218 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
219 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -0800220 "chksum report faill ! REG_MCUFWDL:0x%08x\n", value32);
Larry Finger32473282011-03-27 16:19:57 -0500221 return -EIO;
Larry Finger0c817332010-12-08 11:12:31 -0600222 }
223
224 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800225 "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32);
Larry Finger0c817332010-12-08 11:12:31 -0600226
227 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
228 value32 |= MCUFWDL_RDY;
229 value32 &= ~WINTINI_RDY;
230 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
231
232 counter = 0;
233
234 do {
235 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
236 if (value32 & WINTINI_RDY) {
237 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800238 "Polling FW ready success!! REG_MCUFWDL:0x%08x\n",
239 value32);
Larry Finger32473282011-03-27 16:19:57 -0500240 return 0;
Larry Finger0c817332010-12-08 11:12:31 -0600241 }
242
243 mdelay(FW_8192C_POLLING_DELAY);
244
245 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
246
247 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -0800248 "Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", value32);
Larry Finger32473282011-03-27 16:19:57 -0500249 return -EIO;
Larry Finger0c817332010-12-08 11:12:31 -0600250}
251
252int rtl92c_download_fw(struct ieee80211_hw *hw)
253{
254 struct rtl_priv *rtlpriv = rtl_priv(hw);
255 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
256 struct rtl92c_firmware_header *pfwheader;
257 u8 *pfwdata;
258 u32 fwsize;
Larry Finger0c817332010-12-08 11:12:31 -0600259 enum version_8192c version = rtlhal->version;
260
Larry Fingerb0302ab2012-01-30 09:54:49 -0600261 if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
Larry Finger0c817332010-12-08 11:12:31 -0600262 return 1;
Larry Finger0c817332010-12-08 11:12:31 -0600263
264 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
Joe Perches2c208892012-06-04 12:44:17 +0000265 pfwdata = rtlhal->pfirmware;
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500266 fwsize = rtlhal->fwsize;
Larry Finger0c817332010-12-08 11:12:31 -0600267
268 if (IS_FW_HEADER_EXIST(pfwheader)) {
269 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
Joe Perchesf30d7502012-01-04 19:40:41 -0800270 "Firmware Version(%d), Signature(%#x),Size(%d)\n",
Larry Fingerabfabc92011-11-17 12:14:44 -0600271 le16_to_cpu(pfwheader->version),
272 le16_to_cpu(pfwheader->signature),
Joe Perchesf30d7502012-01-04 19:40:41 -0800273 (uint)sizeof(struct rtl92c_firmware_header));
Larry Finger0c817332010-12-08 11:12:31 -0600274
275 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
276 fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
277 }
278
279 _rtl92c_enable_fw_download(hw, true);
280 _rtl92c_write_fw(hw, version, pfwdata, fwsize);
281 _rtl92c_enable_fw_download(hw, false);
282
Larry Finger32473282011-03-27 16:19:57 -0500283 if (_rtl92c_fw_free_to_go(hw)) {
Larry Finger0c817332010-12-08 11:12:31 -0600284 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -0800285 "Firmware is not ready to run!\n");
Larry Finger0c817332010-12-08 11:12:31 -0600286 } else {
287 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800288 "Firmware is ready to run!\n");
Larry Finger0c817332010-12-08 11:12:31 -0600289 }
290
291 return 0;
292}
Larry Finger1472d3a2011-02-23 10:24:58 -0600293EXPORT_SYMBOL(rtl92c_download_fw);
Larry Finger0c817332010-12-08 11:12:31 -0600294
295static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
296{
297 struct rtl_priv *rtlpriv = rtl_priv(hw);
298 u8 val_hmetfr, val_mcutst_1;
299 bool result = false;
300
301 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
302 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
303
304 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
305 result = true;
306 return result;
307}
308
309static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
310 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
311{
312 struct rtl_priv *rtlpriv = rtl_priv(hw);
313 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
314 u8 boxnum;
Larry Finger9f219bd2011-04-13 21:00:02 -0500315 u16 box_reg = 0, box_extreg = 0;
Larry Finger0c817332010-12-08 11:12:31 -0600316 u8 u1b_tmp;
317 bool isfw_read = false;
Larry Finger0c817332010-12-08 11:12:31 -0600318 bool bwrite_sucess = false;
319 u8 wait_h2c_limmit = 100;
320 u8 wait_writeh2c_limmit = 100;
321 u8 boxcontent[4], boxextcontent[2];
322 u32 h2c_waitcounter = 0;
323 unsigned long flag;
324 u8 idx;
325
Joe Perchesf30d7502012-01-04 19:40:41 -0800326 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
Larry Finger0c817332010-12-08 11:12:31 -0600327
328 while (true) {
329 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
Larry Finger7ea47242011-02-19 16:28:57 -0600330 if (rtlhal->h2c_setinprogress) {
Larry Finger0c817332010-12-08 11:12:31 -0600331 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800332 "H2C set in progress! Wait to set..element_id(%d)\n",
333 element_id);
Larry Finger0c817332010-12-08 11:12:31 -0600334
Larry Finger7ea47242011-02-19 16:28:57 -0600335 while (rtlhal->h2c_setinprogress) {
Larry Finger0c817332010-12-08 11:12:31 -0600336 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
337 flag);
338 h2c_waitcounter++;
339 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800340 "Wait 100 us (%d times)...\n",
341 h2c_waitcounter);
Larry Finger0c817332010-12-08 11:12:31 -0600342 udelay(100);
343
344 if (h2c_waitcounter > 1000)
345 return;
346 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
347 flag);
348 }
349 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
350 } else {
Larry Finger7ea47242011-02-19 16:28:57 -0600351 rtlhal->h2c_setinprogress = true;
Larry Finger0c817332010-12-08 11:12:31 -0600352 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
353 break;
354 }
355 }
356
357 while (!bwrite_sucess) {
358 wait_writeh2c_limmit--;
359 if (wait_writeh2c_limmit == 0) {
360 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -0800361 "Write H2C fail because no trigger for FW INT!\n");
Larry Finger0c817332010-12-08 11:12:31 -0600362 break;
363 }
364
365 boxnum = rtlhal->last_hmeboxnum;
366 switch (boxnum) {
367 case 0:
368 box_reg = REG_HMEBOX_0;
369 box_extreg = REG_HMEBOX_EXT_0;
370 break;
371 case 1:
372 box_reg = REG_HMEBOX_1;
373 box_extreg = REG_HMEBOX_EXT_1;
374 break;
375 case 2:
376 box_reg = REG_HMEBOX_2;
377 box_extreg = REG_HMEBOX_EXT_2;
378 break;
379 case 3:
380 box_reg = REG_HMEBOX_3;
381 box_extreg = REG_HMEBOX_EXT_3;
382 break;
383 default:
384 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -0800385 "switch case not processed\n");
Larry Finger0c817332010-12-08 11:12:31 -0600386 break;
387 }
388
389 isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
390 while (!isfw_read) {
391
392 wait_h2c_limmit--;
393 if (wait_h2c_limmit == 0) {
394 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800395 "Waiting too long for FW read clear HMEBox(%d)!\n",
396 boxnum);
Larry Finger0c817332010-12-08 11:12:31 -0600397 break;
398 }
399
400 udelay(10);
401
402 isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
403 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
404 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800405 "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
406 boxnum, u1b_tmp);
Larry Finger0c817332010-12-08 11:12:31 -0600407 }
408
409 if (!isfw_read) {
410 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800411 "Write H2C register BOX[%d] fail!!!!! Fw do not read\n",
412 boxnum);
Larry Finger0c817332010-12-08 11:12:31 -0600413 break;
414 }
415
416 memset(boxcontent, 0, sizeof(boxcontent));
417 memset(boxextcontent, 0, sizeof(boxextcontent));
418 boxcontent[0] = element_id;
419 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800420 "Write element_id box_reg(%4x) = %2x\n",
421 box_reg, element_id);
Larry Finger0c817332010-12-08 11:12:31 -0600422
423 switch (cmd_len) {
424 case 1:
425 boxcontent[0] &= ~(BIT(7));
426 memcpy((u8 *) (boxcontent) + 1,
Larry Finger32473282011-03-27 16:19:57 -0500427 p_cmdbuffer, 1);
Larry Finger0c817332010-12-08 11:12:31 -0600428
429 for (idx = 0; idx < 4; idx++) {
430 rtl_write_byte(rtlpriv, box_reg + idx,
431 boxcontent[idx]);
432 }
433 break;
434 case 2:
435 boxcontent[0] &= ~(BIT(7));
436 memcpy((u8 *) (boxcontent) + 1,
Larry Finger32473282011-03-27 16:19:57 -0500437 p_cmdbuffer, 2);
Larry Finger0c817332010-12-08 11:12:31 -0600438
439 for (idx = 0; idx < 4; idx++) {
440 rtl_write_byte(rtlpriv, box_reg + idx,
441 boxcontent[idx]);
442 }
443 break;
444 case 3:
445 boxcontent[0] &= ~(BIT(7));
446 memcpy((u8 *) (boxcontent) + 1,
Larry Finger32473282011-03-27 16:19:57 -0500447 p_cmdbuffer, 3);
Larry Finger0c817332010-12-08 11:12:31 -0600448
449 for (idx = 0; idx < 4; idx++) {
450 rtl_write_byte(rtlpriv, box_reg + idx,
451 boxcontent[idx]);
452 }
453 break;
454 case 4:
455 boxcontent[0] |= (BIT(7));
456 memcpy((u8 *) (boxextcontent),
Larry Finger32473282011-03-27 16:19:57 -0500457 p_cmdbuffer, 2);
Larry Finger0c817332010-12-08 11:12:31 -0600458 memcpy((u8 *) (boxcontent) + 1,
Larry Finger32473282011-03-27 16:19:57 -0500459 p_cmdbuffer + 2, 2);
Larry Finger0c817332010-12-08 11:12:31 -0600460
461 for (idx = 0; idx < 2; idx++) {
462 rtl_write_byte(rtlpriv, box_extreg + idx,
463 boxextcontent[idx]);
464 }
465
466 for (idx = 0; idx < 4; idx++) {
467 rtl_write_byte(rtlpriv, box_reg + idx,
468 boxcontent[idx]);
469 }
470 break;
471 case 5:
472 boxcontent[0] |= (BIT(7));
473 memcpy((u8 *) (boxextcontent),
Larry Finger32473282011-03-27 16:19:57 -0500474 p_cmdbuffer, 2);
Larry Finger0c817332010-12-08 11:12:31 -0600475 memcpy((u8 *) (boxcontent) + 1,
Larry Finger32473282011-03-27 16:19:57 -0500476 p_cmdbuffer + 2, 3);
Larry Finger0c817332010-12-08 11:12:31 -0600477
478 for (idx = 0; idx < 2; idx++) {
479 rtl_write_byte(rtlpriv, box_extreg + idx,
480 boxextcontent[idx]);
481 }
482
483 for (idx = 0; idx < 4; idx++) {
484 rtl_write_byte(rtlpriv, box_reg + idx,
485 boxcontent[idx]);
486 }
487 break;
488 default:
489 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -0800490 "switch case not processed\n");
Larry Finger0c817332010-12-08 11:12:31 -0600491 break;
492 }
493
494 bwrite_sucess = true;
495
496 rtlhal->last_hmeboxnum = boxnum + 1;
497 if (rtlhal->last_hmeboxnum == 4)
498 rtlhal->last_hmeboxnum = 0;
499
500 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800501 "pHalData->last_hmeboxnum = %d\n",
502 rtlhal->last_hmeboxnum);
Larry Finger0c817332010-12-08 11:12:31 -0600503 }
504
505 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
Larry Finger7ea47242011-02-19 16:28:57 -0600506 rtlhal->h2c_setinprogress = false;
Larry Finger0c817332010-12-08 11:12:31 -0600507 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
508
Joe Perchesf30d7502012-01-04 19:40:41 -0800509 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
Larry Finger0c817332010-12-08 11:12:31 -0600510}
511
512void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
513 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
514{
Larry Finger0c817332010-12-08 11:12:31 -0600515 u32 tmp_cmdbuf[2];
516
Larry Finger0c817332010-12-08 11:12:31 -0600517 memset(tmp_cmdbuf, 0, 8);
518 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
519 _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
520
521 return;
522}
Larry Finger1472d3a2011-02-23 10:24:58 -0600523EXPORT_SYMBOL(rtl92c_fill_h2c_cmd);
Larry Finger0c817332010-12-08 11:12:31 -0600524
525void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
526{
527 u8 u1b_tmp;
528 u8 delay = 100;
529 struct rtl_priv *rtlpriv = rtl_priv(hw);
530
531 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
532 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
533
534 while (u1b_tmp & BIT(2)) {
535 delay--;
536 if (delay == 0) {
Joe Perches9d833ed2012-01-04 19:40:43 -0800537 RT_ASSERT(false, "8051 reset fail\n");
Larry Finger0c817332010-12-08 11:12:31 -0600538 break;
539 }
540 udelay(50);
541 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
542 }
543}
Larry Finger1472d3a2011-02-23 10:24:58 -0600544EXPORT_SYMBOL(rtl92c_firmware_selfreset);
Larry Finger0c817332010-12-08 11:12:31 -0600545
546void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
547{
548 struct rtl_priv *rtlpriv = rtl_priv(hw);
549 u8 u1_h2c_set_pwrmode[3] = {0};
550 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
551
Joe Perchesf30d7502012-01-04 19:40:41 -0800552 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
Larry Finger0c817332010-12-08 11:12:31 -0600553
554 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
555 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
556 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
557 ppsc->reg_max_lps_awakeintvl);
558
559 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
Joe Perchesaf086872012-01-04 19:40:40 -0800560 "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode",
Larry Finger0c817332010-12-08 11:12:31 -0600561 u1_h2c_set_pwrmode, 3);
562 rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
563
564}
Larry Finger1472d3a2011-02-23 10:24:58 -0600565EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd);
Larry Finger0c817332010-12-08 11:12:31 -0600566
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500567static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
568 struct sk_buff *skb)
569{
570 struct rtl_priv *rtlpriv = rtl_priv(hw);
571 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
572 struct rtl8192_tx_ring *ring;
573 struct rtl_tx_desc *pdesc;
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500574 unsigned long flags;
575 struct sk_buff *pskb = NULL;
576
577 ring = &rtlpci->tx_ring[BEACON_QUEUE];
578
579 pskb = __skb_dequeue(&ring->queue);
Wei Yongjun6babc282012-08-28 21:12:00 +0800580 kfree_skb(pskb);
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500581
582 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
583
584 pdesc = &ring->desc[0];
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500585
586 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
587
588 __skb_queue_tail(&ring->queue, skb);
589
590 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
591
592 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
593
594 return true;
595}
596
Larry Finger0c817332010-12-08 11:12:31 -0600597#define BEACON_PG 0 /*->1*/
598#define PSPOLL_PG 2
599#define NULL_PG 3
600#define PROBERSP_PG 4 /*->5*/
601
602#define TOTAL_RESERVED_PKT_LEN 768
603
604static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
605 /* page 0 beacon */
606 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
607 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
608 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
611 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
612 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
613 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
614 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
615 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
616 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
620 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622
623 /* page 1 beacon */
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 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 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640
641 /* page 2 ps-poll */
642 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
643 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
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 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 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
656 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658
659 /* page 3 null */
660 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
661 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
662 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 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 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
674 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676
677 /* page 4 probe_resp */
678 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
679 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
680 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
681 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
682 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
683 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
684 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
685 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
686 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
687 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
688 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
692 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694
695 /* page 5 probe_resp */
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,
699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702 0x00, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712};
713
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500714void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
Larry Finger0c817332010-12-08 11:12:31 -0600715{
716 struct rtl_priv *rtlpriv = rtl_priv(hw);
717 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
718 struct sk_buff *skb = NULL;
719
720 u32 totalpacketlen;
721 bool rtstatus;
722 u8 u1RsvdPageLoc[3] = {0};
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500723 bool dlok = false;
Larry Finger0c817332010-12-08 11:12:31 -0600724
725 u8 *beacon;
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500726 u8 *pspoll;
Larry Finger0c817332010-12-08 11:12:31 -0600727 u8 *nullfunc;
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500728 u8 *probersp;
Larry Finger0c817332010-12-08 11:12:31 -0600729 /*---------------------------------------------------------
730 (1) beacon
731 ---------------------------------------------------------*/
732 beacon = &reserved_page_packet[BEACON_PG * 128];
733 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
734 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
735
736 /*-------------------------------------------------------
737 (2) ps-poll
738 --------------------------------------------------------*/
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500739 pspoll = &reserved_page_packet[PSPOLL_PG * 128];
740 SET_80211_PS_POLL_AID(pspoll, (mac->assoc_id | 0xc000));
741 SET_80211_PS_POLL_BSSID(pspoll, mac->bssid);
742 SET_80211_PS_POLL_TA(pspoll, mac->mac_addr);
Larry Finger0c817332010-12-08 11:12:31 -0600743
744 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
745
746 /*--------------------------------------------------------
747 (3) null data
748 ---------------------------------------------------------*/
749 nullfunc = &reserved_page_packet[NULL_PG * 128];
750 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
751 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
752 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
753
754 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
755
756 /*---------------------------------------------------------
757 (4) probe response
758 ----------------------------------------------------------*/
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500759 probersp = &reserved_page_packet[PROBERSP_PG * 128];
760 SET_80211_HDR_ADDRESS1(probersp, mac->bssid);
761 SET_80211_HDR_ADDRESS2(probersp, mac->mac_addr);
762 SET_80211_HDR_ADDRESS3(probersp, mac->bssid);
Larry Finger0c817332010-12-08 11:12:31 -0600763
764 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
765
766 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
767
768 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
Joe Perchesaf086872012-01-04 19:40:40 -0800769 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
Larry Finger0c817332010-12-08 11:12:31 -0600770 &reserved_page_packet[0], totalpacketlen);
771 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
Joe Perchesaf086872012-01-04 19:40:40 -0800772 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
Larry Finger0c817332010-12-08 11:12:31 -0600773 u1RsvdPageLoc, 3);
774
775
776 skb = dev_alloc_skb(totalpacketlen);
Larry Finger76a92be2012-01-07 20:46:40 -0600777 if (!skb)
778 return;
Larry Fingerf11bbfd2012-04-13 13:57:43 -0500779 kmemleak_not_leak(skb);
780
Larry Finger0c817332010-12-08 11:12:31 -0600781 memcpy((u8 *) skb_put(skb, totalpacketlen),
782 &reserved_page_packet, totalpacketlen);
783
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500784 rtstatus = _rtl92c_cmd_send_packet(hw, skb);
Larry Finger0c817332010-12-08 11:12:31 -0600785
786 if (rtstatus)
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500787 dlok = true;
Larry Finger0c817332010-12-08 11:12:31 -0600788
Chaoming_Li3ac5e262011-04-25 12:53:40 -0500789 if (dlok) {
Larry Finger0c817332010-12-08 11:12:31 -0600790 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800791 "Set RSVD page location to Fw\n");
Larry Finger0c817332010-12-08 11:12:31 -0600792 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
Joe Perchesaf086872012-01-04 19:40:40 -0800793 "H2C_RSVDPAGE", u1RsvdPageLoc, 3);
Larry Finger0c817332010-12-08 11:12:31 -0600794 rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
795 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
796 } else
797 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Joe Perchesf30d7502012-01-04 19:40:41 -0800798 "Set RSVD page location to Fw FAIL!!!!!!\n");
Larry Finger0c817332010-12-08 11:12:31 -0600799}
Larry Finger1472d3a2011-02-23 10:24:58 -0600800EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt);
Larry Finger0c817332010-12-08 11:12:31 -0600801
802void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
803{
804 u8 u1_joinbssrpt_parm[1] = {0};
805
806 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
807
808 rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
809}
Larry Finger1472d3a2011-02-23 10:24:58 -0600810EXPORT_SYMBOL(rtl92c_set_fw_joinbss_report_cmd);