~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/net/wireless/rtlwifi/rtl8192cu/mac.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 *
 
3
 * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
 
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
#include <linux/module.h>
 
30
 
 
31
#include "../wifi.h"
 
32
#include "../pci.h"
 
33
#include "../usb.h"
 
34
#include "../ps.h"
 
35
#include "../cam.h"
 
36
#include "reg.h"
 
37
#include "def.h"
 
38
#include "phy.h"
 
39
#include "rf.h"
 
40
#include "dm.h"
 
41
#include "mac.h"
 
42
#include "trx.h"
 
43
 
 
44
/* macro to shorten lines */
 
45
 
 
46
#define LINK_Q  ui_link_quality
 
47
#define RX_EVM  rx_evm_percentage
 
48
#define RX_SIGQ rx_mimo_signalquality
 
49
 
 
50
 
 
51
void rtl92c_read_chip_version(struct ieee80211_hw *hw)
 
52
{
 
53
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
54
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 
55
        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 
56
        enum version_8192c chip_version = VERSION_UNKNOWN;
 
57
        u32 value32;
 
58
 
 
59
        value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
 
60
        if (value32 & TRP_VAUX_EN) {
 
61
                chip_version = (value32 & TYPE_ID) ? VERSION_TEST_CHIP_92C :
 
62
                               VERSION_TEST_CHIP_88C;
 
63
        } else {
 
64
                /* Normal mass production chip. */
 
65
                chip_version = NORMAL_CHIP;
 
66
                chip_version |= ((value32 & TYPE_ID) ? CHIP_92C : 0);
 
67
                chip_version |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0);
 
68
                /* RTL8723 with BT function. */
 
69
                chip_version |= ((value32 & BT_FUNC) ? CHIP_8723 : 0);
 
70
                if (IS_VENDOR_UMC(chip_version))
 
71
                        chip_version |= ((value32 & CHIP_VER_RTL_MASK) ?
 
72
                                         CHIP_VENDOR_UMC_B_CUT : 0);
 
73
                if (IS_92C_SERIAL(chip_version)) {
 
74
                        value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM);
 
75
                        chip_version |= ((CHIP_BONDING_IDENTIFIER(value32) ==
 
76
                                 CHIP_BONDING_92C_1T2R) ? CHIP_92C_1T2R : 0);
 
77
                } else if (IS_8723_SERIES(chip_version)) {
 
78
                        value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS);
 
79
                        chip_version |= ((value32 & RF_RL_ID) ?
 
80
                                          CHIP_8723_DRV_REV : 0);
 
81
                }
 
82
        }
 
83
        rtlhal->version  = (enum version_8192c)chip_version;
 
84
        switch (rtlhal->version) {
 
85
        case VERSION_NORMAL_TSMC_CHIP_92C_1T2R:
 
86
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
87
                 ("Chip Version ID: VERSION_B_CHIP_92C.\n"));
 
88
                break;
 
89
        case VERSION_NORMAL_TSMC_CHIP_92C:
 
90
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
91
                        ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C.\n"));
 
92
                break;
 
93
        case VERSION_NORMAL_TSMC_CHIP_88C:
 
94
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
95
                        ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C.\n"));
 
96
                break;
 
97
        case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT:
 
98
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
99
                        ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_i"
 
100
                        "92C_1T2R_A_CUT.\n"));
 
101
                break;
 
102
        case VERSION_NORMAL_UMC_CHIP_92C_A_CUT:
 
103
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
104
                        ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_"
 
105
                        "92C_A_CUT.\n"));
 
106
                break;
 
107
        case VERSION_NORMAL_UMC_CHIP_88C_A_CUT:
 
108
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
109
                        ("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
 
110
                        "_88C_A_CUT.\n"));
 
111
                break;
 
112
        case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT:
 
113
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
114
                        ("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
 
115
                        "_92C_1T2R_B_CUT.\n"));
 
116
                break;
 
117
        case VERSION_NORMAL_UMC_CHIP_92C_B_CUT:
 
118
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
119
                        ("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
 
120
                        "_92C_B_CUT.\n"));
 
121
                break;
 
122
        case VERSION_NORMAL_UMC_CHIP_88C_B_CUT:
 
123
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
124
                        ("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
 
125
                        "_88C_B_CUT.\n"));
 
126
                break;
 
127
        case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT:
 
128
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
129
                        ("Chip Version ID: VERSION_NORMA_UMC_CHIP"
 
130
                        "_8723_1T1R_A_CUT.\n"));
 
131
                break;
 
132
        case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT:
 
133
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
134
                        ("Chip Version ID: VERSION_NORMA_UMC_CHIP"
 
135
                        "_8723_1T1R_B_CUT.\n"));
 
136
                break;
 
137
        case VERSION_TEST_CHIP_92C:
 
138
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
139
                        ("Chip Version ID: VERSION_TEST_CHIP_92C.\n"));
 
140
                break;
 
141
        case VERSION_TEST_CHIP_88C:
 
142
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
143
                        ("Chip Version ID: VERSION_TEST_CHIP_88C.\n"));
 
144
                break;
 
145
        default:
 
146
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 
147
                        ("Chip Version ID: ???????????????.\n"));
 
148
                break;
 
149
        }
 
150
        if (IS_92C_SERIAL(rtlhal->version))
 
151
                rtlphy->rf_type =
 
152
                         (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R;
 
153
        else
 
154
                rtlphy->rf_type = RF_1T1R;
 
155
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 
156
                 ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
 
157
                  "RF_2T2R" : "RF_1T1R"));
 
158
        if (get_rf_type(rtlphy) == RF_1T1R)
 
159
                rtlpriv->dm.rfpath_rxenable[0] = true;
 
160
        else
 
161
                rtlpriv->dm.rfpath_rxenable[0] =
 
162
                    rtlpriv->dm.rfpath_rxenable[1] = true;
 
163
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n",
 
164
                                                rtlhal->version));
 
165
}
 
