~ubuntu-branches/ubuntu/trusty/linux-backports-modules-3.2.0/trusty

« back to all changes in this revision

Viewing changes to updates/cw-3.3/drivers/net/wireless/rtlwifi/rtl8192de/fw.c

  • Committer: Package Import Robot
  • Author(s): Leann Ogasawara
  • Date: 2012-02-15 08:42:08 UTC
  • Revision ID: package-import@ubuntu.com-20120215084208-2gcs2zosufz014pi
Tags: 3.2.0-18.1
* Open Precise LBM
* Add compat-wireless v3.3
* Consolidated amd64 server flavour into generic
* Remove lpia control file
* Update Vcs-Git to ubuntu-preicse-lbm

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "../wifi.h"
 
31
#include "../pci.h"
 
32
#include "../base.h"
 
33
#include "reg.h"
 
34
#include "def.h"
 
35
#include "fw.h"
 
36
#include "sw.h"
 
37
 
 
38
static bool _rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv)
 
39
{
 
40
        return (rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) ?
 
41
                true : false;
 
42
}
 
43
 
 
44
static void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable)
 
45
{
 
46
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
47
        u8 tmp;
 
48
 
 
49
        if (enable) {
 
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);
 
56
        } else {
 
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);*/
 
63
        }
 
64
}
 
65
 
 
66
static void _rtl92d_fw_block_write(struct ieee80211_hw *hw,
 
67
                                   const u8 *buffer, u32 size)
 
68
{
 
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;
 
74
 
 
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),
 
80
                                *(pu4BytePtr + i));
 
81
        }
 
82
        if (remainSize) {
 
83
                offset = blockCount * blocksize;
 
84
                bufferptr += offset;
 
85
                for (i = 0; i < remainSize; i++) {
 
86
                        rtl_write_byte(rtlpriv, (FW_8192D_START_ADDRESS +
 
87
                                                 offset + i), *(bufferptr + i));
 
88
                }
 
89
        }
 
90
}
 
91
 
 
92
static void _rtl92d_fw_page_write(struct ieee80211_hw *hw,
 
93
                                  u32 page, const u8 *buffer, u32 size)
 
94
{
 
95
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
96
        u8 value8;
 
97
        u8 u8page = (u8) (page & 0x07);
 
98
 
 
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);
 
102
}
 
103
 
 
104
static void _rtl92d_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
 
105
{
 
106
        u32 fwlen = *pfwlen;
 
107
        u8 remain = (u8) (fwlen % 4);
 
108
 
 
109
        remain = (remain == 0) ? 0 : (4 - remain);
 
110
        while (remain > 0) {
 
111
                pfwbuf[fwlen] = 0;
 
112
                fwlen++;
 
113
                remain--;
 
114
        }
 
115
        *pfwlen = fwlen;
 
116
}
 
117
 
 
118
static void _rtl92d_write_fw(struct ieee80211_hw *hw,
 
119
                             enum version_8192d version, u8 *buffer, u32 size)
 
120
{
 
121
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
122
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
123
        u8 *bufferPtr = (u8 *) buffer;
 
124
        u32 pagenums, remainSize;
 
125
        u32 page, offset;
 
126
 
 
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;
 
132
        if (pagenums > 8) {
 
133
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 
134
                         ("Page numbers should not greater then 8\n"));
 
135
        }
 
136
        for (page = 0; page < pagenums; page++) {
 
137
                offset = page * FW_8192D_PAGE_SIZE;
 
138
                _rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
 
139
                                      FW_8192D_PAGE_SIZE);
 
140
        }
 
141
        if (remainSize) {
 
142
                offset = pagenums * FW_8192D_PAGE_SIZE;
 
143
                page = pagenums;
 
144
                _rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
 
145
                                      remainSize);
 
146
        }
 
147
}
 
148
 
 
149
static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
 
150
{
 
151
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
152
        u32 counter = 0;
 
153
        u32 value32;
 
154
 
 
155
        do {
 
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",
 
162
                         value32));
 
163
                return -EIO;
 
164
        }
 
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);
 
170
        return 0;
 
171
}
 