166
 
 
167
/**
 
168
 * writeLLT - LLT table write access
 
169
 * @io: io callback
 
170
 * @address: LLT logical address.
 
171
 * @data: LLT data content
 
172
 *
 
173
 * Realtek hardware access function.
 
174
 *
 
175
 */
 
176
bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
 
177
{
 
178
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
179
        bool status = true;
 
180
        long count = 0;
 
181
        u32 value = _LLT_INIT_ADDR(address) |
 
182
            _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
 
183
 
 
184
        rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
 
185
        do {
 
186
                value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
 
187
                if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
 
188
                        break;
 
189
                if (count > POLLING_LLT_THRESHOLD) {
 
190
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 
191
                                 ("Failed to polling write LLT done at"
 
192
                                 " address %d! _LLT_OP_VALUE(%x)\n",
 
193
                                 address, _LLT_OP_VALUE(value)));
 
194
                        status = false;
 
195
                        break;
 
196
                }
 
197
        } while (++count);
 
198
        return status;
 
199
}
 
200
/**
 
201
 * rtl92c_init_LLT_table - Init LLT table
 
202
 * @io: io callback
 
203
 * @boundary:
 
204
 *
 
205
 * Realtek hardware access function.
 
206
 *
 
207
 */
 
208
bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary)
 
209
{
 
210
        bool rst = true;
 
211
        u32     i;
 
212
 
 
213
        for (i = 0; i < (boundary - 1); i++) {
 
214
                rst = rtl92c_llt_write(hw, i , i + 1);
 
215
                if (true != rst) {
 
216
                        printk(KERN_ERR "===> %s #1 fail\n", __func__);
 
217
                        return rst;
 
218
                }
 
219
        }
 
220
        /* end of list */
 
221
        rst = rtl92c_llt_write(hw, (boundary - 1), 0xFF);
 
222
        if (true != rst) {
 
223
                printk(KERN_ERR "===> %s #2 fail\n", __func__);
 
224
                return rst;
 
225
        }
 
226
        /* Make the other pages as ring buffer
 
227
         * This ring buffer is used as beacon buffer if we config this MAC
 
228
         *  as two MAC transfer.
 
229
         * Otherwise used as local loopback buffer.
 
230
         */
 
231
        for (i = boundary; i < LLT_LAST_ENTRY_OF_TX_PKT_BUFFER; i++) {
 
232
                rst = rtl92c_llt_write(hw, i, (i + 1));
 
233
                if (true != rst) {
 
234
                        printk(KERN_ERR "===> %s #3 fail\n", __func__);
 
235
                        return rst;
 
236
                }
 
237
        }
 
238
        /* Let last entry point to the start entry of ring buffer */
 
239
        rst = rtl92c_llt_write(hw, LLT_LAST_ENTRY_OF_TX_PKT_BUFFER, boundary);
 
240
        if (true != rst) {
 
241
                printk(KERN_ERR "===> %s #4 fail\n", __func__);
 
242
                return rst;
 
243
        }
 
244
        return rst;
 
245
}
 
246
void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
 
247
                     u8 *p_macaddr, bool is_group, u8 enc_algo,
 
248
                     bool is_wepkey, bool clear_all)
 
249
{
 
250
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
251
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
252
        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 
253
        u8 *macaddr = p_macaddr;
 
254
        u32 entry_id = 0;
 
255
        bool is_pairwise = false;
 
256
        static u8 cam_const_addr[4][6] = {
 
257
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 
258
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
 
259
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
 
260
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
 
261
        };
 
262
        static u8 cam_const_broad[] = {
 
263
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff
 
264
        };
 
265
 
 
266
        if (clear_all) {
 
267
                u8 idx = 0;
 
268
                u8 cam_offset = 0;
 
269
                u8 clear_number = 5;
 
270
 
 
271
                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
 
272
                for (idx = 0; idx < clear_number; idx++) {
 
273
                        rtl_cam_mark_invalid(hw, cam_offset + idx);
 
274
                        rtl_cam_empty_entry(hw, cam_offset + idx);
 
275
                        if (idx < 5) {
 
276
                                memset(rtlpriv->sec.key_buf[idx], 0,
 
277
                                       MAX_KEY_LEN);
 
278
                                rtlpriv->sec.key_len[idx] = 0;
 
279
                        }
 
280
                }
 
281
        } else {
 
282
                switch (enc_algo) {
 
283
                case WEP40_ENCRYPTION:
 
284
                        enc_algo = CAM_WEP40;
 
285
                        break;
 
286
                case WEP104_ENCRYPTION:
 
287
                        enc_algo = CAM_WEP104;
 
288
                        break;
 
289
                case TKIP_ENCRYPTION:
 
290
                        enc_algo = CAM_TKIP;
 
291
                        break;
 
292
                case AESCCMP_ENCRYPTION:
 
293
                        enc_algo = CAM_AES;
 
294
                        break;
 
295
                default:
 
296
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 
297
                                ("iillegal switch case\n"));
 
298
                        enc_algo = CAM_TKIP;
 
299
                        break;
 
300
                }
 
301
                if (is_wepkey || rtlpriv->sec.use_defaultkey) {
 
302
                        macaddr = cam_const_addr[key_index];
 
303
                        entry_id = key_index;
 
304
                } else {
 
305
                        if (is_group) {
 
306
                                macaddr = cam_const_broad;
 
307
                                entry_id = key_index;
 
308
                        } else {
 
309
                                key_index = PAIRWISE_KEYIDX;
 
310
                                entry_id = CAM_PAIRWISE_KEY_POSITION;
 
311
                                is_pairwise = true;
 
312
                        }
 
313
                }
 
314
                if (rtlpriv->sec.key_len[key_index] == 0) {
 
315
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 
316
                                 ("delete one entry\n"));
 
317
                        rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
 
318
                } else {
 
319
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
 
320
                                 ("The insert KEY length is %d\n",
 
321
                                  rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
 
322
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
 
323
                                 ("The insert KEY  is %x %x\n",
 
324
                                  rtlpriv->sec.key_buf[0][0],
 
325
                                  rtlpriv->sec.key_buf[0][1]));
 
326
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 
327
                                 ("add one entry\n"));
 
328
                        if (is_pairwise) {
 
329
                                RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
 
330
                                              "Pairwiase Key content :",
 
331
                                              rtlpriv->sec.pairwise_key,
 
332
                                              rtlpriv->sec.
 
333
                                              key_len[PAIRWISE_KEYIDX]);
 
334
                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 
335
                                         ("set Pairwiase key\n"));
 
336
 
 
337
                                rtl_cam_add_one_entry(hw, macaddr, key_index,
 
338
                                                entry_id, enc_algo,
 
339
                                                CAM_CONFIG_NO_USEDK,
 
340
                                                rtlpriv->sec.
 
341
                                                key_buf[key_index]);
 
342
                        } else {
 
343
                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 
344
                                         ("set group key\n"));
 
345
                                if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 
346
                                        rtl_cam_add_one_entry(hw,
 
347
                                                rtlefuse->dev_addr,
 
348
                                                PAIRWISE_KEYIDX,
 
349
                                                CAM_PAIRWISE_KEY_POSITION,
 
350
                                                enc_algo,
 
351
                                                CAM_CONFIG_NO_USEDK,
 
352
                                                rtlpriv->sec.key_buf
 
353
                                                [entry_id]);
 
354
                                }
 
355
                                rtl_cam_add_one_entry(hw, macaddr, key_index,
 
356
                                                entry_id, enc_algo,
 
357
                                                CAM_CONFIG_NO_USEDK,
 
358
                                                rtlpriv->sec.key_buf[entry_id]);
 
359
                        }
 
360
                }
 
361
        }
 
362
}
 
363
 
 
364
u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw)
 
365
{
 
366
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
367
 
 
368
        return rtl_read_dword(rtlpriv, REG_TXDMA_STATUS);
 
369
}
 
370
 
 
371
void rtl92c_enable_interrupt(struct ieee80211_hw *hw)
 
372
{
 
373
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
374
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
375
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
376
        struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
 
377
 
 
378
        if (IS_HARDWARE_TYPE_8192CE(rtlhal)) {
 
379
                rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] &
 
380
                                0xFFFFFFFF);
 
381
                rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] &
 
382
                                0xFFFFFFFF);
 
383
                rtlpci->irq_enabled = true;
 
384
        } else {
 
385
                rtl_write_dword(rtlpriv, REG_HIMR, rtlusb->irq_mask[0] &
 
386
                                0xFFFFFFFF);
 
387
                rtl_write_dword(rtlpriv, REG_HIMRE, rtlusb->irq_mask[1] &
 
388
                                0xFFFFFFFF);
 
389
                rtlusb->irq_enabled = true;
 
390
        }
 
391
}
 
392
 
 
393
void rtl92c_init_interrupt(struct ieee80211_hw *hw)
 
394
{
 
395
         rtl92c_enable_interrupt(hw);
 
396
}
 
397
 
 
398
void rtl92c_disable_interrupt(struct ieee80211_hw *hw)
 
399
{
 
400
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
401
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
402
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
403
        struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
 
404
 
 
405
        rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
 
406
        rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
 
407
        if (IS_HARDWARE_TYPE_8192CE(rtlhal))
 
408
                rtlpci->irq_enabled = false;
 
409
        else if (IS_HARDWARE_TYPE_8192CU(rtlhal))
 
410
                rtlusb->irq_enabled = false;
 
411
}
 
412
 
 
413
void rtl92c_set_qos(struct ieee80211_hw *hw, int aci)
 
414
{
 
415
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
416
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
417
        u32 u4b_ac_param;
 
418
 
 
419
        rtl92c_dm_init_edca_turbo(hw);
 
420
        u4b_ac_param = (u32) mac->ac[aci].aifs;
 
421
        u4b_ac_param |=
 
422
            ((u32) le16_to_cpu(mac->ac[aci].cw_min) & 0xF) <<
 
423
            AC_PARAM_ECW_MIN_OFFSET;
 
424
        u4b_ac_param |=
 
425
            ((u32) le16_to_cpu(mac->ac[aci].cw_max) & 0xF) <<
 
426
            AC_PARAM_ECW_MAX_OFFSET;
 
427
        u4b_ac_param |= (u32) le16_to_cpu(mac->ac[aci].tx_op) <<
 
428
                         AC_PARAM_TXOP_OFFSET;
 
429
        RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD,
 
430
                 ("queue:%x, ac_param:%x\n", aci, u4b_ac_param));
 
431
        switch (aci) {
 
432
        case AC1_BK:
 
433
                rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param);
 
434
                break;
 
435
        case AC0_BE:
 
436
                rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param);
 
437
                break;
 
438
        case AC2_VI:
 
439
                rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param);
 
440
                break;
 
441
        case AC3_VO:
 
442
                rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param);
 
443
                break;
 
444
        default:
 
445
                RT_ASSERT(false, ("invalid aci: %d !\n", aci));
 
446
                break;
 
447
        }
 
448
}
 
449
 
 
450
/*-------------------------------------------------------------------------
 
451
 * HW MAC Address
 
452
 *-------------------------------------------------------------------------*/
 
453
void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr)
 
454
{
 
455
        u32 i;
 
456
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
457
 
 
458
        for (i = 0 ; i < ETH_ALEN ; i++)
 
459
                rtl_write_byte(rtlpriv, (REG_MACID + i), *(addr+i));
 
460
 
 
461
        RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("MAC Address: %02X-%02X-%02X-"
 
462
                "%02X-%02X-%02X\n",
 
463
                rtl_read_byte(rtlpriv, REG_MACID),
 
464
                rtl_read_byte(rtlpriv, REG_MACID+1),
 
465
                rtl_read_byte(rtlpriv, REG_MACID+2),
 
466
                rtl_read_byte(rtlpriv, REG_MACID+3),
 
467
                rtl_read_byte(rtlpriv, REG_MACID+4),
 
468
                rtl_read_byte(rtlpriv, REG_MACID+5)));
 