172
 
 
173
void rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
 
174
{
 
175
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
176
        u8 u1b_tmp;
 
177
        u8 delay = 100;
 
178
 
 
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)) {
 
183
                delay--;
 
184
                if (delay == 0)
 
185
                        break;
 
186
                udelay(50);
 
187
                u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
 
188
        }
 
189
        RT_ASSERT((delay > 0), ("8051 reset failed!\n"));
 
190
        RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
 
191
                 ("=====> 8051 reset success (%d) .\n", delay));
 
192
}
 
193
 
 
194
static int _rtl92d_fw_init(struct ieee80211_hw *hw)
 
195
{
 
196
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
197
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
198
        u32 counter;
 
199
 
 
200
        RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, ("FW already have download\n"));
 
201
        /* polling for FW ready */
 
202
        counter = 0;
 
203
        do {
 
204
                if (rtlhal->interfaceindex == 0) {
 
205
                        if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
 
206
                            MAC0_READY) {
 
207
                                RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
 
208
                                         ("Polling FW ready success!! "
 
209
                                         "REG_MCUFWDL: 0x%x .\n",
 
210
                                         rtl_read_byte(rtlpriv,
 
211
                                         FW_MAC0_READY)));
 
212
                                return 0;
 
213
                        }
 
214
                        udelay(5);
 
215
                } else {
 
216
                        if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
 
217
                            MAC1_READY) {
 
218
                                RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
 
219
                                         ("Polling FW ready success!! "
 
220
                                         "REG_MCUFWDL: 0x%x .\n",
 
221
                                         rtl_read_byte(rtlpriv,
 
222
                                                       FW_MAC1_READY)));
 
223
                                return 0;
 
224
                        }
 
225
                        udelay(5);
 
226
                }
 
227
        } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
 
228
 
 
229
        if (rtlhal->interfaceindex == 0) {
 
230
                RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
 
231
                         ("Polling FW ready fail!! MAC0 FW init not ready: "
 
232
                         "0x%x .\n",
 
233
                         rtl_read_byte(rtlpriv, FW_MAC0_READY)));
 
234
        } else {
 
235
                RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
 
236
                         ("Polling FW ready fail!! MAC1 FW init not ready: "
 
237
                         "0x%x .\n",
 
238
                         rtl_read_byte(rtlpriv, FW_MAC1_READY)));
 
239
        }
 
240
        RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
 
241
                 ("Polling FW ready fail!! REG_MCUFWDL:0x%08ul .\n",
 
242
                 rtl_read_dword(rtlpriv, REG_MCUFWDL)));
 
243
        return -1;
 
244
}
 
245
 
 
246
int rtl92d_download_fw(struct ieee80211_hw *hw)
 
247
{
 
248
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
249
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
250
        u8 *pfwheader;
 
251
        u8 *pfwdata;
 
252
        u32 fwsize;
 
253
        int err;
 
254
        enum version_8192d version = rtlhal->version;
 
255
        u8 value;
 
256
        u32 count;
 
257
        bool fw_downloaded = false, fwdl_in_process = false;
 
258
        unsigned long flags;
 
259
 
 
260
        if (!rtlhal->pfirmware)
 
261
                return 1;
 
262
        fwsize = rtlhal->fwsize;
 
263
        pfwheader = (u8 *) rtlhal->pfirmware;
 
264
        pfwdata = (u8 *) rtlhal->pfirmware;
 
265
        rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
 
266
        rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
 
267
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, (" FirmwareVersion(%d),"
 
268
                 "FirmwareSubVersion(%d), Signature(%#x)\n",
 
269
                 rtlhal->fw_version,    rtlhal->fw_subversion,
 
270
                 GET_FIRMWARE_HDR_SIGNATURE(pfwheader)));
 
271
        if (IS_FW_HEADER_EXIST(pfwheader)) {
 
272
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 
273
                         ("Shift 32 bytes for FW header!!\n"));
 
274
                pfwdata = pfwdata + 32;
 
275
                fwsize = fwsize - 32;
 
276
        }
 
277
 
 
278
        spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
 
279
        fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
 
280
        if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
 
281
                fwdl_in_process = true;
 
282
        else
 
283
                fwdl_in_process = false;
 
284
        if (fw_downloaded) {
 
285
                spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
 
286
                goto exit;
 
287
        } else if (fwdl_in_process) {
 
288
                spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
 
289
                for (count = 0; count < 5000; count++) {
 
290
                        udelay(500);
 
291
                        spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
 
292
                        fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
 
293
                        if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
 
294
                                fwdl_in_process = true;
 
295
                        else
 
296
                                fwdl_in_process = false;
 
297
                        spin_unlock_irqrestore(&globalmutex_for_fwdownload,
 
298
                                               flags);
 
299
                        if (fw_downloaded)
 
300
                                goto exit;
 
301
                        else if (!fwdl_in_process)
 
302
                                break;
 
303
                        else
 
304
                                RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
 
305
                                         ("Wait for another mac "
 
306
                                         "download fw\n"));
 
307
                }
 
308
                spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
 
309
                value = rtl_read_byte(rtlpriv, 0x1f);
 
310
                value |= BIT(5);
 
311
                rtl_write_byte(rtlpriv, 0x1f, value);
 
312
                spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
 
313
        } else {
 
314
                value = rtl_read_byte(rtlpriv, 0x1f);
 
315
                value |= BIT(5);
 
316
                rtl_write_byte(rtlpriv, 0x1f, value);
 
317
                spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
 
318
        }
 
319
 
 
320
        /* If 8051 is running in RAM code, driver should
 
321
         * inform Fw to reset by itself, or it will cause
 
322
         * download Fw fail.*/
 
323
        /* 8051 RAM code */
 
324
        if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
 
325
                rtl92d_firmware_selfreset(hw);
 
326
                rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
 
327
        }
 
328
        _rtl92d_enable_fw_download(hw, true);
 
329
        _rtl92d_write_fw(hw, version, pfwdata, fwsize);
 
330
        _rtl92d_enable_fw_download(hw, false);
 
331
        spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
 
332
        err = _rtl92d_fw_free_to_go(hw);
 
333
        /* download fw over,clear 0x1f[5] */
 
334
        value = rtl_read_byte(rtlpriv, 0x1f);
 
335
        value &= (~BIT(5));
 
336
        rtl_write_byte(rtlpriv, 0x1f, value);
 
337
        spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
 
338
        if (err) {
 
339
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 
340
                         ("fw is not ready to run!\n"));
 
341
                goto exit;
 
342
        } else {
 
343
                RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
 
344
                         ("fw is ready to run!\n"));
 
345
        }
 
346
exit:
 
347
        err = _rtl92d_fw_init(hw);
 
348
        return err;
 
349
}
 
350
 
 
351
static bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
 
352
{
 
353
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
354
        u8 val_hmetfr;
 
355
        bool result = false;
 
356
 
 
357
        val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
 
358
        if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
 
359
                result = true;
 
360
        return result;
 
361
}
 
362
 
 
363
static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
 
364
                              u8 element_id, u32 cmd_len, u8 *cmdbuffer)
 
365
{
 
366
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
367
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
368
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 
369
        u8 boxnum;
 
370
        u16 box_reg = 0, box_extreg = 0;
 
371
        u8 u1b_tmp;
 
372
        bool isfw_read = false;
 
373
        u8 buf_index = 0;
 
374
        bool bwrite_sucess = false;
 
375
        u8 wait_h2c_limmit = 100;
 
376
        u8 wait_writeh2c_limmit = 100;
 
377
        u8 boxcontent[4], boxextcontent[2];
 
378
        u32 h2c_waitcounter = 0;
 
379
        unsigned long flag;
 
380
        u8 idx;
 
381
 
 
382
        if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
 
383
                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 
384
                         ("Return as RF is off!!!\n"));
 
385
                return;
 
386
        }
 
387
        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
 