469
}
 
470
 
 
471
void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size)
 
472
{
 
473
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
474
        rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, size);
 
475
}
 
476
 
 
477
int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
 
478
{
 
479
        u8 value;
 
480
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
481
 
 
482
        switch (type) {
 
483
        case NL80211_IFTYPE_UNSPECIFIED:
 
484
                value = NT_NO_LINK;
 
485
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 
486
                        ("Set Network type to NO LINK!\n"));
 
487
                break;
 
488
        case NL80211_IFTYPE_ADHOC:
 
489
                value = NT_LINK_AD_HOC;
 
490
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 
491
                        ("Set Network type to Ad Hoc!\n"));
 
492
                break;
 
493
        case NL80211_IFTYPE_STATION:
 
494
                value = NT_LINK_AP;
 
495
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 
496
                        ("Set Network type to STA!\n"));
 
497
                break;
 
498
        case NL80211_IFTYPE_AP:
 
499
                value = NT_AS_AP;
 
500
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 
501
                        ("Set Network type to AP!\n"));
 
502
                break;
 
503
        default:
 
504
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 
505
                        ("Network type %d not support!\n", type));
 
506
                return -EOPNOTSUPP;
 
507
        }
 
508
        rtl_write_byte(rtlpriv, (REG_CR + 2), value);
 
509
        return 0;
 
510
}
 
511
 
 
512
void rtl92c_init_network_type(struct ieee80211_hw *hw)
 
513
{
 
514
        rtl92c_set_network_type(hw, NL80211_IFTYPE_UNSPECIFIED);
 
515
}
 
516
 
 
517
void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw)
 
518
{
 
519
        u16     value16;
 
520
        u32     value32;
 
521
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
522
 
 
523
        /* Response Rate Set */
 
524
        value32 = rtl_read_dword(rtlpriv, REG_RRSR);
 
525
        value32 &= ~RATE_BITMAP_ALL;
 
526
        value32 |= RATE_RRSR_CCK_ONLY_1M;
 
527
        rtl_write_dword(rtlpriv, REG_RRSR, value32);
 
528
        /* SIFS (used in NAV) */
 
529
        value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
 
530
        rtl_write_word(rtlpriv,  REG_SPEC_SIFS, value16);
 
531
        /* Retry Limit */
 
532
        value16 = _LRL(0x30) | _SRL(0x30);
 
533
        rtl_write_dword(rtlpriv,  REG_RL, value16);
 
534
}
 
535
 
 
536
void rtl92c_init_rate_fallback(struct ieee80211_hw *hw)
 
537
{
 
538
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
539
 
 
540
        /* Set Data Auto Rate Fallback Retry Count register. */
 
541
        rtl_write_dword(rtlpriv,  REG_DARFRC, 0x00000000);
 
542
        rtl_write_dword(rtlpriv,  REG_DARFRC+4, 0x10080404);
 
543
        rtl_write_dword(rtlpriv,  REG_RARFRC, 0x04030201);
 
544
        rtl_write_dword(rtlpriv,  REG_RARFRC+4, 0x08070605);
 
545
}
 
546
 
 
547
static void rtl92c_set_cck_sifs(struct ieee80211_hw *hw, u8 trx_sifs,
 
548
                                u8 ctx_sifs)
 
549
{
 
550
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
551
 
 
552
        rtl_write_byte(rtlpriv, REG_SIFS_CCK, trx_sifs);
 
553
        rtl_write_byte(rtlpriv, (REG_SIFS_CCK + 1), ctx_sifs);
 
554
}
 
555
 
 
556
static void rtl92c_set_ofdm_sifs(struct ieee80211_hw *hw, u8 trx_sifs,
 
557
                                 u8 ctx_sifs)
 
558
{
 
559
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
560
 
 
561
        rtl_write_byte(rtlpriv, REG_SIFS_OFDM, trx_sifs);
 
562
        rtl_write_byte(rtlpriv, (REG_SIFS_OFDM + 1), ctx_sifs);
 
563
}
 
564
 
 
565
void rtl92c_init_edca_param(struct ieee80211_hw *hw,
 
566
                            u16 queue, u16 txop, u8 cw_min, u8 cw_max, u8 aifs)
 
567
{
 
568
        /* sequence: VO, VI, BE, BK ==> the same as 92C hardware design.
 
569
         * referenc : enum nl80211_txq_q or ieee80211_set_wmm_default function.
 
570
         */
 
571
        u32 value;
 
572
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
573
 
 
574
        value = (u32)aifs;
 
575
        value |= ((u32)cw_min & 0xF) << 8;
 
576
        value |= ((u32)cw_max & 0xF) << 12;
 
577
        value |= (u32)txop << 16;
 
578
        /* 92C hardware register sequence is the same as queue number. */
 
579
        rtl_write_dword(rtlpriv, (REG_EDCA_VO_PARAM + (queue * 4)), value);
 
580
}
 
581
 
 
582
void rtl92c_init_edca(struct ieee80211_hw *hw)
 
583
{
 
584
        u16 value16;
 
585
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
586
 
 
587
        /* disable EDCCA count down, to reduce collison and retry */
 
588
        value16 = rtl_read_word(rtlpriv, REG_RD_CTRL);
 
589
        value16 |= DIS_EDCA_CNT_DWN;
 
590
        rtl_write_word(rtlpriv, REG_RD_CTRL, value16);
 
591
        /* Update SIFS timing.  ??????????
 
592
         * pHalData->SifsTime = 0x0e0e0a0a; */
 
593
        rtl92c_set_cck_sifs(hw, 0xa, 0xa);
 
594
        rtl92c_set_ofdm_sifs(hw, 0xe, 0xe);
 
595
        /* Set CCK/OFDM SIFS to be 10us. */
 
596
        rtl_write_word(rtlpriv, REG_SIFS_CCK, 0x0a0a);
 
597
        rtl_write_word(rtlpriv, REG_SIFS_OFDM, 0x1010);
 
598
        rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0204);
 
599
        rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x014004);
 
600
        /* TXOP */
 
601
        rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 0x005EA42B);
 
602
        rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0x0000A44F);
 
603
        rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x005EA324);
 
604
        rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x002FA226);
 
605
        /* PIFS */
 
606
        rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);
 
607
        /* AGGR BREAK TIME Register */
 
608
        rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
 
609
        rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
 
610
        rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x02);
 
611
        rtl_write_byte(rtlpriv, REG_ATIMWND, 0x02);
 
612
}
 
613
 
 
614
void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw)
 
615
{
 
616
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
617
 
 
618
        rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x99997631);
 
619
        rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
 
620
        /* init AMPDU aggregation number, tuning for Tx's TP, */
 
621
        rtl_write_word(rtlpriv, 0x4CA, 0x0708);
 
622
}
 
623
 
 
624
void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw, bool infra_mode)
 
625
{
 
626
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
627
 
 
628
        rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xFF);
 
629
}
 
630
 
 
631
void rtl92c_init_rdg_setting(struct ieee80211_hw *hw)
 
632
{
 
633
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
634
 
 
635
        rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xFF);
 
636
        rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200);
 
637
        rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05);
 
638
}
 
639
 
 
640
void rtl92c_init_retry_function(struct ieee80211_hw *hw)
 
641
{
 
642
        u8      value8;
 
643
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
644
 
 
645
        value8 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL);
 
646
        value8 |= EN_AMPDU_RTY_NEW;
 
647
        rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL, value8);
 
648
        /* Set ACK timeout */
 
649
        rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
 
650
}
 
651
 
 
652
void rtl92c_init_beacon_parameters(struct ieee80211_hw *hw,
 
653
                                   enum version_8192c version)
 
654
{
 
655
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
656
        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 
657
 
 
658
        rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404);/* ms */
 
659
        rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);/*ms*/
 
660
        rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME);
 
661
        if (IS_NORMAL_CHIP(rtlhal->version))
 
662
                rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F);
 
663
        else
 
664
                rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF);
 
665
}
 
666
 
 
667
void rtl92c_disable_fast_edca(struct ieee80211_hw *hw)
 
668
{
 
669
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
670
 
 
671
        rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0);
 
672
}
 
673
 
 
674
void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T)
 
675
{
 
676
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
677
        u8 value = is2T ? MAX_MSS_DENSITY_2T : MAX_MSS_DENSITY_1T;
 
678
 
 
679
        rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, value);
 
680
}
 
681
 
 
682
u16 rtl92c_get_mgt_filter(struct ieee80211_hw *hw)
 
683
{
 
684
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
685
 
 
686
        return rtl_read_word(rtlpriv, REG_RXFLTMAP0);
 
687
}
 
688
 
 
689
void rtl92c_set_mgt_filter(struct ieee80211_hw *hw, u16 filter)
 
690
{
 
691
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
692
 
 
693
        rtl_write_word(rtlpriv, REG_RXFLTMAP0, filter);
 
694
}
 
695
 
 
696
u16 rtl92c_get_ctrl_filter(struct ieee80211_hw *hw)
 
697
{
 
698
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
699
 
 
700
        return rtl_read_word(rtlpriv, REG_RXFLTMAP1);
 
701
}
 
702
 
 
703
void rtl92c_set_ctrl_filter(struct ieee80211_hw *hw, u16 filter)
 
704
{
 
705
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
706
 
 
707
        rtl_write_word(rtlpriv, REG_RXFLTMAP1, filter);
 
708
}
 
709
 
 
710
u16 rtl92c_get_data_filter(struct ieee80211_hw *hw)
 
711
{
 
712
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
713
 
 
714
        return rtl_read_word(rtlpriv,  REG_RXFLTMAP2);
 
715
}
 
716
 
 
717
void rtl92c_set_data_filter(struct ieee80211_hw *hw, u16 filter)
 
718
{
 
719
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
720
 
 
721
        rtl_write_word(rtlpriv, REG_RXFLTMAP2, filter);
 
722
}
 
723
/*==============================================================*/
 
724
 
 
725
static u8 _rtl92c_query_rxpwrpercentage(char antpower)
 
726
{
 
727
        if ((antpower <= -100) || (antpower >= 20))
 
728
                return 0;
 
729
        else if (antpower >= 0)
 
730
                return 100;
 
731
        else
 
732
                return 100 + antpower;
 
733
}
 
734
 
 
735
static u8 _rtl92c_evm_db_to_percentage(char value)
 
736
{
 
737
        char ret_val;
 
738
 
 
739
        ret_val = value;
 
740
        if (ret_val >= 0)
 
741
                ret_val = 0;
 
742
        if (ret_val <= -33)
 
743
                ret_val = -33;
 
744
        ret_val = 0 - ret_val;
 
745
        ret_val *= 3;
 
746
        if (ret_val == 99)
 
747
                ret_val = 100;
 
748
        return ret_val;
 
749
}
 
750
 
 
751
static long _rtl92c_translate_todbm(struct ieee80211_hw *hw,
 
752
                                     u8 signal_strength_index)
 
753
{
 
754
        long signal_power;
 
755
 
 
756
        signal_power = (long)((signal_strength_index + 1) >> 1);
 
757
        signal_power -= 95;
 
758
        return signal_power;
 
759
}
 
760
 
 
761
static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw,
 
762
                long currsig)
 