388
        while (true) {
 
389
                spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
 
390
                if (rtlhal->h2c_setinprogress) {
 
391
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 
392
                                 ("H2C set in progress! Wait to set.."
 
393
                                 "element_id(%d).\n", element_id));
 
394
 
 
395
                        while (rtlhal->h2c_setinprogress) {
 
396
                                spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
 
397
                                                       flag);
 
398
                                h2c_waitcounter++;
 
399
                                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 
400
                                         ("Wait 100 us (%d times)...\n",
 
401
                                         h2c_waitcounter));
 
402
                                udelay(100);
 
403
 
 
404
                                if (h2c_waitcounter > 1000)
 
405
                                        return;
 
406
 
 
407
                                spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
 
408
                                                  flag);
 
409
                        }
 
410
                        spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
 
411
                } else {
 
412
                        rtlhal->h2c_setinprogress = true;
 
413
                        spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
 
414
                        break;
 
415
                }
 
416
        }
 
417
        while (!bwrite_sucess) {
 
418
                wait_writeh2c_limmit--;
 
419
                if (wait_writeh2c_limmit == 0) {
 
420
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 
421
                                 ("Write H2C fail because no trigger "
 
422
                                 "for FW INT!\n"));
 
423
                        break;
 
424
                }
 
425
                boxnum = rtlhal->last_hmeboxnum;
 
426
                switch (boxnum) {
 
427
                case 0:
 
428
                        box_reg = REG_HMEBOX_0;
 
429
                        box_extreg = REG_HMEBOX_EXT_0;
 
430
                        break;
 
431
                case 1:
 
432
                        box_reg = REG_HMEBOX_1;
 
433
                        box_extreg = REG_HMEBOX_EXT_1;
 
434
                        break;
 
435
                case 2:
 
436
                        box_reg = REG_HMEBOX_2;
 
437
                        box_extreg = REG_HMEBOX_EXT_2;
 
438
                        break;
 
439
                case 3:
 
440
                        box_reg = REG_HMEBOX_3;
 
441
                        box_extreg = REG_HMEBOX_EXT_3;
 
442
                        break;
 
443
                default:
 
444
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 
445
                                 ("switch case not process\n"));
 
446
                        break;
 
447
                }
 
448
                isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
 
449
                while (!isfw_read) {
 
450
                        wait_h2c_limmit--;
 
451
                        if (wait_h2c_limmit == 0) {
 
452
                                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 
453
                                         ("Wating too long for FW read "
 
454
                                         "clear HMEBox(%d)!\n", boxnum));
 
455
                                break;
 
456
                        }
 
457
                        udelay(10);
 
458
                        isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
 
459
                        u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
 
460
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 
461
                                 ("Wating for FW read clear HMEBox(%d)!!! "
 
462
                                 "0x1BF = %2x\n", boxnum, u1b_tmp));
 
463
                }
 
464
                if (!isfw_read) {
 
465
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 
466
                                 ("Write H2C register BOX[%d] fail!!!!! "
 
467
                                 "Fw do not read.\n", boxnum));
 
468
                        break;
 
469
                }
 
470
                memset(boxcontent, 0, sizeof(boxcontent));
 
471
                memset(boxextcontent, 0, sizeof(boxextcontent));
 
472
                boxcontent[0] = element_id;
 
473
                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 
474
                         ("Write element_id box_reg(%4x) = %2x\n",
 
475
                         box_reg, element_id));
 
476
                switch (cmd_len) {
 
477
                case 1:
 
478
                        boxcontent[0] &= ~(BIT(7));
 
479
                        memcpy(boxcontent + 1, cmdbuffer + buf_index, 1);
 
480
                        for (idx = 0; idx < 4; idx++)
 
481
                                rtl_write_byte(rtlpriv, box_reg + idx,
 
482
                                               boxcontent[idx]);
 
483
                        break;
 
484
                case 2:
 
485
                        boxcontent[0] &= ~(BIT(7));
 
486
                        memcpy(boxcontent + 1, cmdbuffer + buf_index, 2);
 
487
                        for (idx = 0; idx < 4; idx++)
 
488
                                rtl_write_byte(rtlpriv, box_reg + idx,
 
489
                                               boxcontent[idx]);
 
490
                        break;
 
491
                case 3:
 
492
                        boxcontent[0] &= ~(BIT(7));
 
493
                        memcpy(boxcontent + 1, cmdbuffer + buf_index, 3);
 
494
                        for (idx = 0; idx < 4; idx++)
 
495
                                rtl_write_byte(rtlpriv, box_reg + idx,
 
496
                                               boxcontent[idx]);
 
497
                        break;
 
498
                case 4:
 
499
                        boxcontent[0] |= (BIT(7));
 
500
                        memcpy(boxextcontent, cmdbuffer + buf_index, 2);
 
501
                        memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 2);
 