763
{
 
764
        long retsig;
 
765
 
 
766
        if (currsig >= 61 && currsig <= 100)
 
767
                retsig = 90 + ((currsig - 60) / 4);
 
768
        else if (currsig >= 41 && currsig <= 60)
 
769
                retsig = 78 + ((currsig - 40) / 2);
 
770
        else if (currsig >= 31 && currsig <= 40)
 
771
                retsig = 66 + (currsig - 30);
 
772
        else if (currsig >= 21 && currsig <= 30)
 
773
                retsig = 54 + (currsig - 20);
 
774
        else if (currsig >= 5 && currsig <= 20)
 
775
                retsig = 42 + (((currsig - 5) * 2) / 3);
 
776
        else if (currsig == 4)
 
777
                retsig = 36;
 
778
        else if (currsig == 3)
 
779
                retsig = 27;
 
780
        else if (currsig == 2)
 
781
                retsig = 18;
 
782
        else if (currsig == 1)
 
783
                retsig = 9;
 
784
        else
 
785
                retsig = currsig;
 
786
        return retsig;
 
787
}
 
788
 
 
789
static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,
 
790
                                      struct rtl_stats *pstats,
 
791
                                      struct rx_desc_92c *pdesc,
 
792
                                      struct rx_fwinfo_92c *p_drvinfo,
 
793
                                      bool packet_match_bssid,
 
794
                                      bool packet_toself,
 
795
                                      bool packet_beacon)
 
796
{
 
797
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
798
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 
799
        struct phy_sts_cck_8192s_t *cck_buf;
 
800
        s8 rx_pwr_all = 0, rx_pwr[4];
 
801
        u8 rf_rx_num = 0, evm, pwdb_all;
 
802
        u8 i, max_spatial_stream;
 
803
        u32 rssi, total_rssi = 0;
 
804
        bool in_powersavemode = false;
 
805
        bool is_cck_rate;
 
806
 
 
807
        is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
 
808
        pstats->packet_matchbssid = packet_match_bssid;
 
809
        pstats->packet_toself = packet_toself;
 
810
        pstats->is_cck = is_cck_rate;
 
811
        pstats->packet_beacon = packet_beacon;
 
812
        pstats->is_cck = is_cck_rate;
 
813
        pstats->RX_SIGQ[0] = -1;
 
814
        pstats->RX_SIGQ[1] = -1;
 
815
        if (is_cck_rate) {
 
816
                u8 report, cck_highpwr;
 
817
                cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
 
818
                if (!in_powersavemode)
 
819
                        cck_highpwr = rtlphy->cck_high_power;
 
820
                else
 
821
                        cck_highpwr = false;
 
822
                if (!cck_highpwr) {
 
823
                        u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 
824
                        report = cck_buf->cck_agc_rpt & 0xc0;
 
825
                        report = report >> 6;
 
826
                        switch (report) {
 
827
                        case 0x3:
 
828
                                rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
 
829
                                break;
 
830
                        case 0x2:
 
831
                                rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
 
832
                                break;
 
833
                        case 0x1:
 
834
                                rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
 
835
                                break;
 
836
                        case 0x0:
 
837
                                rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
 
838
                                break;
 
839
                        }
 
840
                } else {
 
841
                        u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 
842
                        report = p_drvinfo->cfosho[0] & 0x60;
 
843
                        report = report >> 5;
 
844
                        switch (report) {
 
845
                        case 0x3:
 
846
                                rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
 
847
                                break;
 
848
                        case 0x2:
 
849
                                rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
 
850
                                break;
 
851
                        case 0x1:
 
852
                                rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
 
853
                                break;
 
854
                        case 0x0:
 
855
                                rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
 
856
                                break;
 
857
                        }
 
858
                }
 
859
                pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
 
860
                pstats->rx_pwdb_all = pwdb_all;
 
861
                pstats->recvsignalpower = rx_pwr_all;
 
862
                if (packet_match_bssid) {
 
863
                        u8 sq;
 
864
                        if (pstats->rx_pwdb_all > 40)
 
865
                                sq = 100;
 
866
                        else {
 
867
                                sq = cck_buf->sq_rpt;
 
868
                                if (sq > 64)
 
869
                                        sq = 0;
 
870
                                else if (sq < 20)
 
871
                                        sq = 100;
 
872
                                else
 
873
                                        sq = ((64 - sq) * 100) / 44;
 
874
                        }
 
875
                        pstats->signalquality = sq;
 
876
                        pstats->RX_SIGQ[0] = sq;
 
877
                        pstats->RX_SIGQ[1] = -1;
 
878
                }
 
879
        } else {
 
880
                rtlpriv->dm.rfpath_rxenable[0] =
 
881
                    rtlpriv->dm.rfpath_rxenable[1] = true;
 
882
                for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
 
883
                        if (rtlpriv->dm.rfpath_rxenable[i])
 
884
                                rf_rx_num++;
 
885
                        rx_pwr[i] =
 
886
                            ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
 
887
                        rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
 
888
                        total_rssi += rssi;
 
889
                        rtlpriv->stats.rx_snr_db[i] =
 
890
                            (long)(p_drvinfo->rxsnr[i] / 2);
 
891
 
 
892
                        if (packet_match_bssid)
 
893
                                pstats->rx_mimo_signalstrength[i] = (u8) rssi;
 
894
                }
 
895
                rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
 
896
                pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
 
897
                pstats->rx_pwdb_all = pwdb_all;
 
898
                pstats->rxpower = rx_pwr_all;
 
899
                pstats->recvsignalpower = rx_pwr_all;
 
900
                if (GET_RX_DESC_RX_MCS(pdesc) &&
 
901
                    GET_RX_DESC_RX_MCS(pdesc) >= DESC92C_RATEMCS8 &&
 
902
                    GET_RX_DESC_RX_MCS(pdesc) <= DESC92C_RATEMCS15)
 
903
                        max_spatial_stream = 2;
 
904
                else
 
905
                        max_spatial_stream = 1;
 
906
                for (i = 0; i < max_spatial_stream; i++) {
 
907
                        evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
 
908
                        if (packet_match_bssid) {
 
909
                                if (i == 0)
 
910
                                        pstats->signalquality =
 
911
                                            (u8) (evm & 0xff);
 
912
                                pstats->RX_SIGQ[i] =
 
913
                                    (u8) (evm & 0xff);
 
914
                        }
 
915
                }
 
916
        }
 
917
        if (is_cck_rate)
 
918
                pstats->signalstrength =
 
919
                    (u8) (_rtl92c_signal_scale_mapping(hw, pwdb_all));
 
920
        else if (rf_rx_num != 0)
 
921
                pstats->signalstrength =
 
922
                    (u8) (_rtl92c_signal_scale_mapping
 
923
                          (hw, total_rssi /= rf_rx_num));
 
924
}
 
925
 
 
926
static void _rtl92c_process_ui_rssi(struct ieee80211_hw *hw,
 
927
                struct rtl_stats *pstats)
 
928
{
 
929
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
930
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 
931
        u8 rfpath;
 
932
        u32 last_rssi, tmpval;
 
933
 
 
934
        if (pstats->packet_toself || pstats->packet_beacon) {
 
935
                rtlpriv->stats.rssi_calculate_cnt++;
 
936
                if (rtlpriv->stats.ui_rssi.total_num++ >=
 
937
                    PHY_RSSI_SLID_WIN_MAX) {
 
938
                        rtlpriv->stats.ui_rssi.total_num =
 
939
                            PHY_RSSI_SLID_WIN_MAX;
 
940
                        last_rssi =
 
941
                            rtlpriv->stats.ui_rssi.elements[rtlpriv->
 
942
                                                           stats.ui_rssi.index];
 
943
                        rtlpriv->stats.ui_rssi.total_val -= last_rssi;
 
944
                }
 
945
                rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
 
946
                rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.
 
947
                                        index++] = pstats->signalstrength;
 
948
                if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
 
949
                        rtlpriv->stats.ui_rssi.index = 0;
 
950
                tmpval = rtlpriv->stats.ui_rssi.total_val /
 
951
                    rtlpriv->stats.ui_rssi.total_num;
 
952
                rtlpriv->stats.signal_strength =
 
953
                    _rtl92c_translate_todbm(hw, (u8) tmpval);
 
954
                pstats->rssi = rtlpriv->stats.signal_strength;
 
955
        }
 
956
        if (!pstats->is_cck && pstats->packet_toself) {
 
957
                for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
 
958
                     rfpath++) {
 
959
                        if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath))
 
960
                                continue;
 
961
                        if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
 
962
                                rtlpriv->stats.rx_rssi_percentage[rfpath] =
 
963
                                    pstats->rx_mimo_signalstrength[rfpath];
 
964
                        }
 
965
                        if (pstats->rx_mimo_signalstrength[rfpath] >
 
966
                            rtlpriv->stats.rx_rssi_percentage[rfpath]) {
 
967
                                rtlpriv->stats.rx_rssi_percentage[rfpath] =
 
968
                                    ((rtlpriv->stats.
 
969
                                      rx_rssi_percentage[rfpath] *
 
970
                                      (RX_SMOOTH_FACTOR - 1)) +
 
971
                                     (pstats->rx_mimo_signalstrength[rfpath])) /
 
972
                                    (RX_SMOOTH_FACTOR);
 
973
 
 
974
                                rtlpriv->stats.rx_rssi_percentage[rfpath] =
 
975
                                    rtlpriv->stats.rx_rssi_percentage[rfpath] +
 
976
                                    1;
 
977
                        } else {
 
978
                                rtlpriv->stats.rx_rssi_percentage[rfpath] =
 
979
                                    ((rtlpriv->stats.
 
980
                                      rx_rssi_percentage[rfpath] *
 
981
                                      (RX_SMOOTH_FACTOR - 1)) +
 
982
                                     (pstats->rx_mimo_signalstrength[rfpath])) /
 
983
                                    (RX_SMOOTH_FACTOR);
 
984
                        }
 
985
                }
 
986
        }
 
987
}
 
988
 
 
989
static void _rtl92c_update_rxsignalstatistics(struct ieee80211_hw *hw,
 
990
                                               struct rtl_stats *pstats)
 
991
{
 
992
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
993
        int weighting = 0;
 
994
 
 
995
        if (rtlpriv->stats.recv_signal_power == 0)
 
996
                rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
 
997
        if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
 
998
                weighting = 5;
 
999
        else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
 
1000
                weighting = (-5);
 
1001
        rtlpriv->stats.recv_signal_power =
 
1002
            (rtlpriv->stats.recv_signal_power * 5 +
 
1003
             pstats->recvsignalpower + weighting) / 6;
 
1004
}
 
1005
 
 
1006
static void _rtl92c_process_pwdb(struct ieee80211_hw *hw,
 
1007
                struct rtl_stats *pstats)
 
1008
{
 
1009
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
1010
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
1011
        long undecorated_smoothed_pwdb = 0;
 
1012
 
 
1013
        if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 
1014
                return;
 
1015
        } else {
 
1016
                undecorated_smoothed_pwdb =
 
1017
                    rtlpriv->dm.undecorated_smoothed_pwdb;
 
1018
        }
 