502
                        for (idx = 0; idx < 2; idx++)
 
503
                                rtl_write_byte(rtlpriv, box_extreg + idx,
 
504
                                               boxextcontent[idx]);
 
505
                        for (idx = 0; idx < 4; idx++)
 
506
                                rtl_write_byte(rtlpriv, box_reg + idx,
 
507
                                               boxcontent[idx]);
 
508
                        break;
 
509
                case 5:
 
510
                        boxcontent[0] |= (BIT(7));
 
511
                        memcpy(boxextcontent, cmdbuffer + buf_index, 2);
 
512
                        memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 3);
 
513
                        for (idx = 0; idx < 2; idx++)
 
514
                                rtl_write_byte(rtlpriv, box_extreg + idx,
 
515
                                               boxextcontent[idx]);
 
516
                        for (idx = 0; idx < 4; idx++)
 
517
                                rtl_write_byte(rtlpriv, box_reg + idx,
 
518
                                               boxcontent[idx]);
 
519
                        break;
 
520
                default:
 
521
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 
522
                                ("switch case not process\n"));
 
523
                        break;
 
524
                }
 
525
                bwrite_sucess = true;
 
526
                rtlhal->last_hmeboxnum = boxnum + 1;
 
527
                if (rtlhal->last_hmeboxnum == 4)
 
528
                        rtlhal->last_hmeboxnum = 0;
 
529
                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 
530
                         ("pHalData->last_hmeboxnum  = %d\n",
 
531
                          rtlhal->last_hmeboxnum));
 
532
        }
 
533
        spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
 
534
        rtlhal->h2c_setinprogress = false;
 
535
        spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
 
536
        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
 
537
}
 
538
 
 
539
void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
 
540
                         u8 element_id, u32 cmd_len, u8 *cmdbuffer)
 
541
{
 
542
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
543
        u32 tmp_cmdbuf[2];
 
544
 
 
545
        if (rtlhal->fw_ready == false) {
 
546
                RT_ASSERT(false, ("return H2C cmd because of Fw "
 
547
                                  "download fail!!!\n"));
 
548
                return;
 
549
        }
 
550
        memset(tmp_cmdbuf, 0, 8);
 
551
        memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
 
552
        _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
 
553
        return;
 
554
}
 
555
 
 
556
void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
 
557
{
 
558
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
559
        u8 u1_h2c_set_pwrmode[3] = { 0 };
 
560
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 
561
 
 
562
        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
 
563
        SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
 
564
        SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
 
565
        SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
 
566
                                              ppsc->reg_max_lps_awakeintvl);
 
567
        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
 
568
                      "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
 
569
                      u1_h2c_set_pwrmode, 3);
 
570
        rtl92d_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
 
571
}
 
572
 
 
573
static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,
 
574
                                    struct sk_buff *skb)
 
575
{
 
576
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
577
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
578
        struct rtl8192_tx_ring *ring;
 
579
        struct rtl_tx_desc *pdesc;
 
580
        u8 idx = 0;
 
581
        unsigned long flags;
 
582
        struct sk_buff *pskb;
 
583
 
 
584
        ring = &rtlpci->tx_ring[BEACON_QUEUE];
 
585
        pskb = __skb_dequeue(&ring->queue);
 
586
        if (pskb)
 
587
                kfree_skb(pskb);
 
588
        spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
 
589
        pdesc = &ring->desc[idx];
 
590
        /* discard output from call below */
 
591
        rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
 
592
        rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
 
593
        __skb_queue_tail(&ring->queue, skb);
 
594
        spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
 
595
        rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
 
596
        return true;
 
597
}
 