1019
        if (pstats->packet_toself || pstats->packet_beacon) {
 
1020
                if (undecorated_smoothed_pwdb < 0)
 
1021
                        undecorated_smoothed_pwdb = pstats->rx_pwdb_all;
 
1022
                if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) {
 
1023
                        undecorated_smoothed_pwdb =
 
1024
                            (((undecorated_smoothed_pwdb) *
 
1025
                              (RX_SMOOTH_FACTOR - 1)) +
 
1026
                             (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
 
1027
                        undecorated_smoothed_pwdb = undecorated_smoothed_pwdb
 
1028
                            + 1;
 
1029
                } else {
 
1030
                        undecorated_smoothed_pwdb =
 
1031
                            (((undecorated_smoothed_pwdb) *
 
1032
                              (RX_SMOOTH_FACTOR - 1)) +
 
1033
                             (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
 
1034
                }
 
1035
                rtlpriv->dm.undecorated_smoothed_pwdb =
 
1036
                    undecorated_smoothed_pwdb;
 
1037
                _rtl92c_update_rxsignalstatistics(hw, pstats);
 
1038
        }
 
1039
}
 
1040
 
 
1041
static void _rtl92c_process_LINK_Q(struct ieee80211_hw *hw,
 
1042
                                             struct rtl_stats *pstats)
 
1043
{
 
1044
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
1045
        u32 last_evm = 0, n_stream, tmpval;
 
1046
 
 
1047
        if (pstats->signalquality != 0) {
 
1048
                if (pstats->packet_toself || pstats->packet_beacon) {
 
1049
                        if (rtlpriv->stats.LINK_Q.total_num++ >=
 
1050
                            PHY_LINKQUALITY_SLID_WIN_MAX) {
 
1051
                                rtlpriv->stats.LINK_Q.total_num =
 
1052
                                    PHY_LINKQUALITY_SLID_WIN_MAX;
 
1053
                                last_evm =
 
1054
                                    rtlpriv->stats.LINK_Q.elements
 
1055
                                    [rtlpriv->stats.LINK_Q.index];
 
1056
                                rtlpriv->stats.LINK_Q.total_val -=
 
1057
                                    last_evm;
 
1058
                        }
 
1059
                        rtlpriv->stats.LINK_Q.total_val +=
 
1060
                            pstats->signalquality;
 
1061
                        rtlpriv->stats.LINK_Q.elements
 
1062
                           [rtlpriv->stats.LINK_Q.index++] =
 
1063
                            pstats->signalquality;
 
1064
                        if (rtlpriv->stats.LINK_Q.index >=
 
1065
                            PHY_LINKQUALITY_SLID_WIN_MAX)
 
1066
                                rtlpriv->stats.LINK_Q.index = 0;
 
1067
                        tmpval = rtlpriv->stats.LINK_Q.total_val /
 
1068
                            rtlpriv->stats.LINK_Q.total_num;
 
1069
                        rtlpriv->stats.signal_quality = tmpval;
 
1070
                        rtlpriv->stats.last_sigstrength_inpercent = tmpval;
 
1071
                        for (n_stream = 0; n_stream < 2;
 
1072
                             n_stream++) {
 
1073
                                if (pstats->RX_SIGQ[n_stream] != -1) {
 
1074
                                        if (!rtlpriv->stats.RX_EVM[n_stream]) {
 
1075
                                                rtlpriv->stats.RX_EVM[n_stream]
 
1076
                                                 = pstats->RX_SIGQ[n_stream];
 
1077
                                        }
 
1078
                                        rtlpriv->stats.RX_EVM[n_stream] =
 
1079
                                            ((rtlpriv->stats.RX_EVM
 
1080
                                            [n_stream] *
 
1081
                                            (RX_SMOOTH_FACTOR - 1)) +
 
1082
                                            (pstats->RX_SIGQ
 
1083
                                            [n_stream] * 1)) /
 
1084
                                            (RX_SMOOTH_FACTOR);
 
1085
                                }
 
1086
                        }
 
1087
                }
 
1088
        } else {
 
1089
                ;
 
1090
        }
 
1091
}
 
1092
 
 
1093
static void _rtl92c_process_phyinfo(struct ieee80211_hw *hw,
 
1094
                                     u8 *buffer,
 
1095
                                     struct rtl_stats *pcurrent_stats)
 
1096
{
 
1097
        if (!pcurrent_stats->packet_matchbssid &&
 
1098
            !pcurrent_stats->packet_beacon)
 
1099
                return;
 
1100
        _rtl92c_process_ui_rssi(hw, pcurrent_stats);
 
1101
        _rtl92c_process_pwdb(hw, pcurrent_stats);
 
1102
        _rtl92c_process_LINK_Q(hw, pcurrent_stats);
 
1103
}
 
1104
 
 
1105
void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
 
1106
                                               struct sk_buff *skb,
 
1107
                                               struct rtl_stats *pstats,
 
1108
                                               struct rx_desc_92c *pdesc,
 
1109
                                               struct rx_fwinfo_92c *p_drvinfo)
 
1110
{
 
1111
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
1112
        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 
1113
        struct ieee80211_hdr *hdr;
 
1114
        u8 *tmp_buf;
 
1115
        u8 *praddr;
 
1116
        u8 *psaddr;
 
1117
        __le16 fc;
 
1118
        u16 type, cpu_fc;
 
1119
        bool packet_matchbssid, packet_toself, packet_beacon;
 
1120
 
 
1121
        tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
 
1122
        hdr = (struct ieee80211_hdr *)tmp_buf;
 
1123
        fc = hdr->frame_control;
 
1124
        cpu_fc = le16_to_cpu(fc);
 
1125
        type = WLAN_FC_GET_TYPE(fc);
 
1126
        praddr = hdr->addr1;
 
1127
        psaddr = hdr->addr2;
 
1128
        packet_matchbssid =
 
1129
            ((IEEE80211_FTYPE_CTL != type) &&
 
1130
             (!compare_ether_addr(mac->bssid,
 
1131
                          (cpu_fc & IEEE80211_FCTL_TODS) ?
 
1132
                          hdr->addr1 : (cpu_fc & IEEE80211_FCTL_FROMDS) ?
 
1133
                          hdr->addr2 : hdr->addr3)) &&
 
1134
             (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
 
1135
 
 
1136
        packet_toself = packet_matchbssid &&
 
1137
            (!compare_ether_addr(praddr, rtlefuse->dev_addr));
 
1138
        if (ieee80211_is_beacon(fc))
 
1139
                packet_beacon = true;
 
1140
        _rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
 
1141
                                   packet_matchbssid, packet_toself,
 
1142
                                   packet_beacon);
 
1143
        _rtl92c_process_phyinfo(hw, tmp_buf, pstats);
 
1144
}