598
 
 
599
#define BEACON_PG               0       /*->1 */
 
600
#define PSPOLL_PG               2
 
601
#define NULL_PG                 3
 
602
#define PROBERSP_PG             4       /*->5 */
 
603
#define TOTAL_RESERVED_PKT_LEN  768
 
604
 
 
605
static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
 
606
        /* page 0 beacon */
 
607
        0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
 
608
        0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
 
609
        0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
 
610
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
611
        0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
 
612
        0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
 
613
        0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
 
614
        0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
 
615
        0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
 
616
        0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
 
617
        0x03, 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
        0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
 
621
        0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
622
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
623
 
 
624
        /* page 1 beacon */
 
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
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
637
        0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
 
638
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
639
        0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
640
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
641
 
 
642
        /* page 2  ps-poll */
 
643
        0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
 
644
        0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
 
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
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
655
        0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
 
656
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
 
657
        0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
658
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
659
 
 
660
        /* page 3  null */
 
661
        0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
 
662
        0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
 
663
        0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 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
        0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
 
674
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
 
675
        0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
676
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
677
 
 
678
        /* page 4  probe_resp */
 
679
        0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
 
680
        0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
 
681
        0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
 
682
        0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
 
683
        0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
 
684
        0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
 
685
        0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
 
686
        0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
 
687
        0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
 
688
        0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
 
689
        0x03, 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
        0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
 
693
        0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
694
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
695
 
 
696
        /* page 5  probe_resp */
 
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
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
713
};
 
714
 
 
715
void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
 
716
{
 
717
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
718
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
719
        struct sk_buff *skb = NULL;
 
720
        u32 totalpacketlen;
 
721
        bool rtstatus;
 
722
        u8 u1RsvdPageLoc[3] = { 0 };
 
723
        bool dlok = false;
 
724
        u8 *beacon;
 
725
        u8 *p_pspoll;
 
726
        u8 *nullfunc;
 
727
        u8 *p_probersp;
 
728
        /*---------------------------------------------------------
 
729
                                                (1) beacon
 
730
        ---------------------------------------------------------*/
 
731
        beacon = &reserved_page_packet[BEACON_PG * 128];
 
732
        SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
 
733
        SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
 
734
        /*-------------------------------------------------------
 
735
                                                (2) ps-poll
 
736
        --------------------------------------------------------*/
 
737
        p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
 
738
        SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
 
739
        SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
 
740
        SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
 
741
        SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
 
742
        /*--------------------------------------------------------
 
743
                                                (3) null data
 
744
        ---------------------------------------------------------*/
 
745
        nullfunc = &reserved_page_packet[NULL_PG * 128];
 
746
        SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
 
747
        SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
 
748
        SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
 
749
        SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
 
750
        /*---------------------------------------------------------
 
751
                                                (4) probe response
 
752
        ----------------------------------------------------------*/
 
753
        p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
 
754
        SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
 
755
        SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
 
756
        SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
 
757
        SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
 
758
        totalpacketlen = TOTAL_RESERVED_PKT_LEN;
 
759
        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
 
760
                      "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
 
761
                      &reserved_page_packet[0], totalpacketlen);
 
762
        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
 
763
                      "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
 
764
                      u1RsvdPageLoc, 3);
 
765
        skb = dev_alloc_skb(totalpacketlen);
 
766
        memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet,
 
767
                totalpacketlen);
 
768
        rtstatus = _rtl92d_cmd_send_packet(hw, skb);
 
769
 
 
770
        if (rtstatus)
 
771
                dlok = true;
 
772
        if (dlok) {
 
773
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 
774
                        ("Set RSVD page location to Fw.\n"));
 
775
                RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
 
776
                              "H2C_RSVDPAGE:\n", u1RsvdPageLoc, 3);
 
777
                rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,
 
778
                        sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
 
779
        } else
 
780
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 
781
                        ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
 
782
}
 
783
 
 
784
void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
 
785
{
 
786
        u8 u1_joinbssrpt_parm[1] = {0};
 
787
 
 
788
        SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
 
789
        rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
 
790
}