aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtlwifi
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2012-10-25 14:46:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-11-14 14:54:53 -0500
commitc592e631bcec4d858695eee8bf321d60390d38e9 (patch)
tree721760de02b9b0df3bc0294b77b7ba15b45d6e6b /drivers/net/wireless/rtlwifi
parentb7fd76d114568d0b1e0d443049ed597b3a55f9c6 (diff)
rtlwifi: rtl8723ae: Add new driver
This patch is the addition of files for a new driver to handle the Realtek RTL8723AE wireless device. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Cc: <chaoming_li@realsil.com.cn> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtlwifi')
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/btc.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/def.h163
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.c920
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.h149
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.c745
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.h101
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c542
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h160
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c1786
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h151
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c2380
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.h73
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/led.c151
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/led.h39
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/phy.c2044
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/phy.h224
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c109
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h322
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c129
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h98
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/reg.h2097
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/rf.c505
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/rf.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.c387
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.h37
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/table.c738
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/table.h50
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/trx.c670
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/trx.h725
29 files changed, 15579 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h b/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h
new file mode 100644
index 000000000000..417afeed36af
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h
@@ -0,0 +1,41 @@
1/******************************************************************************
2 **
3 ** Copyright(c) 2009-2012 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 ** Larry Finger <Larry.Finger@lwfinger.net>
26 **
27 *****************************************************************************
28 */
29
30#ifndef __RTL8723E_BTC_H__
31#define __RTL8723E_BTC_H__
32
33#include "../wifi.h"
34#include "hal_bt_coexist.h"
35
36struct bt_coexist_c2h_info {
37 u8 no_parse_c2h;
38 u8 has_c2h;
39};
40
41#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
new file mode 100644
index 000000000000..8c110356dff9
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
@@ -0,0 +1,163 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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
31#ifndef __RTL8723E_DEF_H__
32#define __RTL8723E_DEF_H__
33
34#define HAL_PRIME_CHNL_OFFSET_LOWER 1
35
36#define RX_MPDU_QUEUE 0
37
38#define CHIP_8723 BIT(0)
39#define NORMAL_CHIP BIT(3)
40#define RF_TYPE_1T2R BIT(4)
41#define RF_TYPE_2T2R BIT(5)
42#define CHIP_VENDOR_UMC BIT(7)
43#define B_CUT_VERSION BIT(12)
44#define C_CUT_VERSION BIT(13)
45#define D_CUT_VERSION ((BIT(12)|BIT(13)))
46#define E_CUT_VERSION BIT(14)
47#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28))
48
49enum version_8723e {
50 VERSION_TEST_UMC_CHIP_8723 = 0x0081,
51 VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089,
52 VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089,
53};
54
55/* MASK */
56#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2))
57#define CHIP_TYPE_MASK BIT(3)
58#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6))
59#define MANUFACTUER_MASK BIT(7)
60#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8))
61#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12))
62
63/* Get element */
64#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK)
65#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK)
66#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK)
67
68#define IS_81XXC(version) ((GET_CVID_IC_TYPE(version) == 0) ?\
69 true : false)
70#define IS_8723_SERIES(version) \
71 ((GET_CVID_IC_TYPE(version) == CHIP_8723) ? true : false)
72#define IS_CHIP_VENDOR_UMC(version) \
73 ((GET_CVID_MANUFACTUER(version)) ? true : false)
74
75#define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? \
76 ((GET_CVID_CUT_VERSION(version)) ? false : true) : false)
77#define IS_VENDOR_8723_A_CUT(version) ((IS_8723_SERIES(version)) ? \
78 ((GET_CVID_CUT_VERSION(version)) ? false : true) : false)
79#define IS_81xxC_VENDOR_UMC_B_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) \
80 ? ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? \
81 true : false) : false)
82
83enum rf_optype {
84 RF_OP_BY_SW_3WIRE = 0,
85 RF_OP_BY_FW,
86 RF_OP_MAX
87};
88
89enum rf_power_state {
90 RF_ON,
91 RF_OFF,
92 RF_SLEEP,
93 RF_SHUT_DOWN,
94};
95
96enum power_save_mode {
97 POWER_SAVE_MODE_ACTIVE,
98 POWER_SAVE_MODE_SAVE,
99};
100
101enum power_polocy_config {
102 POWERCFG_MAX_POWER_SAVINGS,
103 POWERCFG_GLOBAL_POWER_SAVINGS,
104 POWERCFG_LOCAL_POWER_SAVINGS,
105 POWERCFG_LENOVO,
106};
107
108enum interface_select_pci {
109 INTF_SEL1_MINICARD = 0,
110 INTF_SEL0_PCIE = 1,
111 INTF_SEL2_RSV = 2,
112 INTF_SEL3_RSV = 3,
113};
114
115enum hal_fw_c2h_cmd_id {
116 HAL_FW_C2H_CMD_Read_MACREG = 0,
117 HAL_FW_C2H_CMD_Read_BBREG = 1,
118 HAL_FW_C2H_CMD_Read_RFREG = 2,
119 HAL_FW_C2H_CMD_Read_EEPROM = 3,
120 HAL_FW_C2H_CMD_Read_EFUSE = 4,
121 HAL_FW_C2H_CMD_Read_CAM = 5,
122 HAL_FW_C2H_CMD_Get_BasicRate = 6,
123 HAL_FW_C2H_CMD_Get_DataRate = 7,
124 HAL_FW_C2H_CMD_Survey = 8,
125 HAL_FW_C2H_CMD_SurveyDone = 9,
126 HAL_FW_C2H_CMD_JoinBss = 10,
127 HAL_FW_C2H_CMD_AddSTA = 11,
128 HAL_FW_C2H_CMD_DelSTA = 12,
129 HAL_FW_C2H_CMD_AtimDone = 13,
130 HAL_FW_C2H_CMD_TX_Report = 14,
131 HAL_FW_C2H_CMD_CCX_Report = 15,
132 HAL_FW_C2H_CMD_DTM_Report = 16,
133 HAL_FW_C2H_CMD_TX_Rate_Statistics = 17,
134 HAL_FW_C2H_CMD_C2HLBK = 18,
135 HAL_FW_C2H_CMD_C2HDBG = 19,
136 HAL_FW_C2H_CMD_C2HFEEDBACK = 20,
137 HAL_FW_C2H_CMD_MAX
138};
139
140enum rtl_desc_qsel {
141 QSLT_BK = 0x2,
142 QSLT_BE = 0x0,
143 QSLT_VI = 0x5,
144 QSLT_VO = 0x7,
145 QSLT_BEACON = 0x10,
146 QSLT_HIGH = 0x11,
147 QSLT_MGNT = 0x12,
148 QSLT_CMD = 0x13,
149};
150
151struct phy_sts_cck_8723e_t {
152 u8 adc_pwdb_X[4];
153 u8 sq_rpt;
154 u8 cck_agc_rpt;
155};
156
157struct h2c_cmd_8723e {
158 u8 element_id;
159 u32 cmd_len;
160 u8 *p_cmdbuffer;
161};
162
163#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
new file mode 100644
index 000000000000..12e2a3cb0701
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
@@ -0,0 +1,920 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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
31#include "../wifi.h"
32#include "../base.h"
33#include "../pci.h"
34#include "reg.h"
35#include "def.h"
36#include "phy.h"
37#include "dm.h"
38#include "fw.h"
39#include "hal_btc.h"
40
41static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
42 0x7f8001fe,
43 0x788001e2,
44 0x71c001c7,
45 0x6b8001ae,
46 0x65400195,
47 0x5fc0017f,
48 0x5a400169,
49 0x55400155,
50 0x50800142,
51 0x4c000130,
52 0x47c0011f,
53 0x43c0010f,
54 0x40000100,
55 0x3c8000f2,
56 0x390000e4,
57 0x35c000d7,
58 0x32c000cb,
59 0x300000c0,
60 0x2d4000b5,
61 0x2ac000ab,
62 0x288000a2,
63 0x26000098,
64 0x24000090,
65 0x22000088,
66 0x20000080,
67 0x1e400079,
68 0x1c800072,
69 0x1b00006c,
70 0x19800066,
71 0x18000060,
72 0x16c0005b,
73 0x15800056,
74 0x14400051,
75 0x1300004c,
76 0x12000048,
77 0x11000044,
78 0x10000040,
79};
80
81static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
82 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
83 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
84 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
85 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
86 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
87 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
88 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
89 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
90 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
91 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
92 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
93 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
94 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
95 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
96 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
97 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
98 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
99 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
100 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
101 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
102 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
103 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
104 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
105 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
106 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
107 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
108 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
109 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
110 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
111 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
112 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
113 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
114 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}
115};
116
117static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
118 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
119 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
120 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
121 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
122 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
123 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
124 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
125 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
126 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
127 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
128 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
129 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
130 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
131 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
132 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
133 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
134 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
135 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
136 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
137 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
138 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
139 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
140 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
141 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
142 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
143 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
144 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
145 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
146 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
147 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
148 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
149 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
150 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
151};
152
153static void rtl8723ae_dm_diginit(struct ieee80211_hw *hw)
154{
155 struct rtl_priv *rtlpriv = rtl_priv(hw);
156 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
157
158 dm_digtable->dig_enable_flag = true;
159 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
160 dm_digtable->cur_igvalue = 0x20;
161 dm_digtable->pre_igvalue = 0x0;
162 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
163 dm_digtable->presta_cstate = DIG_STA_DISCONNECT;
164 dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
165 dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
166 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
167 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
168 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
169 dm_digtable->rx_gain_range_max = DM_DIG_MAX;
170 dm_digtable->rx_gain_range_min = DM_DIG_MIN;
171 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
172 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
173 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
174 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
175 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
176}
177
178static u8 rtl_init_gain_min_pwdb(struct ieee80211_hw *hw)
179{
180 struct rtl_priv *rtlpriv = rtl_priv(hw);
181 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
182 long rssi_val_min = 0;
183
184 if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
185 (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) {
186 if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
187 rssi_val_min =
188 (rtlpriv->dm.entry_min_undec_sm_pwdb >
189 rtlpriv->dm.undec_sm_pwdb) ?
190 rtlpriv->dm.undec_sm_pwdb :
191 rtlpriv->dm.entry_min_undec_sm_pwdb;
192 else
193 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
194 } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT ||
195 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) {
196 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
197 } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
198 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
199 }
200
201 return (u8) rssi_val_min;
202}
203
204static void rtl8723ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
205{
206 u32 ret_value;
207 struct rtl_priv *rtlpriv = rtl_priv(hw);
208 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
209
210 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
211 falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
212
213 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
214 falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
215 falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
216
217 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
218 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
219 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
220 falsealm_cnt->cnt_rate_illegal +
221 falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
222
223 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
224 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
225 falsealm_cnt->cnt_cck_fail = ret_value;
226
227 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
228 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
229 falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
230 falsealm_cnt->cnt_rate_illegal +
231 falsealm_cnt->cnt_crc8_fail +
232 falsealm_cnt->cnt_mcs_fail +
233 falsealm_cnt->cnt_cck_fail);
234
235 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
236 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
237 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
238 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
239
240 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
241 "cnt_parity_fail = %d, cnt_rate_illegal = %d, "
242 "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
243 falsealm_cnt->cnt_parity_fail,
244 falsealm_cnt->cnt_rate_illegal,
245 falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
246
247 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
248 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
249 falsealm_cnt->cnt_ofdm_fail,
250 falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
251}
252
253static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
254{
255 struct rtl_priv *rtlpriv = rtl_priv(hw);
256 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
257 u8 value_igi = dm_digtable->cur_igvalue;
258
259 if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
260 value_igi--;
261 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
262 value_igi += 0;
263 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
264 value_igi++;
265 else
266 value_igi += 2;
267
268 value_igi = clamp(value_igi, (u8)DM_DIG_FA_LOWER, (u8)DM_DIG_FA_UPPER);
269 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
270 value_igi = 0x32;
271
272 dm_digtable->cur_igvalue = value_igi;
273 rtl8723ae_dm_write_dig(hw);
274}
275
276static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
277{
278 struct rtl_priv *rtlpriv = rtl_priv(hw);
279 struct dig_t *dgtbl = &rtlpriv->dm_digtable;
280
281 if (rtlpriv->falsealm_cnt.cnt_all > dgtbl->fa_highthresh) {
282 if ((dgtbl->back_val - 2) < dgtbl->back_range_min)
283 dgtbl->back_val = dgtbl->back_range_min;
284 else
285 dgtbl->back_val -= 2;
286 } else if (rtlpriv->falsealm_cnt.cnt_all < dgtbl->fa_lowthresh) {
287 if ((dgtbl->back_val + 2) > dgtbl->back_range_max)
288 dgtbl->back_val = dgtbl->back_range_max;
289 else
290 dgtbl->back_val += 2;
291 }
292
293 if ((dgtbl->rssi_val_min + 10 - dgtbl->back_val) >
294 dgtbl->rx_gain_range_max)
295 dgtbl->cur_igvalue = dgtbl->rx_gain_range_max;
296 else if ((dgtbl->rssi_val_min + 10 -
297 dgtbl->back_val) < dgtbl->rx_gain_range_min)
298 dgtbl->cur_igvalue = dgtbl->rx_gain_range_min;
299 else
300 dgtbl->cur_igvalue = dgtbl->rssi_val_min + 10 - dgtbl->back_val;
301
302 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
303 "rssi_val_min = %x back_val %x\n",
304 dgtbl->rssi_val_min, dgtbl->back_val);
305
306 rtl8723ae_dm_write_dig(hw);
307}
308
309static void rtl8723ae_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
310{
311 struct rtl_priv *rtlpriv = rtl_priv(hw);
312 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
313 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
314 long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb;
315 bool multi_sta = false;
316
317 if (mac->opmode == NL80211_IFTYPE_ADHOC)
318 multi_sta = true;
319
320 if ((!multi_sta) ||
321 (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) {
322 rtlpriv->initialized = false;
323 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
324 return;
325 } else if (!rtlpriv->initialized) {
326 rtlpriv->initialized = true;
327 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
328 dm_digtable->cur_igvalue = 0x20;
329 rtl8723ae_dm_write_dig(hw);
330 }
331
332 if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
333 if ((rssi_strength < dm_digtable->rssi_lowthresh) &&
334 (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
335
336 if (dm_digtable->dig_ext_port_stage ==
337 DIG_EXT_PORT_STAGE_2) {
338 dm_digtable->cur_igvalue = 0x20;
339 rtl8723ae_dm_write_dig(hw);
340 }
341
342 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
343 } else if (rssi_strength > dm_digtable->rssi_highthresh) {
344 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
345 rtl92c_dm_ctrl_initgain_by_fa(hw);
346 }
347 } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
348 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
349 dm_digtable->cur_igvalue = 0x20;
350 rtl8723ae_dm_write_dig(hw);
351 }
352
353 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
354 "curmultista_cstate = %x dig_ext_port_stage %x\n",
355 dm_digtable->curmultista_cstate,
356 dm_digtable->dig_ext_port_stage);
357}
358
359static void rtl8723ae_dm_initial_gain_sta(struct ieee80211_hw *hw)
360{
361 struct rtl_priv *rtlpriv = rtl_priv(hw);
362 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
363
364 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
365 "presta_cstate = %x, cursta_cstate = %x\n",
366 dm_digtable->presta_cstate,
367 dm_digtable->cursta_cstate);
368
369 if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
370 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
371 dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
372
373 if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
374 dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw);
375 rtl92c_dm_ctrl_initgain_by_rssi(hw);
376 }
377 } else {
378 dm_digtable->rssi_val_min = 0;
379 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
380 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
381 dm_digtable->cur_igvalue = 0x20;
382 dm_digtable->pre_igvalue = 0;
383 rtl8723ae_dm_write_dig(hw);
384 }
385}
386static void rtl8723ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
387{
388 struct rtl_priv *rtlpriv = rtl_priv(hw);
389 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
390
391 if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
392 dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw);
393
394 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {
395 if (dm_digtable->rssi_val_min <= 25)
396 dm_digtable->cur_cck_pd_state =
397 CCK_PD_STAGE_LowRssi;
398 else
399 dm_digtable->cur_cck_pd_state =
400 CCK_PD_STAGE_HighRssi;
401 } else {
402 if (dm_digtable->rssi_val_min <= 20)
403 dm_digtable->cur_cck_pd_state =
404 CCK_PD_STAGE_LowRssi;
405 else
406 dm_digtable->cur_cck_pd_state =
407 CCK_PD_STAGE_HighRssi;
408 }
409 } else {
410 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
411 }
412
413 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
414 if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) {
415 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
416 dm_digtable->cur_cck_fa_state =
417 CCK_FA_STAGE_High;
418 else
419 dm_digtable->cur_cck_fa_state =
420 CCK_FA_STAGE_Low;
421
422 if (dm_digtable->pre_cck_fa_state !=
423 dm_digtable->cur_cck_fa_state) {
424 if (dm_digtable->cur_cck_fa_state ==
425 CCK_FA_STAGE_Low)
426 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
427 0x83);
428 else
429 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
430 0xcd);
431
432 dm_digtable->pre_cck_fa_state =
433 dm_digtable->cur_cck_fa_state;
434 }
435
436 rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
437
438 } else {
439 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
440 rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
441
442 }
443 dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
444 }
445
446 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
447 "CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state);
448
449}
450
451static void rtl8723ae_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
452{
453 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
454 struct rtl_priv *rtlpriv = rtl_priv(hw);
455 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
456
457 if (mac->act_scanning == true)
458 return;
459
460 if (mac->link_state >= MAC80211_LINKED)
461 dm_digtable->cursta_cstate = DIG_STA_CONNECT;
462 else
463 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
464
465 rtl8723ae_dm_initial_gain_sta(hw);
466 rtl8723ae_dm_initial_gain_multi_sta(hw);
467 rtl8723ae_dm_cck_packet_detection_thresh(hw);
468
469 dm_digtable->presta_cstate = dm_digtable->cursta_cstate;
470
471}
472
473static void rtl8723ae_dm_dig(struct ieee80211_hw *hw)
474{
475 struct rtl_priv *rtlpriv = rtl_priv(hw);
476 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
477
478 if (rtlpriv->dm.dm_initialgain_enable == false)
479 return;
480 if (dm_digtable->dig_enable_flag == false)
481 return;
482
483 rtl8723ae_dm_ctrl_initgain_by_twoport(hw);
484}
485
486static void rtl8723ae_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
487{
488 struct rtl_priv *rtlpriv = rtl_priv(hw);
489
490 rtlpriv->dm.dynamic_txpower_enable = false;
491
492 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
493 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
494}
495
496static void rtl8723ae_dm_dynamic_txpower(struct ieee80211_hw *hw)
497{
498 struct rtl_priv *rtlpriv = rtl_priv(hw);
499 struct rtl_phy *rtlphy = &(rtlpriv->phy);
500 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
501 long undec_sm_pwdb;
502
503 if (!rtlpriv->dm.dynamic_txpower_enable)
504 return;
505
506 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
507 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
508 return;
509 }
510
511 if ((mac->link_state < MAC80211_LINKED) &&
512 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
513 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
514 "Not connected\n");
515
516 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
517
518 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
519 return;
520 }
521
522 if (mac->link_state >= MAC80211_LINKED) {
523 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
524 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
525 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
526 "AP Client PWDB = 0x%lx\n",
527 undec_sm_pwdb);
528 } else {
529 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
530 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
531 "STA Default Port PWDB = 0x%lx\n",
532 undec_sm_pwdb);
533 }
534 } else {
535 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
536
537 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
538 "AP Ext Port PWDB = 0x%lx\n",
539 undec_sm_pwdb);
540 }
541
542 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
543 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
544 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
545 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
546 } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
547 (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
548 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
549 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
550 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
551 } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
552 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
553 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
554 "TXHIGHPWRLEVEL_NORMAL\n");
555 }
556
557 if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
558 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
559 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
560 rtlphy->current_channel);
561 rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
562 }
563
564 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
565}
566
567void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw)
568{
569 struct rtl_priv *rtlpriv = rtl_priv(hw);
570 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
571
572 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
573 "cur_igvalue = 0x%x, "
574 "pre_igvalue = 0x%x, back_val = %d\n",
575 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
576 dm_digtable->back_val);
577
578 if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
579 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
580 dm_digtable->cur_igvalue);
581 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
582 dm_digtable->cur_igvalue);
583
584 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
585 }
586}
587
588static void rtl8723ae_dm_pwdmonitor(struct ieee80211_hw *hw)
589{
590}
591
592void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw)
593{
594 struct rtl_priv *rtlpriv = rtl_priv(hw);
595
596 rtlpriv->dm.current_turbo_edca = false;
597 rtlpriv->dm.is_any_nonbepkts = false;
598 rtlpriv->dm.is_cur_rdlstate = false;
599}
600
601static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
602{
603 struct rtl_priv *rtlpriv = rtl_priv(hw);
604 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
605 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
606
607 u64 cur_txok_cnt = 0;
608 u64 cur_rxok_cnt = 0;
609 u32 edca_be_ul = 0x5ea42b;
610 u32 edca_be_dl = 0x5ea42b;
611 bool bt_change_edca = false;
612
613 if ((mac->last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) ||
614 (mac->last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) {
615 rtlpriv->dm.current_turbo_edca = false;
616 mac->last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
617 mac->last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl;
618 }
619
620 if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) {
621 edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
622 bt_change_edca = true;
623 }
624
625 if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) {
626 edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl;
627 bt_change_edca = true;
628 }
629
630 if (mac->link_state != MAC80211_LINKED) {
631 rtlpriv->dm.current_turbo_edca = false;
632 return;
633 }
634
635 if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) {
636 if (!(edca_be_ul & 0xffff0000))
637 edca_be_ul |= 0x005e0000;
638
639 if (!(edca_be_dl & 0xffff0000))
640 edca_be_dl |= 0x005e0000;
641 }
642
643 if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
644 (!rtlpriv->dm.disable_framebursting))) {
645
646 cur_txok_cnt = rtlpriv->stats.txbytesunicast -
647 mac->last_txok_cnt;
648 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast -
649 mac->last_rxok_cnt;
650
651 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
652 if (!rtlpriv->dm.is_cur_rdlstate ||
653 !rtlpriv->dm.current_turbo_edca) {
654 rtl_write_dword(rtlpriv,
655 REG_EDCA_BE_PARAM,
656 edca_be_dl);
657 rtlpriv->dm.is_cur_rdlstate = true;
658 }
659 } else {
660 if (rtlpriv->dm.is_cur_rdlstate ||
661 !rtlpriv->dm.current_turbo_edca) {
662 rtl_write_dword(rtlpriv,
663 REG_EDCA_BE_PARAM,
664 edca_be_ul);
665 rtlpriv->dm.is_cur_rdlstate = false;
666 }
667 }
668 rtlpriv->dm.current_turbo_edca = true;
669 } else {
670 if (rtlpriv->dm.current_turbo_edca) {
671 u8 tmp = AC0_BE;
672 rtlpriv->cfg->ops->set_hw_reg(hw,
673 HW_VAR_AC_PARAM,
674 (u8 *) (&tmp));
675 rtlpriv->dm.current_turbo_edca = false;
676 }
677 }
678
679 rtlpriv->dm.is_any_nonbepkts = false;
680 mac->last_txok_cnt = rtlpriv->stats.txbytesunicast;
681 mac->last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
682}
683
684static void rtl8723ae_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
685{
686 struct rtl_priv *rtlpriv = rtl_priv(hw);
687
688 rtlpriv->dm.txpower_tracking = true;
689 rtlpriv->dm.txpower_trackinginit = false;
690
691 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
692 "pMgntInfo->txpower_tracking = %d\n",
693 rtlpriv->dm.txpower_tracking);
694}
695
696void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
697{
698 struct rtl_priv *rtlpriv = rtl_priv(hw);
699 struct rate_adaptive *p_ra = &(rtlpriv->ra);
700
701 p_ra->ratr_state = DM_RATR_STA_INIT;
702 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
703
704 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
705 rtlpriv->dm.useramask = true;
706 else
707 rtlpriv->dm.useramask = false;
708}
709
710static void rtl8723ae_dm_init_dynamic_bpowersaving(struct ieee80211_hw *hw)
711{
712 struct rtl_priv *rtlpriv = rtl_priv(hw);
713
714 rtlpriv->dm_pstable.pre_ccastate = CCA_MAX;
715 rtlpriv->dm_pstable.cur_ccasate = CCA_MAX;
716 rtlpriv->dm_pstable.pre_rfstate = RF_MAX;
717 rtlpriv->dm_pstable.cur_rfstate = RF_MAX;
718 rtlpriv->dm_pstable.rssi_val_min = 0;
719}
720
721void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 force_in_normal)
722{
723 struct rtl_priv *rtlpriv = rtl_priv(hw);
724 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
725
726 if (!rtlpriv->reg_init) {
727 rtlpriv->reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
728 MASKDWORD) & 0x1CC000) >> 14;
729
730 rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
731 MASKDWORD) & BIT(3)) >> 3;
732
733 rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
734 MASKDWORD) & 0xFF000000) >> 24;
735
736 rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) &
737 0xF000) >> 12;
738
739 rtlpriv->reg_init = true;
740 }
741
742 if (!force_in_normal) {
743 if (dm_pstable->rssi_val_min != 0) {
744 if (dm_pstable->pre_rfstate == RF_NORMAL) {
745 if (dm_pstable->rssi_val_min >= 30)
746 dm_pstable->cur_rfstate = RF_SAVE;
747 else
748 dm_pstable->cur_rfstate = RF_NORMAL;
749 } else {
750 if (dm_pstable->rssi_val_min <= 25)
751 dm_pstable->cur_rfstate = RF_NORMAL;
752 else
753 dm_pstable->cur_rfstate = RF_SAVE;
754 }
755 } else {
756 dm_pstable->cur_rfstate = RF_MAX;
757 }
758 } else {
759 dm_pstable->cur_rfstate = RF_NORMAL;
760 }
761
762 if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) {
763 if (dm_pstable->cur_rfstate == RF_SAVE) {
764
765 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
766 BIT(5), 0x1);
767 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
768 0x1C0000, 0x2);
769 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
770 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
771 0xFF000000, 0x63);
772 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
773 0xC000, 0x2);
774 rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
775 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
776 rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
777 } else {
778 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
779 0x1CC000, rtlpriv->reg_874);
780 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
781 rtlpriv->reg_c70);
782 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
783 rtlpriv->reg_85c);
784 rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74);
785 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
786 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
787 BIT(5), 0x0);
788 }
789
790 dm_pstable->pre_rfstate = dm_pstable->cur_rfstate;
791 }
792}
793
794static void rtl8723ae_dm_dynamic_bpowersaving(struct ieee80211_hw *hw)
795{
796 struct rtl_priv *rtlpriv = rtl_priv(hw);
797 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
798 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
799
800 if (((mac->link_state == MAC80211_NOLINK)) &&
801 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
802 dm_pstable->rssi_val_min = 0;
803 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
804 "Not connected to any\n");
805 }
806
807 if (mac->link_state == MAC80211_LINKED) {
808 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
809 dm_pstable->rssi_val_min =
810 rtlpriv->dm.entry_min_undec_sm_pwdb;
811 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
812 "AP Client PWDB = 0x%lx\n",
813 dm_pstable->rssi_val_min);
814 } else {
815 dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
816 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
817 "STA Default Port PWDB = 0x%lx\n",
818 dm_pstable->rssi_val_min);
819 }
820 } else {
821 dm_pstable->rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
822
823 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
824 "AP Ext Port PWDB = 0x%lx\n",
825 dm_pstable->rssi_val_min);
826 }
827
828 rtl8723ae_dm_rf_saving(hw, false);
829}
830
831void rtl8723ae_dm_init(struct ieee80211_hw *hw)
832{
833 struct rtl_priv *rtlpriv = rtl_priv(hw);
834
835 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
836 rtl8723ae_dm_diginit(hw);
837 rtl8723ae_dm_init_dynamic_txpower(hw);
838 rtl8723ae_dm_init_edca_turbo(hw);
839 rtl8723ae_dm_init_rate_adaptive_mask(hw);
840 rtl8723ae_dm_initialize_txpower_tracking(hw);
841 rtl8723ae_dm_init_dynamic_bpowersaving(hw);
842}
843
844void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw)
845{
846 struct rtl_priv *rtlpriv = rtl_priv(hw);
847 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
848 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
849 bool fw_current_inpsmode = false;
850 bool fw_ps_awake = true;
851 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
852 (u8 *) (&fw_current_inpsmode));
853 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
854 (u8 *) (&fw_ps_awake));
855
856 if ((ppsc->rfpwr_state == ERFON) &&
857 ((!fw_current_inpsmode) && fw_ps_awake) &&
858 (!ppsc->rfchange_inprogress)) {
859 rtl8723ae_dm_pwdmonitor(hw);
860 rtl8723ae_dm_dig(hw);
861 rtl8723ae_dm_false_alarm_counter_statistics(hw);
862 rtl8723ae_dm_dynamic_bpowersaving(hw);
863 rtl8723ae_dm_dynamic_txpower(hw);
864 /* rtl92c_dm_refresh_rate_adaptive_mask(hw); */
865 rtl8723ae_dm_bt_coexist(hw);
866 rtl8723ae_dm_check_edca_turbo(hw);
867 }
868 if (rtlpcipriv->bt_coexist.init_set)
869 rtl_write_byte(rtlpriv, 0x76e, 0xc);
870}
871
872static void rtl8723ae_dm_init_bt_coexist(struct ieee80211_hw *hw)
873{
874 struct rtl_priv *rtlpriv = rtl_priv(hw);
875 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
876
877 rtlpcipriv->bt_coexist.bt_rfreg_origin_1e
878 = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff);
879 rtlpcipriv->bt_coexist.bt_rfreg_origin_1f
880 = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0);
881
882 rtlpcipriv->bt_coexist.cstate = 0;
883 rtlpcipriv->bt_coexist.previous_state = 0;
884 rtlpcipriv->bt_coexist.cstate_h = 0;
885 rtlpcipriv->bt_coexist.previous_state_h = 0;
886 rtlpcipriv->bt_coexist.lps_counter = 0;
887
888 /* Enable counter statistics */
889 rtl_write_byte(rtlpriv, 0x76e, 0x4);
890 rtl_write_byte(rtlpriv, 0x778, 0x3);
891 rtl_write_byte(rtlpriv, 0x40, 0x20);
892
893 rtlpcipriv->bt_coexist.init_set = true;
894}
895
896void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw)
897{
898 struct rtl_priv *rtlpriv = rtl_priv(hw);
899 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
900 u8 tmp_byte = 0;
901 if (!rtlpcipriv->bt_coexist.bt_coexistence) {
902 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
903 "[DM]{BT], BT not exist!!\n");
904 return;
905 }
906
907 if (!rtlpcipriv->bt_coexist.init_set) {
908 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
909 "[DM][BT], rtl8723ae_dm_bt_coexist()\n");
910
911 rtl8723ae_dm_init_bt_coexist(hw);
912 }
913
914 tmp_byte = rtl_read_byte(rtlpriv, 0x40);
915 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
916 "[DM][BT], 0x40 is 0x%x", tmp_byte);
917 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
918 "[DM][BT], bt_dm_coexist start");
919 rtl8723ae_dm_bt_coexist_8723(hw);
920}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
new file mode 100644
index 000000000000..39d246196247
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
@@ -0,0 +1,149 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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
31#ifndef __RTL8723E_DM_H__
32#define __RTL8723E_DM_H__
33
34#define HAL_DM_HIPWR_DISABLE BIT(1)
35
36#define OFDM_TABLE_SIZE 37
37#define CCK_TABLE_SIZE 33
38
39#define DM_DIG_THRESH_HIGH 40
40#define DM_DIG_THRESH_LOW 35
41
42#define DM_FALSEALARM_THRESH_LOW 400
43#define DM_FALSEALARM_THRESH_HIGH 1000
44
45#define DM_DIG_MAX 0x3e
46#define DM_DIG_MIN 0x1e
47
48#define DM_DIG_FA_UPPER 0x32
49#define DM_DIG_FA_LOWER 0x20
50#define DM_DIG_FA_TH0 0x20
51#define DM_DIG_FA_TH1 0x100
52#define DM_DIG_FA_TH2 0x200
53
54#define DM_DIG_BACKOFF_MAX 12
55#define DM_DIG_BACKOFF_MIN -4
56#define DM_DIG_BACKOFF_DEFAULT 10
57
58#define DM_RATR_STA_INIT 0
59
60#define TXHIGHPWRLEVEL_NORMAL 0
61#define TXHIGHPWRLEVEL_LEVEL1 1
62#define TXHIGHPWRLEVEL_LEVEL2 2
63#define TXHIGHPWRLEVEL_BT1 3
64#define TXHIGHPWRLEVEL_BT2 4
65
66#define DM_TYPE_BYDRIVER 1
67
68#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
69#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
70
71struct swat_t {
72 u8 failure_cnt;
73 u8 try_flag;
74 u8 stop_trying;
75 long pre_rssi;
76 long trying_threshold;
77 u8 cur_antenna;
78 u8 pre_antenna;
79};
80
81enum tag_dynamic_init_gain_operation_type_definition {
82 DIG_TYPE_THRESH_HIGH = 0,
83 DIG_TYPE_THRESH_LOW = 1,
84 DIG_TYPE_BACKOFF = 2,
85 DIG_TYPE_RX_GAIN_MIN = 3,
86 DIG_TYPE_RX_GAIN_MAX = 4,
87 DIG_TYPE_ENABLE = 5,
88 DIG_TYPE_DISABLE = 6,
89 DIG_OP_TYPE_MAX
90};
91
92enum tag_cck_packet_detection_threshold_type_definition {
93 CCK_PD_STAGE_LowRssi = 0,
94 CCK_PD_STAGE_HighRssi = 1,
95 CCK_FA_STAGE_Low = 2,
96 CCK_FA_STAGE_High = 3,
97 CCK_PD_STAGE_MAX = 4,
98};
99
100enum dm_1r_cca_e {
101 CCA_1R = 0,
102 CCA_2R = 1,
103 CCA_MAX = 2,
104};
105
106enum dm_rf_e {
107 RF_SAVE = 0,
108 RF_NORMAL = 1,
109 RF_MAX = 2,
110};
111
112enum dm_sw_ant_switch_e {
113 ANS_ANTENNA_B = 1,
114 ANS_ANTENNA_A = 2,
115 ANS_ANTENNA_MAX = 3,
116};
117
118enum dm_dig_ext_port_alg_e {
119 DIG_EXT_PORT_STAGE_0 = 0,
120 DIG_EXT_PORT_STAGE_1 = 1,
121 DIG_EXT_PORT_STAGE_2 = 2,
122 DIG_EXT_PORT_STAGE_3 = 3,
123 DIG_EXT_PORT_STAGE_MAX = 4,
124};
125
126enum dm_dig_connect_e {
127 DIG_STA_DISCONNECT = 0,
128 DIG_STA_CONNECT = 1,
129 DIG_STA_BEFORE_CONNECT = 2,
130 DIG_MULTISTA_DISCONNECT = 3,
131 DIG_MULTISTA_CONNECT = 4,
132 DIG_CONNECT_MAX
133};
134
135#define GET_UNDECORATED_AVERAGE_RSSI(_priv) \
136 ((((struct rtl_priv *)(_priv))->mac80211.opmode == \
137 NL80211_IFTYPE_ADHOC) ? \
138 (((struct rtl_priv *)(_priv))->dm.entry_min_undec_sm_pwdb) \
139 : (((struct rtl_priv *)(_priv))->dm.undec_sm_pwdb))
140
141void rtl8723ae_dm_init(struct ieee80211_hw *hw);
142void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw);
143void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw);
144void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw);
145void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
146void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
147void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw);
148
149#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
new file mode 100644
index 000000000000..f55b1767ef57
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
@@ -0,0 +1,745 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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
31#include "../wifi.h"
32#include "../pci.h"
33#include "../base.h"
34#include "reg.h"
35#include "def.h"
36#include "fw.h"
37
38static void _rtl8723ae_enable_fw_download(struct ieee80211_hw *hw, bool enable)
39{
40 struct rtl_priv *rtlpriv = rtl_priv(hw);
41 u8 tmp;
42 if (enable) {
43 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
44 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
45
46 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
47 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
48
49 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
50 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
51 } else {
52 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
53 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
54
55 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
56 }
57}
58
59static void _rtl8723ae_fw_block_write(struct ieee80211_hw *hw,
60 const u8 *buffer, u32 size)
61{
62 struct rtl_priv *rtlpriv = rtl_priv(hw);
63 u32 blockSize = sizeof(u32);
64 u8 *bufferPtr = (u8 *) buffer;
65 u32 *pu4BytePtr = (u32 *) buffer;
66 u32 i, offset, blockCount, remainSize;
67
68 blockCount = size / blockSize;
69 remainSize = size % blockSize;
70
71 for (i = 0; i < blockCount; i++) {
72 offset = i * blockSize;
73 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
74 *(pu4BytePtr + i));
75 }
76
77 if (remainSize) {
78 offset = blockCount * blockSize;
79 bufferPtr += offset;
80 for (i = 0; i < remainSize; i++) {
81 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
82 offset + i), *(bufferPtr + i));
83 }
84 }
85}
86
87static void _rtl8723ae_fw_page_write(struct ieee80211_hw *hw,
88 u32 page, const u8 *buffer, u32 size)
89{
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
91 u8 value8;
92 u8 u8page = (u8) (page & 0x07);
93
94 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
95
96 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
97 _rtl8723ae_fw_block_write(hw, buffer, size);
98}
99
100static void _rtl8723ae_write_fw(struct ieee80211_hw *hw,
101 enum version_8723e version, u8 *buffer,
102 u32 size)
103{
104 struct rtl_priv *rtlpriv = rtl_priv(hw);
105 u8 *bufferPtr = (u8 *) buffer;
106 u32 page_nums, remain_size;
107 u32 page, offset;
108
109 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
110
111 page_nums = size / FW_8192C_PAGE_SIZE;
112 remain_size = size % FW_8192C_PAGE_SIZE;
113
114 if (page_nums > 6) {
115 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
116 "Page numbers should not be greater then 6\n");
117 }
118
119 for (page = 0; page < page_nums; page++) {
120 offset = page * FW_8192C_PAGE_SIZE;
121 _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset),
122 FW_8192C_PAGE_SIZE);
123 }
124
125 if (remain_size) {
126 offset = page_nums * FW_8192C_PAGE_SIZE;
127 page = page_nums;
128 _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset),
129 remain_size);
130 }
131
132 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n");
133}
134
135static int _rtl8723ae_fw_free_to_go(struct ieee80211_hw *hw)
136{
137 struct rtl_priv *rtlpriv = rtl_priv(hw);
138 int err = -EIO;
139 u32 counter = 0;
140 u32 value32;
141
142 do {
143 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
144 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
145 (!(value32 & FWDL_ChkSum_rpt)));
146
147 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
148 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
149 "chksum report faill ! REG_MCUFWDL:0x%08x .\n",
150 value32);
151 goto exit;
152 }
153
154 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
155 "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32);
156
157 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
158 value32 |= MCUFWDL_RDY;
159 value32 &= ~WINTINI_RDY;
160 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
161
162 counter = 0;
163
164 do {
165 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
166 if (value32 & WINTINI_RDY) {
167 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
168 "Polling FW ready success!! REG_MCUFWDL:0x%08x .\n",
169 value32);
170 err = 0;
171 goto exit;
172 }
173
174 mdelay(FW_8192C_POLLING_DELAY);
175
176 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
177
178 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
179 "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32);
180
181exit:
182 return err;
183}
184
185int rtl8723ae_download_fw(struct ieee80211_hw *hw)
186{
187 struct rtl_priv *rtlpriv = rtl_priv(hw);
188 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
189 struct rtl8723ae_firmware_header *pfwheader;
190 u8 *pfwdata;
191 u32 fwsize;
192 int err;
193 enum version_8723e version = rtlhal->version;
194
195 if (!rtlhal->pfirmware)
196 return 1;
197
198 pfwheader = (struct rtl8723ae_firmware_header *)rtlhal->pfirmware;
199 pfwdata = (u8 *) rtlhal->pfirmware;
200 fwsize = rtlhal->fwsize;
201
202 if (IS_FW_HEADER_EXIST(pfwheader)) {
203 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
204 "Firmware Version(%d), Signature(%#x),Size(%d)\n",
205 pfwheader->version, pfwheader->signature,
206 (int)sizeof(struct rtl8723ae_firmware_header));
207
208 pfwdata = pfwdata + sizeof(struct rtl8723ae_firmware_header);
209 fwsize = fwsize - sizeof(struct rtl8723ae_firmware_header);
210 }
211
212 if (rtl_read_byte(rtlpriv, REG_MCUFWDL)&BIT(7)) {
213 rtl8723ae_firmware_selfreset(hw);
214 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
215 }
216 _rtl8723ae_enable_fw_download(hw, true);
217 _rtl8723ae_write_fw(hw, version, pfwdata, fwsize);
218 _rtl8723ae_enable_fw_download(hw, false);
219
220 err = _rtl8723ae_fw_free_to_go(hw);
221 if (err) {
222 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
223 "Firmware is not ready to run!\n");
224 } else {
225 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
226 "Firmware is ready to run!\n");
227 }
228 return 0;
229}
230
231static bool rtl8723ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
232{
233 struct rtl_priv *rtlpriv = rtl_priv(hw);
234 u8 val_hmetfr, val_mcutst_1;
235 bool result = false;
236
237 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
238 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
239
240 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
241 result = true;
242 return result;
243}
244
245static void _rtl8723ae_fill_h2c_command(struct ieee80211_hw *hw,
246 u8 element_id, u32 cmd_len,
247 u8 *p_cmdbuffer)
248{
249 struct rtl_priv *rtlpriv = rtl_priv(hw);
250 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
251 u8 boxnum;
252 u16 box_reg = 0, box_extreg = 0;
253 u8 u1tmp;
254 bool isfw_rd = false;
255 bool bwrite_sucess = false;
256 u8 wait_h2c_limmit = 100;
257 u8 wait_writeh2c_limmit = 100;
258 u8 boxcontent[4], boxextcontent[2];
259 u32 h2c_waitcounter = 0;
260 unsigned long flag;
261 u8 idx;
262
263 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
264
265 while (true) {
266 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
267 if (rtlhal->h2c_setinprogress) {
268 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
269 "H2C set in progress! Wait to set..element_id(%d).\n",
270 element_id);
271
272 while (rtlhal->h2c_setinprogress) {
273 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
274 flag);
275 h2c_waitcounter++;
276 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
277 "Wait 100 us (%d times)...\n",
278 h2c_waitcounter);
279 udelay(100);
280
281 if (h2c_waitcounter > 1000)
282 return;
283 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
284 flag);
285 }
286 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
287 } else {
288 rtlhal->h2c_setinprogress = true;
289 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
290 break;
291 }
292 }
293
294 while (!bwrite_sucess) {
295 wait_writeh2c_limmit--;
296 if (wait_writeh2c_limmit == 0) {
297 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
298 "Write H2C fail because no trigger "
299 "for FW INT!\n");
300 break;
301 }
302
303 boxnum = rtlhal->last_hmeboxnum;
304 switch (boxnum) {
305 case 0:
306 box_reg = REG_HMEBOX_0;
307 box_extreg = REG_HMEBOX_EXT_0;
308 break;
309 case 1:
310 box_reg = REG_HMEBOX_1;
311 box_extreg = REG_HMEBOX_EXT_1;
312 break;
313 case 2:
314 box_reg = REG_HMEBOX_2;
315 box_extreg = REG_HMEBOX_EXT_2;
316 break;
317 case 3:
318 box_reg = REG_HMEBOX_3;
319 box_extreg = REG_HMEBOX_EXT_3;
320 break;
321 default:
322 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
323 "switch case not processed\n");
324 break;
325 }
326
327 isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum);
328 while (!isfw_rd) {
329
330 wait_h2c_limmit--;
331 if (wait_h2c_limmit == 0) {
332 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
333 "Wating too long for FW read clear HMEBox(%d)!\n",
334 boxnum);
335 break;
336 }
337
338 udelay(10);
339
340 isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum);
341 u1tmp = rtl_read_byte(rtlpriv, 0x1BF);
342 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
343 "Wating for FW read clear HMEBox(%d)!!! "
344 "0x1BF = %2x\n", boxnum, u1tmp);
345 }
346
347 if (!isfw_rd) {
348 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
349 "Write H2C register BOX[%d] fail!!!!! "
350 "Fw do not read.\n", boxnum);
351 break;
352 }
353
354 memset(boxcontent, 0, sizeof(boxcontent));
355 memset(boxextcontent, 0, sizeof(boxextcontent));
356 boxcontent[0] = element_id;
357 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
358 "Write element_id box_reg(%4x) = %2x\n",
359 box_reg, element_id);
360
361 switch (cmd_len) {
362 case 1:
363 boxcontent[0] &= ~(BIT(7));
364 memcpy((u8 *) (boxcontent) + 1,
365 p_cmdbuffer, 1);
366
367 for (idx = 0; idx < 4; idx++) {
368 rtl_write_byte(rtlpriv, box_reg + idx,
369 boxcontent[idx]);
370 }
371 break;
372 case 2:
373 boxcontent[0] &= ~(BIT(7));
374 memcpy((u8 *) (boxcontent) + 1,
375 p_cmdbuffer, 2);
376
377 for (idx = 0; idx < 4; idx++) {
378 rtl_write_byte(rtlpriv, box_reg + idx,
379 boxcontent[idx]);
380 }
381 break;
382 case 3:
383 boxcontent[0] &= ~(BIT(7));
384 memcpy((u8 *) (boxcontent) + 1,
385 p_cmdbuffer, 3);
386
387 for (idx = 0; idx < 4; idx++) {
388 rtl_write_byte(rtlpriv, box_reg + idx,
389 boxcontent[idx]);
390 }
391 break;
392 case 4:
393 boxcontent[0] |= (BIT(7));
394 memcpy((u8 *) (boxextcontent),
395 p_cmdbuffer, 2);
396 memcpy((u8 *) (boxcontent) + 1,
397 p_cmdbuffer + 2, 2);
398
399 for (idx = 0; idx < 2; idx++) {
400 rtl_write_byte(rtlpriv, box_extreg + idx,
401 boxextcontent[idx]);
402 }
403
404 for (idx = 0; idx < 4; idx++) {
405 rtl_write_byte(rtlpriv, box_reg + idx,
406 boxcontent[idx]);
407 }
408 break;
409 case 5:
410 boxcontent[0] |= (BIT(7));
411 memcpy((u8 *) (boxextcontent),
412 p_cmdbuffer, 2);
413 memcpy((u8 *) (boxcontent) + 1,
414 p_cmdbuffer + 2, 3);
415
416 for (idx = 0; idx < 2; idx++) {
417 rtl_write_byte(rtlpriv, box_extreg + idx,
418 boxextcontent[idx]);
419 }
420
421 for (idx = 0; idx < 4; idx++) {
422 rtl_write_byte(rtlpriv, box_reg + idx,
423 boxcontent[idx]);
424 }
425 break;
426 default:
427 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
428 "switch case not process\n");
429 break;
430 }
431
432 bwrite_sucess = true;
433
434 rtlhal->last_hmeboxnum = boxnum + 1;
435 if (rtlhal->last_hmeboxnum == 4)
436 rtlhal->last_hmeboxnum = 0;
437
438 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
439 "pHalData->last_hmeboxnum = %d\n",
440 rtlhal->last_hmeboxnum);
441 }
442
443 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
444 rtlhal->h2c_setinprogress = false;
445 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
446
447 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
448}
449
450void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw,
451 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
452{
453 struct rtl_priv *rtlpriv = rtl_priv(hw);
454 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
455
456 if (rtlhal->fw_ready == false) {
457 RT_ASSERT(false,
458 "return H2C cmd because of Fw download fail!!!\n");
459 return;
460 }
461
462 _rtl8723ae_fill_h2c_command(hw, element_id, cmd_len, p_cmdbuffer);
463 return;
464}
465
466void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw)
467{
468 u8 u1tmp;
469 u8 delay = 100;
470 struct rtl_priv *rtlpriv = rtl_priv(hw);
471
472 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
473 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
474
475 while (u1tmp & BIT(2)) {
476 delay--;
477 if (delay == 0)
478 break;
479 udelay(50);
480 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
481 }
482 if (delay == 0) {
483 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
484 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1tmp&(~BIT(2)));
485 }
486}
487
488void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
489{
490 struct rtl_priv *rtlpriv = rtl_priv(hw);
491 u8 u1_h2c_set_pwrmode[3] = { 0 };
492 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
493
494 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
495
496 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
497 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
498 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
499 ppsc->reg_max_lps_awakeintvl);
500
501 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
502 "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
503 u1_h2c_set_pwrmode, 3);
504 rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
505
506}
507
508static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw,
509 struct sk_buff *skb)
510{
511 struct rtl_priv *rtlpriv = rtl_priv(hw);
512 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
513 struct rtl8192_tx_ring *ring;
514 struct rtl_tx_desc *pdesc;
515 u8 own;
516 unsigned long flags;
517 struct sk_buff *pskb = NULL;
518
519 ring = &rtlpci->tx_ring[BEACON_QUEUE];
520
521 pskb = __skb_dequeue(&ring->queue);
522 if (pskb)
523 kfree_skb(pskb);
524
525 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
526
527 pdesc = &ring->desc[0];
528 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
529
530 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
531
532 __skb_queue_tail(&ring->queue, skb);
533
534 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
535
536 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
537
538 return true;
539}
540
541static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
542 /* page 0 beacon */
543 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
544 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
545 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
548 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
549 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
550 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
551 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
552 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
553 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
557 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559
560 /* page 1 beacon */
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577
578 /* page 2 ps-poll */
579 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
580 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
593 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595
596 /* page 3 null */
597 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
598 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
599 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
611 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613
614 /* page 4 probe_resp */
615 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
616 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
617 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
618 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
619 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
620 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
621 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
622 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
623 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
624 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
625 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
629 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631
632 /* page 5 probe_resp */
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649};
650
651void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
652{
653 struct rtl_priv *rtlpriv = rtl_priv(hw);
654 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
655 struct sk_buff *skb = NULL;
656
657 u32 totalpacketlen;
658 bool rtstatus;
659 u8 u1RsvdPageLoc[3] = { 0 };
660 bool dlok = false;
661
662 u8 *beacon;
663 u8 *p_pspoll;
664 u8 *nullfunc;
665 u8 *p_probersp;
666 /*---------------------------------------------------------
667 (1) beacon
668 ---------------------------------------------------------
669 */
670 beacon = &reserved_page_packet[BEACON_PG * 128];
671 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
672 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
673
674 /*-------------------------------------------------------
675 (2) ps-poll
676 --------------------------------------------------------
677 */
678 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
679 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
680 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
681 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
682
683 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
684
685 /*--------------------------------------------------------
686 (3) null data
687 ---------------------------------------------------------i
688 */
689 nullfunc = &reserved_page_packet[NULL_PG * 128];
690 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
691 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
692 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
693
694 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
695
696 /*---------------------------------------------------------
697 (4) probe response
698 ----------------------------------------------------------
699 */
700 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
701 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
702 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
703 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
704
705 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
706
707 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
708
709 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
710 "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
711 &reserved_page_packet[0], totalpacketlen);
712 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
713 "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
714 u1RsvdPageLoc, 3);
715
716 skb = dev_alloc_skb(totalpacketlen);
717 memcpy((u8 *) skb_put(skb, totalpacketlen),
718 &reserved_page_packet, totalpacketlen);
719
720 rtstatus = _rtl8723ae_cmd_send_packet(hw, skb);
721
722 if (rtstatus)
723 dlok = true;
724
725 if (dlok) {
726 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
727 "Set RSVD page location to Fw.\n");
728 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
729 "H2C_RSVDPAGE:\n",
730 u1RsvdPageLoc, 3);
731 rtl8723ae_fill_h2c_cmd(hw, H2C_RSVDPAGE,
732 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
733 } else
734 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
735 "Set RSVD page location to Fw FAIL!!!!!!.\n");
736}
737
738void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
739{
740 u8 u1_joinbssrpt_parm[1] = { 0 };
741
742 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
743
744 rtl8723ae_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
745}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
new file mode 100644
index 000000000000..89994e16dc83
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
@@ -0,0 +1,101 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 * Larry Finger <Larry.Finger@lwfinger.net>
26 *
27 ****************************************************************************
28 */
29
30#ifndef __RTL92C__FW__H__
31#define __RTL92C__FW__H__
32
33#define FW_8192C_START_ADDRESS 0x1000
34#define FW_8192C_END_ADDRESS 0x3FFF
35#define FW_8192C_PAGE_SIZE 4096
36#define FW_8192C_POLLING_DELAY 5
37#define FW_8192C_POLLING_TIMEOUT_COUNT 1000
38
39#define BEACON_PG 0
40#define PSPOLL_PG 2
41#define NULL_PG 3
42#define PROBERSP_PG 4 /* ->5 */
43
44#define TOTAL_RESERVED_PKT_LEN 768
45
46#define IS_FW_HEADER_EXIST(_pfwhdr) \
47 ((_pfwhdr->signature&0xFF00) == 0x2300)
48
49struct rtl8723ae_firmware_header {
50 u16 signature;
51 u8 category;
52 u8 function;
53 u16 version;
54 u8 subversion;
55 u8 rsvd1;
56 u8 month;
57 u8 date;
58 u8 hour;
59 u8 minute;
60 u16 ramcodeSize;
61 u16 rsvd2;
62 u32 svnindex;
63 u32 rsvd3;
64 u32 rsvd4;
65 u32 rsvd5;
66};
67
68enum rtl8192c_h2c_cmd {
69 H2C_AP_OFFLOAD = 0,
70 H2C_SETPWRMODE = 1,
71 H2C_JOINBSSRPT = 2,
72 H2C_RSVDPAGE = 3,
73 H2C_RSSI_REPORT = 5,
74 H2C_RA_MASK = 6,
75 MAX_H2CCMD
76};
77
78#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
79 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
80#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \
81 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
82#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \
83 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
84#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
85 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
86#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
87 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
88#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
89 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
90#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
91 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
92
93int rtl8723ae_download_fw(struct ieee80211_hw *hw);
94void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
95 u32 cmd_len, u8 *p_cmdbuffer);
96void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw);
97void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
98void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
99void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
100
101#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c
new file mode 100644
index 000000000000..3d092e4b0b7f
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c
@@ -0,0 +1,542 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 "hal_bt_coexist.h"
31#include "../pci.h"
32#include "dm.h"
33#include "fw.h"
34#include "phy.h"
35#include "reg.h"
36#include "hal_btc.h"
37
38void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw,
39 bool reject)
40{
41}
42
43void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw)
44{
45 struct rtl_priv *rtlpriv = rtl_priv(hw);
46 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
47 struct rtl_phy *rtlphy = &(rtlpriv->phy);
48
49 if (rtlpriv->link_info.busytraffic) {
50 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_IDLE;
51
52 if (rtlpriv->link_info.tx_busy_traffic)
53 rtlpcipriv->bt_coexist.cstate |=
54 BT_COEX_STATE_WIFI_UPLINK;
55 else
56 rtlpcipriv->bt_coexist.cstate &=
57 ~BT_COEX_STATE_WIFI_UPLINK;
58
59 if (rtlpriv->link_info.rx_busy_traffic)
60 rtlpcipriv->bt_coexist.cstate |=
61 BT_COEX_STATE_WIFI_DOWNLINK;
62 else
63 rtlpcipriv->bt_coexist.cstate &=
64 ~BT_COEX_STATE_WIFI_DOWNLINK;
65 } else {
66 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_IDLE;
67 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_UPLINK;
68 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_DOWNLINK;
69 }
70
71 if (rtlpriv->mac80211.mode == WIRELESS_MODE_G ||
72 rtlpriv->mac80211.mode == WIRELESS_MODE_B) {
73 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_LEGACY;
74 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT20;
75 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT40;
76 } else {
77 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_LEGACY;
78 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
79 rtlpcipriv->bt_coexist.cstate |=
80 BT_COEX_STATE_WIFI_HT40;
81 rtlpcipriv->bt_coexist.cstate &=
82 ~BT_COEX_STATE_WIFI_HT20;
83 } else {
84 rtlpcipriv->bt_coexist.cstate |=
85 BT_COEX_STATE_WIFI_HT20;
86 rtlpcipriv->bt_coexist.cstate &=
87 ~BT_COEX_STATE_WIFI_HT40;
88 }
89 }
90
91 if (rtlpriv->bt_operation_on)
92 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BT30;
93 else
94 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_BT30;
95}
96
97u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw,
98 u8 level_num, u8 rssi_thresh,
99 u8 rssi_thresh1)
100
101{
102 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
103 struct rtl_priv *rtlpriv = rtl_priv(hw);
104 long smooth;
105 u8 bt_rssi_state = 0;
106
107 smooth = rtl8723ae_dm_bt_get_rx_ss(hw);
108
109 if (level_num == 2) {
110 rtlpcipriv->bt_coexist.cstate &=
111 ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
112
113 if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
114 BT_RSSI_STATE_LOW) ||
115 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
116 BT_RSSI_STATE_STAY_LOW)) {
117 if (smooth >= (rssi_thresh +
118 BT_FW_COEX_THRESH_TOL)) {
119 bt_rssi_state = BT_RSSI_STATE_HIGH;
120 rtlpcipriv->bt_coexist.cstate |=
121 BT_COEX_STATE_WIFI_RSSI_1_HIGH;
122 rtlpcipriv->bt_coexist.cstate &=
123 ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
124 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
125 "[DM][BT], RSSI_1 state switch to High\n");
126 } else {
127 bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
128 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
129 "[DM][BT], RSSI_1 state stay at Low\n");
130 }
131 } else {
132 if (smooth < rssi_thresh) {
133 bt_rssi_state = BT_RSSI_STATE_LOW;
134 rtlpcipriv->bt_coexist.cstate |=
135 BT_COEX_STATE_WIFI_RSSI_1_LOW;
136 rtlpcipriv->bt_coexist.cstate &=
137 ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
138 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
139 "[DM][BT], RSSI_1 state switch to Low\n");
140 } else {
141 bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
142 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
143 "[DM][BT], RSSI_1 state stay at High\n");
144 }
145 }
146 } else if (level_num == 3) {
147 if (rssi_thresh > rssi_thresh1) {
148 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
149 "[DM][BT], RSSI_1 thresh error!!\n");
150 return rtlpcipriv->bt_coexist.bt_pre_rssi_state;
151 }
152
153 if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
154 BT_RSSI_STATE_LOW) ||
155 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
156 BT_RSSI_STATE_STAY_LOW)) {
157 if (smooth >=
158 (rssi_thresh+BT_FW_COEX_THRESH_TOL)) {
159 bt_rssi_state = BT_RSSI_STATE_MEDIUM;
160 rtlpcipriv->bt_coexist.cstate |=
161 BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
162 rtlpcipriv->bt_coexist.cstate &=
163 ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
164 rtlpcipriv->bt_coexist.cstate &=
165 ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
166 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
167 "[DM][BT], RSSI_1 state switch to Medium\n");
168 } else {
169 bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
170 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
171 "[DM][BT], RSSI_1 state stay at Low\n");
172 }
173 } else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
174 BT_RSSI_STATE_MEDIUM) ||
175 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
176 BT_RSSI_STATE_STAY_MEDIUM)) {
177 if (smooth >= (rssi_thresh1 +
178 BT_FW_COEX_THRESH_TOL)) {
179 bt_rssi_state = BT_RSSI_STATE_HIGH;
180 rtlpcipriv->bt_coexist.cstate |=
181 BT_COEX_STATE_WIFI_RSSI_1_HIGH;
182 rtlpcipriv->bt_coexist.cstate &=
183 ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
184 rtlpcipriv->bt_coexist.cstate &=
185 ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
186 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
187 "[DM][BT], RSSI_1 state switch to High\n");
188 } else if (smooth < rssi_thresh) {
189 bt_rssi_state = BT_RSSI_STATE_LOW;
190 rtlpcipriv->bt_coexist.cstate |=
191 BT_COEX_STATE_WIFI_RSSI_1_LOW;
192 rtlpcipriv->bt_coexist.cstate &=
193 ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
194 rtlpcipriv->bt_coexist.cstate &=
195 ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
196 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
197 "[DM][BT], RSSI_1 state switch to Low\n");
198 } else {
199 bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
200 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
201 "[DM][BT], RSSI_1 state stay at Medium\n");
202 }
203 } else {
204 if (smooth < rssi_thresh1) {
205 bt_rssi_state = BT_RSSI_STATE_MEDIUM;
206 rtlpcipriv->bt_coexist.cstate |=
207 BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
208 rtlpcipriv->bt_coexist.cstate &=
209 ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
210 rtlpcipriv->bt_coexist.cstate &=
211 ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
212 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
213 "[DM][BT], RSSI_1 state switch to Medium\n");
214 } else {
215 bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
216 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
217 "[DM][BT], RSSI_1 state stay at High\n");
218 }
219 }
220 }
221
222 rtlpcipriv->bt_coexist.bt_pre_rssi_state1 = bt_rssi_state;
223
224 return bt_rssi_state;
225}
226
227u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw,
228 u8 level_num, u8 rssi_thresh,
229 u8 rssi_thresh1)
230{
231 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
232 struct rtl_priv *rtlpriv = rtl_priv(hw);
233 long smooth;
234 u8 bt_rssi_state = 0;
235
236 smooth = rtl8723ae_dm_bt_get_rx_ss(hw);
237
238 if (level_num == 2) {
239 rtlpcipriv->bt_coexist.cstate &=
240 ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
241
242 if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
243 BT_RSSI_STATE_LOW) ||
244 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
245 BT_RSSI_STATE_STAY_LOW)){
246 if (smooth >=
247 (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
248 bt_rssi_state = BT_RSSI_STATE_HIGH;
249 rtlpcipriv->bt_coexist.cstate |=
250 BT_COEX_STATE_WIFI_RSSI_HIGH;
251 rtlpcipriv->bt_coexist.cstate &=
252 ~BT_COEX_STATE_WIFI_RSSI_LOW;
253 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
254 "[DM][BT], RSSI state switch to High\n");
255 } else {
256 bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
257 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
258 "[DM][BT], RSSI state stay at Low\n");
259 }
260 } else {
261 if (smooth < rssi_thresh) {
262 bt_rssi_state = BT_RSSI_STATE_LOW;
263 rtlpcipriv->bt_coexist.cstate |=
264 BT_COEX_STATE_WIFI_RSSI_LOW;
265 rtlpcipriv->bt_coexist.cstate &=
266 ~BT_COEX_STATE_WIFI_RSSI_HIGH;
267 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
268 "[DM][BT], RSSI state switch to Low\n");
269 } else {
270 bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
271 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
272 "[DM][BT], RSSI state stay at High\n");
273 }
274 }
275 } else if (level_num == 3) {
276 if (rssi_thresh > rssi_thresh1) {
277 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
278 "[DM][BT], RSSI thresh error!!\n");
279 return rtlpcipriv->bt_coexist.bt_pre_rssi_state;
280 }
281 if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
282 BT_RSSI_STATE_LOW) ||
283 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
284 BT_RSSI_STATE_STAY_LOW)) {
285 if (smooth >=
286 (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
287 bt_rssi_state = BT_RSSI_STATE_MEDIUM;
288 rtlpcipriv->bt_coexist.cstate
289 |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
290 rtlpcipriv->bt_coexist.cstate
291 &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
292 rtlpcipriv->bt_coexist.cstate
293 &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
294 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
295 "[DM][BT], RSSI state switch to Medium\n");
296 } else {
297 bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
298 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
299 "[DM][BT], RSSI state stay at Low\n");
300 }
301 } else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
302 BT_RSSI_STATE_MEDIUM) ||
303 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
304 BT_RSSI_STATE_STAY_MEDIUM)) {
305 if (smooth >=
306 (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) {
307 bt_rssi_state = BT_RSSI_STATE_HIGH;
308 rtlpcipriv->bt_coexist.cstate
309 |= BT_COEX_STATE_WIFI_RSSI_HIGH;
310 rtlpcipriv->bt_coexist.cstate
311 &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
312 rtlpcipriv->bt_coexist.cstate
313 &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
314 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
315 "[DM][BT], RSSI state switch to High\n");
316 } else if (smooth < rssi_thresh) {
317 bt_rssi_state = BT_RSSI_STATE_LOW;
318 rtlpcipriv->bt_coexist.cstate
319 |= BT_COEX_STATE_WIFI_RSSI_LOW;
320 rtlpcipriv->bt_coexist.cstate
321 &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
322 rtlpcipriv->bt_coexist.cstate
323 &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
324 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
325 "[DM][BT], RSSI state switch to Low\n");
326 } else {
327 bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
328 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
329 "[DM][BT], RSSI state stay at Medium\n");
330 }
331 } else {
332 if (smooth < rssi_thresh1) {
333 bt_rssi_state = BT_RSSI_STATE_MEDIUM;
334 rtlpcipriv->bt_coexist.cstate
335 |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
336 rtlpcipriv->bt_coexist.cstate
337 &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
338 rtlpcipriv->bt_coexist.cstate
339 &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
340 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
341 "[DM][BT], RSSI state switch to Medium\n");
342 } else {
343 bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
344 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
345 "[DM][BT], RSSI state stay at High\n");
346 }
347 }
348 }
349
350 rtlpcipriv->bt_coexist.bt_pre_rssi_state = bt_rssi_state;
351 return bt_rssi_state;
352}
353
354long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw)
355{
356 struct rtl_priv *rtlpriv = rtl_priv(hw);
357 long smooth = 0;
358
359 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
360 smooth = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv);
361 else
362 smooth = rtlpriv->dm.entry_min_undec_sm_pwdb;
363
364 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
365 "rtl8723ae_dm_bt_get_rx_ss() = %ld\n", smooth);
366
367 return smooth;
368}
369
370void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw,
371 bool balance_on, u8 ms0, u8 ms1)
372{
373 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
374 struct rtl_priv *rtlpriv = rtl_priv(hw);
375 u8 h2c_parameter[3] = {0};
376
377 if (balance_on) {
378 h2c_parameter[2] = 1;
379 h2c_parameter[1] = ms1;
380 h2c_parameter[0] = ms0;
381 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
382 } else {
383 h2c_parameter[2] = 0;
384 h2c_parameter[1] = 0;
385 h2c_parameter[0] = 0;
386 }
387 rtlpcipriv->bt_coexist.balance_on = balance_on;
388
389 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
390 "[DM][BT], Balance=[%s:%dms:%dms], write 0xc=0x%x\n",
391 balance_on ? "ON" : "OFF", ms0, ms1,
392 h2c_parameter[0]<<16 | h2c_parameter[1]<<8 | h2c_parameter[2]);
393
394 rtl8723ae_fill_h2c_cmd(hw, 0xc, 3, h2c_parameter);
395}
396
397
398void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type)
399{
400 struct rtl_priv *rtlpriv = rtl_priv(hw);
401 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
402
403 if (type == BT_AGCTABLE_OFF) {
404 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
405 "[BT]AGCTable Off!\n");
406 rtl_write_dword(rtlpriv, 0xc78, 0x641c0001);
407 rtl_write_dword(rtlpriv, 0xc78, 0x631d0001);
408 rtl_write_dword(rtlpriv, 0xc78, 0x621e0001);
409 rtl_write_dword(rtlpriv, 0xc78, 0x611f0001);
410 rtl_write_dword(rtlpriv, 0xc78, 0x60200001);
411
412 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
413 RF_RX_AGC_HP, 0xfffff, 0x32000);
414 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
415 RF_RX_AGC_HP, 0xfffff, 0x71000);
416 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
417 RF_RX_AGC_HP, 0xfffff, 0xb0000);
418 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
419 RF_RX_AGC_HP, 0xfffff, 0xfc000);
420 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
421 RF_RX_G1, 0xfffff, 0x30355);
422 } else if (type == BT_AGCTABLE_ON) {
423 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
424 "[BT]AGCTable On!\n");
425 rtl_write_dword(rtlpriv, 0xc78, 0x4e1c0001);
426 rtl_write_dword(rtlpriv, 0xc78, 0x4d1d0001);
427 rtl_write_dword(rtlpriv, 0xc78, 0x4c1e0001);
428 rtl_write_dword(rtlpriv, 0xc78, 0x4b1f0001);
429 rtl_write_dword(rtlpriv, 0xc78, 0x4a200001);
430
431 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
432 RF_RX_AGC_HP, 0xfffff, 0xdc000);
433 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
434 RF_RX_AGC_HP, 0xfffff, 0x90000);
435 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
436 RF_RX_AGC_HP, 0xfffff, 0x51000);
437 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
438 RF_RX_AGC_HP, 0xfffff, 0x12000);
439 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
440 RF_RX_G1, 0xfffff, 0x00355);
441
442 rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
443 }
444}
445
446void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type)
447{
448 struct rtl_priv *rtlpriv = rtl_priv(hw);
449 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
450
451 if (type == BT_BB_BACKOFF_OFF) {
452 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
453 "[BT]BBBackOffLevel Off!\n");
454 rtl_write_dword(rtlpriv, 0xc04, 0x3a05611);
455 } else if (type == BT_BB_BACKOFF_ON) {
456 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
457 "[BT]BBBackOffLevel On!\n");
458 rtl_write_dword(rtlpriv, 0xc04, 0x3a07611);
459 rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
460 }
461}
462
463void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw)
464{
465 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
466 struct rtl_priv *rtlpriv = rtl_priv(hw);
467 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
468 "rtl8723ae_dm_bt_fw_coex_all_off()\n");
469
470 if (rtlpcipriv->bt_coexist.fw_coexist_all_off)
471 return;
472
473 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
474 "rtl8723ae_dm_bt_fw_coex_all_off(), real Do\n");
475 rtl8723ae_dm_bt_fw_coex_all_off_8723a(hw);
476 rtlpcipriv->bt_coexist.fw_coexist_all_off = true;
477}
478
479void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw)
480{
481 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
482 struct rtl_priv *rtlpriv = rtl_priv(hw);
483
484 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
485 "rtl8723ae_dm_bt_sw_coex_all_off()\n");
486
487 if (rtlpcipriv->bt_coexist.sw_coexist_all_off)
488 return;
489
490 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
491 "rtl8723ae_dm_bt_sw_coex_all_off(), real Do\n");
492 rtl8723ae_dm_bt_sw_coex_all_off_8723a(hw);
493 rtlpcipriv->bt_coexist.sw_coexist_all_off = true;
494}
495
496void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw)
497{
498 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
499 struct rtl_priv *rtlpriv = rtl_priv(hw);
500
501 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
502 "rtl8723ae_dm_bt_hw_coex_all_off()\n");
503
504 if (rtlpcipriv->bt_coexist.hw_coexist_all_off)
505 return;
506 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
507 "rtl8723ae_dm_bt_hw_coex_all_off(), real Do\n");
508
509 rtl8723ae_dm_bt_hw_coex_all_off_8723a(hw);
510
511 rtlpcipriv->bt_coexist.hw_coexist_all_off = true;
512}
513
514void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw)
515{
516 rtl8723ae_dm_bt_fw_coex_all_off(hw);
517 rtl8723ae_dm_bt_sw_coex_all_off(hw);
518 rtl8723ae_dm_bt_hw_coex_all_off(hw);
519}
520
521bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw)
522{
523 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
524
525 if ((rtlpcipriv->bt_coexist.previous_state ==
526 rtlpcipriv->bt_coexist.cstate) &&
527 (rtlpcipriv->bt_coexist.previous_state_h ==
528 rtlpcipriv->bt_coexist.cstate_h))
529 return false;
530 else
531 return true;
532}
533
534bool rtl8723ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw)
535{
536 struct rtl_priv *rtlpriv = rtl_priv(hw);
537
538 if (rtlpriv->link_info.tx_busy_traffic)
539 return true;
540 else
541 return false;
542}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h
new file mode 100644
index 000000000000..76f4d122dbc1
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h
@@ -0,0 +1,160 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 * Larry Finger <Larry.Finger@lwfinger.net>
26 *
27 *****************************************************************************/
28
29#ifndef __RTL8723E_HAL_BT_COEXIST_H__
30#define __RTL8723E_HAL_BT_COEXIST_H__
31
32#include "../wifi.h"
33
34/* The reg define is for 8723 */
35#define REG_HIGH_PRIORITY_TXRX 0x770
36#define REG_LOW_PRIORITY_TXRX 0x774
37
38#define BT_FW_COEX_THRESH_TOL 6
39#define BT_FW_COEX_THRESH_20 20
40#define BT_FW_COEX_THRESH_23 23
41#define BT_FW_COEX_THRESH_25 25
42#define BT_FW_COEX_THRESH_30 30
43#define BT_FW_COEX_THRESH_35 35
44#define BT_FW_COEX_THRESH_40 40
45#define BT_FW_COEX_THRESH_45 45
46#define BT_FW_COEX_THRESH_47 47
47#define BT_FW_COEX_THRESH_50 50
48#define BT_FW_COEX_THRESH_55 55
49
50#define BT_COEX_STATE_BT30 BIT(0)
51#define BT_COEX_STATE_WIFI_HT20 BIT(1)
52#define BT_COEX_STATE_WIFI_HT40 BIT(2)
53#define BT_COEX_STATE_WIFI_LEGACY BIT(3)
54
55#define BT_COEX_STATE_WIFI_RSSI_LOW BIT(4)
56#define BT_COEX_STATE_WIFI_RSSI_MEDIUM BIT(5)
57#define BT_COEX_STATE_WIFI_RSSI_HIGH BIT(6)
58#define BT_COEX_STATE_DEC_BT_POWER BIT(7)
59
60#define BT_COEX_STATE_WIFI_IDLE BIT(8)
61#define BT_COEX_STATE_WIFI_UPLINK BIT(9)
62#define BT_COEX_STATE_WIFI_DOWNLINK BIT(10)
63
64#define BT_COEX_STATE_BT_INQ_PAGE BIT(11)
65#define BT_COEX_STATE_BT_IDLE BIT(12)
66#define BT_COEX_STATE_BT_UPLINK BIT(13)
67#define BT_COEX_STATE_BT_DOWNLINK BIT(14)
68
69#define BT_COEX_STATE_HOLD_FOR_BT_OPERATION BIT(15)
70#define BT_COEX_STATE_BT_RSSI_LOW BIT(19)
71
72#define BT_COEX_STATE_PROFILE_HID BIT(20)
73#define BT_COEX_STATE_PROFILE_A2DP BIT(21)
74#define BT_COEX_STATE_PROFILE_PAN BIT(22)
75#define BT_COEX_STATE_PROFILE_SCO BIT(23)
76
77#define BT_COEX_STATE_WIFI_RSSI_1_LOW BIT(24)
78#define BT_COEX_STATE_WIFI_RSSI_1_MEDIUM BIT(25)
79#define BT_COEX_STATE_WIFI_RSSI_1_HIGH BIT(26)
80
81#define BT_COEX_STATE_BTINFO_COMMON BIT(30)
82#define BT_COEX_STATE_BTINFO_B_HID_SCOESCO BIT(31)
83#define BT_COEX_STATE_BTINFO_B_FTP_A2DP BIT(29)
84
85#define BT_COEX_STATE_BT_CNT_LEVEL_0 BIT(0)
86#define BT_COEX_STATE_BT_CNT_LEVEL_1 BIT(1)
87#define BT_COEX_STATE_BT_CNT_LEVEL_2 BIT(2)
88#define BT_COEX_STATE_BT_CNT_LEVEL_3 BIT(3)
89
90#define BT_RSSI_STATE_HIGH 0
91#define BT_RSSI_STATE_MEDIUM 1
92#define BT_RSSI_STATE_LOW 2
93#define BT_RSSI_STATE_STAY_HIGH 3
94#define BT_RSSI_STATE_STAY_MEDIUM 4
95#define BT_RSSI_STATE_STAY_LOW 5
96
97#define BT_AGCTABLE_OFF 0
98#define BT_AGCTABLE_ON 1
99#define BT_BB_BACKOFF_OFF 0
100#define BT_BB_BACKOFF_ON 1
101#define BT_FW_NAV_OFF 0
102#define BT_FW_NAV_ON 1
103
104#define BT_COEX_MECH_NONE 0
105#define BT_COEX_MECH_SCO 1
106#define BT_COEX_MECH_HID 2
107#define BT_COEX_MECH_A2DP 3
108#define BT_COEX_MECH_PAN 4
109#define BT_COEX_MECH_HID_A2DP 5
110#define BT_COEX_MECH_HID_PAN 6
111#define BT_COEX_MECH_PAN_A2DP 7
112#define BT_COEX_MECH_HID_SCO_ESCO 8
113#define BT_COEX_MECH_FTP_A2DP 9
114#define BT_COEX_MECH_COMMON 10
115#define BT_COEX_MECH_MAX 11
116
117#define BT_DBG_PROFILE_NONE 0
118#define BT_DBG_PROFILE_SCO 1
119#define BT_DBG_PROFILE_HID 2
120#define BT_DBG_PROFILE_A2DP 3
121#define BT_DBG_PROFILE_PAN 4
122#define BT_DBG_PROFILE_HID_A2DP 5
123#define BT_DBG_PROFILE_HID_PAN 6
124#define BT_DBG_PROFILE_PAN_A2DP 7
125#define BT_DBG_PROFILE_MAX 9
126
127#define BTINFO_B_FTP BIT(7)
128#define BTINFO_B_A2DP BIT(6)
129#define BTINFO_B_HID BIT(5)
130#define BTINFO_B_SCO_BUSY BIT(4)
131#define BTINFO_B_ACL_BUSY BIT(3)
132#define BTINFO_B_INQ_PAGE BIT(2)
133#define BTINFO_B_SCO_ESCO BIT(1)
134#define BTINFO_B_CONNECTION BIT(0)
135
136
137void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw);
138void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw);
139
140void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw);
141void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw);
142long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw);
143void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw,
144 bool balance_on, u8 ms0, u8 ms1);
145void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type);
146void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type);
147u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw,
148 u8 level_num, u8 rssi_thresh,
149 u8 rssi_thresh1);
150u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw,
151 u8 level_num, u8 rssi_thresh,
152 u8 rssi_thresh1);
153void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw);
154void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw,
155 bool reject);
156
157bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw);
158bool rtl8723ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw);
159
160#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
new file mode 100644
index 000000000000..887d521fe690
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
@@ -0,0 +1,1786 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 "hal_btc.h"
31#include "../pci.h"
32#include "phy.h"
33#include "fw.h"
34#include "reg.h"
35#include "def.h"
36
37void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw)
38{
39 struct rtl_priv *rtlpriv = rtl_priv(hw);
40 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
41 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
42
43 if (!rtlpcipriv->bt_coexist.bt_coexistence)
44 return;
45
46 if (ppsc->inactiveps) {
47 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
48 "[BT][DM], Before enter IPS, turn off all Coexist DM\n");
49 rtlpcipriv->bt_coexist.cstate = 0;
50 rtlpcipriv->bt_coexist.previous_state = 0;
51 rtlpcipriv->bt_coexist.cstate_h = 0;
52 rtlpcipriv->bt_coexist.previous_state_h = 0;
53 rtl8723ae_btdm_coex_all_off(hw);
54 }
55}
56
57static enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw)
58{
59 struct rtl_priv *rtlpriv = rtl_priv(hw);
60 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
61 enum _RT_MEDIA_STATUS m_status = RT_MEDIA_DISCONNECT;
62
63 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
64
65 if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED)
66 m_status = RT_MEDIA_CONNECT;
67
68 return m_status;
69}
70
71void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw,
72 bool mstatus)
73{
74 struct rtl_priv *rtlpriv = rtl_priv(hw);
75 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
76 struct rtl_phy *rtlphy = &(rtlpriv->phy);
77 u8 h2c_parameter[3] = {0};
78 u8 chnl;
79
80 if (!rtlpcipriv->bt_coexist.bt_coexistence)
81 return;
82
83 if (RT_MEDIA_CONNECT == mstatus)
84 h2c_parameter[0] = 0x1; /* 0: disconnected, 1:connected */
85 else
86 h2c_parameter[0] = 0x0;
87
88 if (mgnt_link_status_query(hw)) {
89 chnl = rtlphy->current_channel;
90 h2c_parameter[1] = chnl;
91 }
92
93 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40)
94 h2c_parameter[2] = 0x30;
95 else
96 h2c_parameter[2] = 0x20;
97
98 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
99 "[BTCoex], FW write 0x19 = 0x%x\n",
100 h2c_parameter[0]<<16|h2c_parameter[1]<<8|h2c_parameter[2]);
101
102 rtl8723ae_fill_h2c_cmd(hw, 0x19, 3, h2c_parameter);
103
104}
105
106static bool rtl8723ae_dm_bt_is_wifi_busy(struct ieee80211_hw *hw)
107{
108 struct rtl_priv *rtlpriv = rtl_priv(hw);
109 if (rtlpriv->link_info.busytraffic ||
110 rtlpriv->link_info.rx_busy_traffic ||
111 rtlpriv->link_info.tx_busy_traffic)
112 return true;
113 else
114 return false;
115}
116
117static void rtl8723ae_dm_bt_set_fw_3a(struct ieee80211_hw *hw,
118 u8 byte1, u8 byte2, u8 byte3,
119 u8 byte4, u8 byte5)
120{
121 struct rtl_priv *rtlpriv = rtl_priv(hw);
122 u8 h2c_parameter[5] = {0};
123
124 h2c_parameter[0] = byte1;
125 h2c_parameter[1] = byte2;
126 h2c_parameter[2] = byte3;
127 h2c_parameter[3] = byte4;
128 h2c_parameter[4] = byte5;
129 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
130 "[BTCoex], FW write 0x3a(4bytes) = 0x%x%8x\n",
131 h2c_parameter[0], h2c_parameter[1]<<24 | h2c_parameter[2]<<16 |
132 h2c_parameter[3]<<8 | h2c_parameter[4]);
133 rtl8723ae_fill_h2c_cmd(hw, 0x3a, 5, h2c_parameter);
134}
135
136static bool rtl8723ae_dm_bt_need_to_dec_bt_pwr(struct ieee80211_hw *hw)
137{
138 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
139 struct rtl_priv *rtlpriv = rtl_priv(hw);
140
141 if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) {
142 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
143 "Need to decrease bt power\n");
144 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_DEC_BT_POWER;
145 return true;
146 }
147
148 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_DEC_BT_POWER;
149 return false;
150}
151
152static bool rtl8723ae_dm_bt_is_same_coexist_state(struct ieee80211_hw *hw)
153{
154 struct rtl_priv *rtlpriv = rtl_priv(hw);
155 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
156
157 if ((rtlpcipriv->bt_coexist.previous_state ==
158 rtlpcipriv->bt_coexist.cstate) &&
159 (rtlpcipriv->bt_coexist.previous_state_h ==
160 rtlpcipriv->bt_coexist.cstate_h)) {
161 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
162 "[DM][BT], Coexist state do not chang!!\n");
163 return true;
164 } else {
165 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
166 "[DM][BT], Coexist state changed!!\n");
167 return false;
168 }
169}
170
171static void rtl8723ae_dm_bt_set_coex_table(struct ieee80211_hw *hw,
172 u32 val_0x6c0, u32 val_0x6c8,
173 u32 val_0x6cc)
174{
175 struct rtl_priv *rtlpriv = rtl_priv(hw);
176
177 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
178 "set coex table, set 0x6c0 = 0x%x\n", val_0x6c0);
179 rtl_write_dword(rtlpriv, 0x6c0, val_0x6c0);
180
181 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
182 "set coex table, set 0x6c8 = 0x%x\n", val_0x6c8);
183 rtl_write_dword(rtlpriv, 0x6c8, val_0x6c8);
184
185 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
186 "set coex table, set 0x6cc = 0x%x\n", val_0x6cc);
187 rtl_write_byte(rtlpriv, 0x6cc, val_0x6cc);
188}
189
190static void rtl8723ae_dm_bt_set_hw_pta_mode(struct ieee80211_hw *hw, bool mode)
191{
192 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
193 struct rtl_priv *rtlpriv = rtl_priv(hw);
194
195 if (BT_PTA_MODE_ON == mode) {
196 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode on, ");
197 /* Enable GPIO 0/1/2/3/8 pins for bt */
198 rtl_write_byte(rtlpriv, 0x40, 0x20);
199 rtlpcipriv->bt_coexist.hw_coexist_all_off = false;
200 } else {
201 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode off\n");
202 rtl_write_byte(rtlpriv, 0x40, 0x0);
203 }
204}
205
206static void rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(struct ieee80211_hw *hw,
207 u8 type)
208{
209 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
210 struct rtl_priv *rtlpriv = rtl_priv(hw);
211
212 if (BT_RF_RX_LPF_CORNER_SHRINK == type) {
213 /* Shrink RF Rx LPF corner, 0x1e[7:4]=1111 ==> [11:4] by Jenyu*/
214 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
215 "Shrink RF Rx LPF corner!!\n");
216 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff,
217 0xf0ff7);
218 rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
219 } else if (BT_RF_RX_LPF_CORNER_RESUME == type) {
220 /*Resume RF Rx LPF corner*/
221 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
222 "Resume RF Rx LPF corner!!\n");
223 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff,
224 rtlpcipriv->bt_coexist.bt_rfreg_origin_1e);
225 }
226}
227
228static void rtl8723ae_bt_set_penalty_tx_rate_adap(struct ieee80211_hw *hw,
229 u8 ra_type)
230{
231 struct rtl_priv *rtlpriv = rtl_priv(hw);
232 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
233 u8 tmu1;
234
235 tmu1 = rtl_read_byte(rtlpriv, 0x4fd);
236 tmu1 |= BIT(0);
237 if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == ra_type) {
238 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
239 "Tx rate adaptive, set low penalty!!\n");
240 tmu1 &= ~BIT(2);
241 rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
242 } else if (BT_TX_RATE_ADAPTIVE_NORMAL == ra_type) {
243 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
244 "Tx rate adaptive, set normal!!\n");
245 tmu1 |= BIT(2);
246 }
247 rtl_write_byte(rtlpriv, 0x4fd, tmu1);
248}
249
250static void rtl8723ae_dm_bt_btdm_structure_reload(struct ieee80211_hw *hw,
251 struct btdm_8723 *btdm)
252{
253 btdm->all_off = false;
254 btdm->agc_table_en = false;
255 btdm->adc_back_off_on = false;
256 btdm->b2_ant_hid_en = false;
257 btdm->low_penalty_rate_adaptive = false;
258 btdm->rf_rx_lpf_shrink = false;
259 btdm->reject_aggre_pkt = false;
260
261 btdm->tdma_on = false;
262 btdm->tdma_ant = TDMA_2ANT;
263 btdm->tdma_nav = TDMA_NAV_OFF;
264 btdm->tdma_dac_swing = TDMA_DAC_SWING_OFF;
265 btdm->fw_dac_swing_lvl = 0x20;
266
267 btdm->tra_tdma_on = false;
268 btdm->tra_tdma_ant = TDMA_2ANT;
269 btdm->tra_tdma_nav = TDMA_NAV_OFF;
270 btdm->ignore_wlan_act = false;
271
272 btdm->ps_tdma_on = false;
273 btdm->ps_tdma_byte[0] = 0x0;
274 btdm->ps_tdma_byte[1] = 0x0;
275 btdm->ps_tdma_byte[2] = 0x0;
276 btdm->ps_tdma_byte[3] = 0x8;
277 btdm->ps_tdma_byte[4] = 0x0;
278
279 btdm->pta_on = true;
280 btdm->val_0x6c0 = 0x5a5aaaaa;
281 btdm->val_0x6c8 = 0xcc;
282 btdm->val_0x6cc = 0x3;
283
284 btdm->sw_dac_swing_on = false;
285 btdm->sw_dac_swing_lvl = 0xc0;
286 btdm->wlan_act_hi = 0x20;
287 btdm->wlan_act_lo = 0x10;
288 btdm->bt_retry_index = 2;
289
290 btdm->dec_bt_pwr = false;
291}
292
293static void dm_bt_btdm_structure_reload_all_off(struct ieee80211_hw *hw,
294 struct btdm_8723 *btdm)
295{
296 rtl8723ae_dm_bt_btdm_structure_reload(hw, btdm);
297 btdm->all_off = true;
298 btdm->pta_on = false;
299 btdm->wlan_act_hi = 0x10;
300}
301
302static bool rtl8723ae_dm_bt_is_2_ant_common_action(struct ieee80211_hw *hw)
303{
304 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
305 struct rtl_priv *rtlpriv = rtl_priv(hw);
306 struct btdm_8723 btdm8723;
307 bool common = false;
308
309 rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723);
310
311 if (!rtl8723ae_dm_bt_is_wifi_busy(hw)
312 && !rtlpcipriv->bt_coexist.bt_busy) {
313 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
314 "Wifi idle + Bt idle, bt coex mechanism always off!!\n");
315 dm_bt_btdm_structure_reload_all_off(hw, &btdm8723);
316 common = true;
317 } else if (rtl8723ae_dm_bt_is_wifi_busy(hw)
318 && !rtlpcipriv->bt_coexist.bt_busy) {
319 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
320 "Wifi non-idle + Bt disabled/idle!!\n");
321 btdm8723.low_penalty_rate_adaptive = true;
322 btdm8723.rf_rx_lpf_shrink = false;
323 btdm8723.reject_aggre_pkt = false;
324
325 /* sw mechanism */
326 btdm8723.agc_table_en = false;
327 btdm8723.adc_back_off_on = false;
328 btdm8723.sw_dac_swing_on = false;
329
330 btdm8723.pta_on = true;
331 btdm8723.val_0x6c0 = 0x5a5aaaaa;
332 btdm8723.val_0x6c8 = 0xcccc;
333 btdm8723.val_0x6cc = 0x3;
334
335 btdm8723.tdma_on = false;
336 btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF;
337 btdm8723.b2_ant_hid_en = false;
338
339 common = true;
340 } else if (rtlpcipriv->bt_coexist.bt_busy) {
341 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
342 "Bt non-idle!\n");
343 if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) {
344 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
345 "Wifi connection exist\n");
346 common = false;
347 } else {
348 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
349 "No Wifi connection!\n");
350 btdm8723.rf_rx_lpf_shrink = true;
351 btdm8723.low_penalty_rate_adaptive = false;
352 btdm8723.reject_aggre_pkt = false;
353
354 /* sw mechanism */
355 btdm8723.agc_table_en = false;
356 btdm8723.adc_back_off_on = false;
357 btdm8723.sw_dac_swing_on = false;
358
359 btdm8723.pta_on = true;
360 btdm8723.val_0x6c0 = 0x55555555;
361 btdm8723.val_0x6c8 = 0x0000ffff;
362 btdm8723.val_0x6cc = 0x3;
363
364 btdm8723.tdma_on = false;
365 btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF;
366 btdm8723.b2_ant_hid_en = false;
367
368 common = true;
369 }
370 }
371
372 if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw))
373 btdm8723.dec_bt_pwr = true;
374
375 if (common)
376 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BTINFO_COMMON;
377
378 if (common && rtl8723ae_dm_bt_is_coexist_state_changed(hw))
379 rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723);
380
381 return common;
382}
383
384static void rtl8723ae_dm_bt_set_sw_full_time_dac_swing(struct ieee80211_hw *hw,
385 bool sw_dac_swing_on,
386 u32 sw_dac_swing_lvl)
387{
388 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
389 struct rtl_priv *rtlpriv = rtl_priv(hw);
390
391 if (sw_dac_swing_on) {
392 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
393 "[BTCoex], SwDacSwing = 0x%x\n", sw_dac_swing_lvl);
394 rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000,
395 sw_dac_swing_lvl);
396 rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
397 } else {
398 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
399 "[BTCoex], SwDacSwing Off!\n");
400 rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0);
401 }
402}
403
404static void rtl8723ae_dm_bt_set_fw_dec_bt_pwr(struct ieee80211_hw *hw,
405 bool dec_bt_pwr)
406{
407 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
408 struct rtl_priv *rtlpriv = rtl_priv(hw);
409 u8 h2c_parameter[1] = {0};
410
411 h2c_parameter[0] = 0;
412
413 if (dec_bt_pwr) {
414 h2c_parameter[0] |= BIT(1);
415 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
416 }
417
418 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
419 "[BTCoex], decrease Bt Power : %s, write 0x21 = 0x%x\n",
420 (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]);
421
422 rtl8723ae_fill_h2c_cmd(hw, 0x21, 1, h2c_parameter);
423}
424
425static void rtl8723ae_dm_bt_set_fw_2_ant_hid(struct ieee80211_hw *hw,
426 bool enable, bool dac_swing_on)
427{
428 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
429 struct rtl_priv *rtlpriv = rtl_priv(hw);
430 u8 h2c_parameter[1] = {0};
431
432 if (enable) {
433 h2c_parameter[0] |= BIT(0);
434 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
435 }
436 if (dac_swing_on)
437 h2c_parameter[0] |= BIT(1); /* Dac Swing default enable */
438 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
439 "[BTCoex], turn 2-Ant+HID mode %s, DACSwing:%s, write 0x15 = 0x%x\n",
440 (enable ? "ON!!" : "OFF!!"), (dac_swing_on ? "ON" : "OFF"),
441 h2c_parameter[0]);
442
443 rtl8723ae_fill_h2c_cmd(hw, 0x15, 1, h2c_parameter);
444}
445
446static void rtl8723ae_dm_bt_set_fw_tdma_ctrl(struct ieee80211_hw *hw,
447 bool enable, u8 ant_num, u8 nav_en,
448 u8 dac_swing_en)
449{
450 struct rtl_priv *rtlpriv = rtl_priv(hw);
451 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
452 u8 h2c_parameter[1] = {0};
453 u8 h2c_parameter1[1] = {0};
454
455 h2c_parameter[0] = 0;
456 h2c_parameter1[0] = 0;
457
458 if (enable) {
459 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
460 "[BTCoex], set BT PTA update manager to trigger update!!\n");
461 h2c_parameter1[0] |= BIT(0);
462
463 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
464 "[BTCoex], turn TDMA mode ON!!\n");
465 h2c_parameter[0] |= BIT(0); /* function enable */
466 if (TDMA_1ANT == ant_num) {
467 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
468 "[BTCoex], TDMA_1ANT\n");
469 h2c_parameter[0] |= BIT(1);
470 } else if (TDMA_2ANT == ant_num) {
471 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
472 "[BTCoex], TDMA_2ANT\n");
473 } else {
474 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
475 "[BTCoex], Unknown Ant\n");
476 }
477
478 if (TDMA_NAV_OFF == nav_en) {
479 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
480 "[BTCoex], TDMA_NAV_OFF\n");
481 } else if (TDMA_NAV_ON == nav_en) {
482 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
483 "[BTCoex], TDMA_NAV_ON\n");
484 h2c_parameter[0] |= BIT(2);
485 }
486
487 if (TDMA_DAC_SWING_OFF == dac_swing_en) {
488 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
489 "[BTCoex], TDMA_DAC_SWING_OFF\n");
490 } else if (TDMA_DAC_SWING_ON == dac_swing_en) {
491 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
492 "[BTCoex], TDMA_DAC_SWING_ON\n");
493 h2c_parameter[0] |= BIT(4);
494 }
495 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
496 } else {
497 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
498 "[BTCoex], set BT PTA update manager to no update!!\n");
499 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
500 "[BTCoex], turn TDMA mode OFF!!\n");
501 }
502
503 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
504 "[BTCoex], FW2AntTDMA, write 0x26 = 0x%x\n",
505 h2c_parameter1[0]);
506 rtl8723ae_fill_h2c_cmd(hw, 0x26, 1, h2c_parameter1);
507
508 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
509 "[BTCoex], FW2AntTDMA, write 0x14 = 0x%x\n", h2c_parameter[0]);
510 rtl8723ae_fill_h2c_cmd(hw, 0x14, 1, h2c_parameter);
511}
512
513static void rtl8723ae_dm_bt_set_fw_ignore_wlan_act(struct ieee80211_hw *hw,
514 bool enable)
515{
516 struct rtl_priv *rtlpriv = rtl_priv(hw);
517 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
518 u8 h2c_parameter[1] = {0};
519
520 if (enable) {
521 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
522 "[BTCoex], BT Ignore Wlan_Act !!\n");
523 h2c_parameter[0] |= BIT(0); /* function enable */
524 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
525 } else {
526 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
527 "[BTCoex], BT don't ignore Wlan_Act !!\n");
528 }
529
530 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
531 "[BTCoex], set FW for BT Ignore Wlan_Act, write 0x25 = 0x%x\n",
532 h2c_parameter[0]);
533
534 rtl8723ae_fill_h2c_cmd(hw, 0x25, 1, h2c_parameter);
535}
536
537static void rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(struct ieee80211_hw *hw,
538 bool enable, u8 ant_num,
539 u8 nav_en)
540{
541 struct rtl_priv *rtlpriv = rtl_priv(hw);
542 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
543 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
544 u8 h2c_parameter[2] = {0};
545
546 /* Only 8723 B cut should do this */
547 if (IS_VENDOR_8723_A_CUT(rtlhal->version)) {
548 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
549 "[BTCoex], not 8723B cut, don't set Traditional TDMA!!\n");
550 return;
551 }
552
553 if (enable) {
554 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
555 "[BTCoex], turn TTDMA mode ON!!\n");
556 h2c_parameter[0] |= BIT(0); /* function enable */
557 if (TDMA_1ANT == ant_num) {
558 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
559 "[BTCoex], TTDMA_1ANT\n");
560 h2c_parameter[0] |= BIT(1);
561 } else if (TDMA_2ANT == ant_num) {
562 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
563 "[BTCoex], TTDMA_2ANT\n");
564 } else {
565 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
566 "[BTCoex], Unknown Ant\n");
567 }
568
569 if (TDMA_NAV_OFF == nav_en) {
570 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
571 "[BTCoex], TTDMA_NAV_OFF\n");
572 } else if (TDMA_NAV_ON == nav_en) {
573 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
574 "[BTCoex], TTDMA_NAV_ON\n");
575 h2c_parameter[1] |= BIT(0);
576 }
577
578 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
579 } else {
580 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
581 "[BTCoex], turn TTDMA mode OFF!!\n");
582 }
583
584 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
585 "[BTCoex], FW Traditional TDMA, write 0x33 = 0x%x\n",
586 h2c_parameter[0] << 8 | h2c_parameter[1]);
587
588 rtl8723ae_fill_h2c_cmd(hw, 0x33, 2, h2c_parameter);
589}
590
591static void rtl8723ae_dm_bt_set_fw_dac_swing_level(struct ieee80211_hw *hw,
592 u8 dac_swing_lvl)
593{
594 struct rtl_priv *rtlpriv = rtl_priv(hw);
595 u8 h2c_parameter[1] = {0};
596
597 h2c_parameter[0] = dac_swing_lvl;
598
599 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
600 "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swing_lvl);
601 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
602 "[BTCoex], write 0x29 = 0x%x\n", h2c_parameter[0]);
603
604 rtl8723ae_fill_h2c_cmd(hw, 0x29, 1, h2c_parameter);
605}
606
607static void rtl8723ae_dm_bt_set_fw_bt_hid_info(struct ieee80211_hw *hw,
608 bool enable)
609{
610 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
611 struct rtl_priv *rtlpriv = rtl_priv(hw);
612 u8 h2c_parameter[1] = {0};
613
614 h2c_parameter[0] = 0;
615
616 if (enable) {
617 h2c_parameter[0] |= BIT(0);
618 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
619 }
620 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
621 "[BTCoex], Set BT HID information = 0x%x\n", enable);
622 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
623 "[BTCoex], write 0x24 = 0x%x\n", h2c_parameter[0]);
624
625 rtl8723ae_fill_h2c_cmd(hw, 0x24, 1, h2c_parameter);
626}
627
628static void rtl8723ae_dm_bt_set_fw_bt_retry_index(struct ieee80211_hw *hw,
629 u8 retry_index)
630{
631 struct rtl_priv *rtlpriv = rtl_priv(hw);
632 u8 h2c_parameter[1] = {0};
633
634 h2c_parameter[0] = retry_index;
635
636 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
637 "[BTCoex], Set BT Retry Index=%d\n", retry_index);
638 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
639 "[BTCoex], write 0x23 = 0x%x\n", h2c_parameter[0]);
640
641 rtl8723ae_fill_h2c_cmd(hw, 0x23, 1, h2c_parameter);
642}
643
644static void rtl8723ae_dm_bt_set_fw_wlan_act(struct ieee80211_hw *hw,
645 u8 wlan_act_hi, u8 wlan_act_lo)
646{
647 struct rtl_priv *rtlpriv = rtl_priv(hw);
648 u8 h2c_parameter_hi[1] = {0};
649 u8 h2c_parameter_lo[1] = {0};
650
651 h2c_parameter_hi[0] = wlan_act_hi;
652 h2c_parameter_lo[0] = wlan_act_lo;
653
654 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
655 "[BTCoex], Set WLAN_ACT Hi:Lo = 0x%x/0x%x\n", wlan_act_hi,
656 wlan_act_lo);
657 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
658 "[BTCoex], write 0x22 = 0x%x\n", h2c_parameter_hi[0]);
659 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
660 "[BTCoex], write 0x11 = 0x%x\n", h2c_parameter_lo[0]);
661
662 /* WLAN_ACT = High duration, unit:ms */
663 rtl8723ae_fill_h2c_cmd(hw, 0x22, 1, h2c_parameter_hi);
664 /* WLAN_ACT = Low duration, unit:3*625us */
665 rtl8723ae_fill_h2c_cmd(hw, 0x11, 1, h2c_parameter_lo);
666}
667
668void rtl8723ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw, struct btdm_8723 *btdm)
669{
670 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
671 struct rtl_priv *rtlpriv = rtl_priv(hw);
672 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
673 struct btdm_8723 *btdm_8723 = &rtlhal->hal_coex_8723.btdm;
674 u8 i;
675 bool fw_current_inpsmode = false;
676 bool fw_ps_awake = true;
677
678 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
679 (u8 *)(&fw_current_inpsmode));
680 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
681 (u8 *)(&fw_ps_awake));
682
683 /* check new setting is different than the old one,
684 * if all the same, don't do the setting again.
685 */
686 if (memcmp(btdm_8723, btdm, sizeof(struct btdm_8723)) == 0) {
687 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
688 "[BTCoex], the same coexist setting, return!!\n");
689 return;
690 } else { /* save the new coexist setting */
691 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
692 "[BTCoex], UPDATE TO NEW COEX SETTING!!\n");
693 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
694 "[BTCoex], original/new bAllOff = 0x%x/ 0x%x\n",
695 btdm_8723->all_off, btdm->all_off);
696 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
697 "[BTCoex], original/new agc_table_en = 0x%x/ 0x%x\n",
698 btdm_8723->agc_table_en, btdm->agc_table_en);
699 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
700 "[BTCoex], original/new adc_back_off_on = 0x%x/ 0x%x\n",
701 btdm_8723->adc_back_off_on, btdm->adc_back_off_on);
702 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
703 "[BTCoex], original/new b2_ant_hid_en = 0x%x/ 0x%x\n",
704 btdm_8723->b2_ant_hid_en, btdm->b2_ant_hid_en);
705 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
706 "[BTCoex], original/new bLowPenaltyRateAdaptive = 0x%x/ 0x%x\n",
707 btdm_8723->low_penalty_rate_adaptive,
708 btdm->low_penalty_rate_adaptive);
709 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
710 "[BTCoex], original/new bRfRxLpfShrink = 0x%x/ 0x%x\n",
711 btdm_8723->rf_rx_lpf_shrink, btdm->rf_rx_lpf_shrink);
712 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
713 "[BTCoex], original/new bRejectAggrePkt = 0x%x/ 0x%x\n",
714 btdm_8723->reject_aggre_pkt, btdm->reject_aggre_pkt);
715 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
716 "[BTCoex], original/new tdma_on = 0x%x/ 0x%x\n",
717 btdm_8723->tdma_on, btdm->tdma_on);
718 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
719 "[BTCoex], original/new tdmaAnt = 0x%x/ 0x%x\n",
720 btdm_8723->tdma_ant, btdm->tdma_ant);
721 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
722 "[BTCoex], original/new tdmaNav = 0x%x/ 0x%x\n",
723 btdm_8723->tdma_nav, btdm->tdma_nav);
724 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
725 "[BTCoex], original/new tdma_dac_swing = 0x%x/ 0x%x\n",
726 btdm_8723->tdma_dac_swing, btdm->tdma_dac_swing);
727 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
728 "[BTCoex], original/new fwDacSwingLvl = 0x%x/ 0x%x\n",
729 btdm_8723->fw_dac_swing_lvl, btdm->fw_dac_swing_lvl);
730
731 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
732 "[BTCoex], original/new bTraTdmaOn = 0x%x/ 0x%x\n",
733 btdm_8723->tra_tdma_on, btdm->tra_tdma_on);
734 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
735 "[BTCoex], original/new traTdmaAnt = 0x%x/ 0x%x\n",
736 btdm_8723->tra_tdma_ant, btdm->tra_tdma_ant);
737 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
738 "[BTCoex], original/new traTdmaNav = 0x%x/ 0x%x\n",
739 btdm_8723->tra_tdma_nav, btdm->tra_tdma_nav);
740 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
741 "[BTCoex], original/new bPsTdmaOn = 0x%x/ 0x%x\n",
742 btdm_8723->ps_tdma_on, btdm->ps_tdma_on);
743 for (i = 0; i < 5; i++) {
744 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
745 "[BTCoex], original/new psTdmaByte[i] = 0x%x/ 0x%x\n",
746 btdm_8723->ps_tdma_byte[i],
747 btdm->ps_tdma_byte[i]);
748 }
749 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
750 "[BTCoex], original/new bIgnoreWlanAct = 0x%x/ 0x%x\n",
751 btdm_8723->ignore_wlan_act, btdm->ignore_wlan_act);
752
753 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
754 "[BTCoex], original/new bPtaOn = 0x%x/ 0x%x\n",
755 btdm_8723->pta_on, btdm->pta_on);
756 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
757 "[BTCoex], original/new val_0x6c0 = 0x%x/ 0x%x\n",
758 btdm_8723->val_0x6c0, btdm->val_0x6c0);
759 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
760 "[BTCoex], original/new val_0x6c8 = 0x%x/ 0x%x\n",
761 btdm_8723->val_0x6c8, btdm->val_0x6c8);
762 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
763 "[BTCoex], original/new val_0x6cc = 0x%x/ 0x%x\n",
764 btdm_8723->val_0x6cc, btdm->val_0x6cc);
765 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
766 "[BTCoex], original/new sw_dac_swing_on = 0x%x/ 0x%x\n",
767 btdm_8723->sw_dac_swing_on, btdm->sw_dac_swing_on);
768 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
769 "[BTCoex], original/new sw_dac_swing_lvl = 0x%x/ 0x%x\n",
770 btdm_8723->sw_dac_swing_lvl,
771 btdm->sw_dac_swing_lvl);
772 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
773 "[BTCoex], original/new wlanActHi = 0x%x/ 0x%x\n",
774 btdm_8723->wlan_act_hi, btdm->wlan_act_hi);
775 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
776 "[BTCoex], original/new wlanActLo = 0x%x/ 0x%x\n",
777 btdm_8723->wlan_act_lo, btdm->wlan_act_lo);
778 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
779 "[BTCoex], original/new btRetryIndex = 0x%x/ 0x%x\n",
780 btdm_8723->bt_retry_index, btdm->bt_retry_index);
781
782 memcpy(btdm_8723, btdm, sizeof(struct btdm_8723));
783 }
784 /*
785 * Here we only consider when Bt Operation
786 * inquiry/paging/pairing is ON
787 * we only need to turn off TDMA
788 */
789
790 if (rtlpcipriv->bt_coexist.hold_for_bt_operation) {
791 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
792 "[BTCoex], set to ignore wlanAct for BT OP!!\n");
793 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, true);
794 return;
795 }
796
797 if (btdm->all_off) {
798 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
799 "[BTCoex], disable all coexist mechanism !!\n");
800 rtl8723ae_btdm_coex_all_off(hw);
801 return;
802 }
803
804 rtl8723ae_dm_bt_reject_ap_aggregated_packet(hw, btdm->reject_aggre_pkt);
805
806 if (btdm->low_penalty_rate_adaptive)
807 rtl8723ae_bt_set_penalty_tx_rate_adap(hw,
808 BT_TX_RATE_ADAPTIVE_LOW_PENALTY);
809 else
810 rtl8723ae_bt_set_penalty_tx_rate_adap(hw,
811 BT_TX_RATE_ADAPTIVE_NORMAL);
812
813 if (btdm->rf_rx_lpf_shrink)
814 rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw,
815 BT_RF_RX_LPF_CORNER_SHRINK);
816 else
817 rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw,
818 BT_RF_RX_LPF_CORNER_RESUME);
819
820 if (btdm->agc_table_en)
821 rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_ON);
822 else
823 rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF);
824
825 if (btdm->adc_back_off_on)
826 rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_ON);
827 else
828 rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_OFF);
829
830 rtl8723ae_dm_bt_set_fw_bt_retry_index(hw, btdm->bt_retry_index);
831
832 rtl8723ae_dm_bt_set_fw_dac_swing_level(hw, btdm->fw_dac_swing_lvl);
833 rtl8723ae_dm_bt_set_fw_wlan_act(hw, btdm->wlan_act_hi,
834 btdm->wlan_act_lo);
835
836 rtl8723ae_dm_bt_set_coex_table(hw, btdm->val_0x6c0,
837 btdm->val_0x6c8, btdm->val_0x6cc);
838 rtl8723ae_dm_bt_set_hw_pta_mode(hw, btdm->pta_on);
839
840 /* Note: There is a constraint between TDMA and 2AntHID
841 * Only one of 2AntHid and tdma can be turned on
842 * We should turn off those mechanisms first
843 * and then turn on them on.
844 */
845 if (btdm->b2_ant_hid_en) {
846 /* turn off tdma */
847 rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
848 btdm->tra_tdma_ant,
849 btdm->tra_tdma_nav);
850 rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant,
851 btdm->tdma_nav,
852 btdm->tdma_dac_swing);
853
854 /* turn off Pstdma */
855 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw,
856 btdm->ignore_wlan_act);
857 /* Antenna control by PTA, 0x870 = 0x300. */
858 rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
859
860 /* turn on 2AntHid */
861 rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, true);
862 rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, true, true);
863 } else if (btdm->tdma_on) {
864 /* turn off 2AntHid */
865 rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false);
866 rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
867
868 /* turn off pstdma */
869 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw,
870 btdm->ignore_wlan_act);
871 /* Antenna control by PTA, 0x870 = 0x300. */
872 rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
873
874 /* turn on tdma */
875 rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
876 btdm->tra_tdma_ant, btdm->tra_tdma_nav);
877 rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, true, btdm->tdma_ant,
878 btdm->tdma_nav, btdm->tdma_dac_swing);
879 } else if (btdm->ps_tdma_on) {
880 /* turn off 2AntHid */
881 rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false);
882 rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
883
884 /* turn off tdma */
885 rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
886 btdm->tra_tdma_ant, btdm->tra_tdma_nav);
887 rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant,
888 btdm->tdma_nav, btdm->tdma_dac_swing);
889
890 /* turn on pstdma */
891 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw,
892 btdm->ignore_wlan_act);
893 rtl8723ae_dm_bt_set_fw_3a(hw,
894 btdm->ps_tdma_byte[0],
895 btdm->ps_tdma_byte[1],
896 btdm->ps_tdma_byte[2],
897 btdm->ps_tdma_byte[3],
898 btdm->ps_tdma_byte[4]);
899 } else {
900 /* turn off 2AntHid */
901 rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false);
902 rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
903
904 /* turn off tdma */
905 rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
906 btdm->tra_tdma_ant, btdm->tra_tdma_nav);
907 rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant,
908 btdm->tdma_nav, btdm->tdma_dac_swing);
909
910 /* turn off pstdma */
911 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw,
912 btdm->ignore_wlan_act);
913 /* Antenna control by PTA, 0x870 = 0x300. */
914 rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
915 }
916
917 /* Note:
918 * We should add delay for making sure sw DacSwing can be set
919 * sucessfully. Because of that rtl8723ae_dm_bt_set_fw_2_ant_hid()
920 * and rtl8723ae_dm_bt_set_fw_tdma_ctrl()
921 * will overwrite the reg 0x880.
922 */
923 mdelay(30);
924 rtl8723ae_dm_bt_set_sw_full_time_dac_swing(hw,
925 btdm->sw_dac_swing_on, btdm->sw_dac_swing_lvl);
926 rtl8723ae_dm_bt_set_fw_dec_bt_pwr(hw, btdm->dec_bt_pwr);
927}
928
929/*============================================================
930 * extern function start with BTDM_
931 *============================================================
932 */
933static u32 rtl8723ae_dm_bt_tx_rx_couter_h(struct ieee80211_hw *hw)
934{
935 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
936 u32 counters = 0;
937
938 counters = rtlhal->hal_coex_8723.high_priority_tx +
939 rtlhal->hal_coex_8723.high_priority_rx;
940 return counters;
941}
942
943static u32 rtl8723ae_dm_bt_tx_rx_couter_l(struct ieee80211_hw *hw)
944{
945 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
946
947 return rtlhal->hal_coex_8723.low_priority_tx +
948 rtlhal->hal_coex_8723.low_priority_rx;
949}
950
951static u8 rtl8723ae_dm_bt_bt_tx_rx_counter_level(struct ieee80211_hw *hw)
952{
953 struct rtl_priv *rtlpriv = rtl_priv(hw);
954 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
955 u32 bt_tx_rx_cnt = 0;
956 u8 bt_tx_rx_cnt_lvl = 0;
957
958 bt_tx_rx_cnt = rtl8723ae_dm_bt_tx_rx_couter_h(hw) +
959 rtl8723ae_dm_bt_tx_rx_couter_l(hw);
960 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
961 "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt);
962
963 rtlpcipriv->bt_coexist.cstate_h &=
964 ~(BT_COEX_STATE_BT_CNT_LEVEL_0 | BT_COEX_STATE_BT_CNT_LEVEL_1 |
965 BT_COEX_STATE_BT_CNT_LEVEL_2);
966
967 if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_3) {
968 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
969 "[BTCoex], BT TxRx Counters at level 3\n");
970 bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_3;
971 rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_3;
972 } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_2) {
973 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
974 "[BTCoex], BT TxRx Counters at level 2\n");
975 bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_2;
976 rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_2;
977 } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_1) {
978 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
979 "[BTCoex], BT TxRx Counters at level 1\n");
980 bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_1;
981 rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_1;
982 } else {
983 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
984 "[BTCoex], BT TxRx Counters at level 0\n");
985 bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_0;
986 rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_0;
987 }
988 return bt_tx_rx_cnt_lvl;
989}
990
991static void rtl8723ae_dm_bt_2_ant_hid_sco_esco(struct ieee80211_hw *hw)
992{
993 struct rtl_priv *rtlpriv = rtl_priv(hw);
994 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
995 struct rtl_phy *rtlphy = &(rtlpriv->phy);
996 struct btdm_8723 btdm8723;
997 u8 bt_rssi_state, bt_rssi_state1;
998 u8 bt_tx_rx_cnt_lvl;
999
1000 rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723);
1001
1002 btdm8723.rf_rx_lpf_shrink = true;
1003 btdm8723.low_penalty_rate_adaptive = true;
1004 btdm8723.reject_aggre_pkt = false;
1005
1006 bt_tx_rx_cnt_lvl = rtl8723ae_dm_bt_bt_tx_rx_counter_level(hw);
1007 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1008 "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl);
1009
1010 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
1011 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n");
1012 /* coex table */
1013 btdm8723.val_0x6c0 = 0x55555555;
1014 btdm8723.val_0x6c8 = 0xffff;
1015 btdm8723.val_0x6cc = 0x3;
1016
1017 /* sw mechanism */
1018 btdm8723.agc_table_en = false;
1019 btdm8723.adc_back_off_on = false;
1020 btdm8723.sw_dac_swing_on = false;
1021
1022 /* fw mechanism */
1023 btdm8723.ps_tdma_on = true;
1024 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1025 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1026 "[BTCoex], BT TxRx Counters >= 1400\n");
1027 btdm8723.ps_tdma_byte[0] = 0xa3;
1028 btdm8723.ps_tdma_byte[1] = 0x5;
1029 btdm8723.ps_tdma_byte[2] = 0x5;
1030 btdm8723.ps_tdma_byte[3] = 0x2;
1031 btdm8723.ps_tdma_byte[4] = 0x80;
1032 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1033 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1034 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1035 btdm8723.ps_tdma_byte[0] = 0xa3;
1036 btdm8723.ps_tdma_byte[1] = 0xa;
1037 btdm8723.ps_tdma_byte[2] = 0xa;
1038 btdm8723.ps_tdma_byte[3] = 0x2;
1039 btdm8723.ps_tdma_byte[4] = 0x80;
1040 } else {
1041 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1042 "[BTCoex], BT TxRx Counters < 1200\n");
1043 btdm8723.ps_tdma_byte[0] = 0xa3;
1044 btdm8723.ps_tdma_byte[1] = 0xf;
1045 btdm8723.ps_tdma_byte[2] = 0xf;
1046 btdm8723.ps_tdma_byte[3] = 0x2;
1047 btdm8723.ps_tdma_byte[4] = 0x80;
1048 }
1049 } else {
1050 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1051 "HT20 or Legacy\n");
1052 bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2,
1053 47, 0);
1054 bt_rssi_state1 = rtl8723ae_dm_bt_check_coex_rssi_state1(hw, 2,
1055 27, 0);
1056
1057 /* coex table */
1058 btdm8723.val_0x6c0 = 0x55555555;
1059 btdm8723.val_0x6c8 = 0xffff;
1060 btdm8723.val_0x6cc = 0x3;
1061
1062 /* sw mechanism */
1063 if ((bt_rssi_state == BT_RSSI_STATE_HIGH) ||
1064 (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) {
1065 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1066 "Wifi rssi high\n");
1067 btdm8723.agc_table_en = true;
1068 btdm8723.adc_back_off_on = true;
1069 btdm8723.sw_dac_swing_on = false;
1070 } else {
1071 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1072 "Wifi rssi low\n");
1073 btdm8723.agc_table_en = false;
1074 btdm8723.adc_back_off_on = false;
1075 btdm8723.sw_dac_swing_on = false;
1076 }
1077
1078 /* fw mechanism */
1079 btdm8723.ps_tdma_on = true;
1080 if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) ||
1081 (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) {
1082 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1083 "Wifi rssi-1 high\n");
1084 /* only rssi high we need to do this,
1085 * when rssi low, the value will modified by fw
1086 */
1087 rtl_write_byte(rtlpriv, 0x883, 0x40);
1088 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1089 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1090 "[BTCoex], BT TxRx Counters >= 1400\n");
1091 btdm8723.ps_tdma_byte[0] = 0xa3;
1092 btdm8723.ps_tdma_byte[1] = 0x5;
1093 btdm8723.ps_tdma_byte[2] = 0x5;
1094 btdm8723.ps_tdma_byte[3] = 0x83;
1095 btdm8723.ps_tdma_byte[4] = 0x80;
1096 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1097 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1098 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1099 btdm8723.ps_tdma_byte[0] = 0xa3;
1100 btdm8723.ps_tdma_byte[1] = 0xa;
1101 btdm8723.ps_tdma_byte[2] = 0xa;
1102 btdm8723.ps_tdma_byte[3] = 0x83;
1103 btdm8723.ps_tdma_byte[4] = 0x80;
1104 } else {
1105 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1106 "[BTCoex], BT TxRx Counters < 1200\n");
1107 btdm8723.ps_tdma_byte[0] = 0xa3;
1108 btdm8723.ps_tdma_byte[1] = 0xf;
1109 btdm8723.ps_tdma_byte[2] = 0xf;
1110 btdm8723.ps_tdma_byte[3] = 0x83;
1111 btdm8723.ps_tdma_byte[4] = 0x80;
1112 }
1113 } else {
1114 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1115 "Wifi rssi-1 low\n");
1116 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1117 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1118 "[BTCoex], BT TxRx Counters >= 1400\n");
1119 btdm8723.ps_tdma_byte[0] = 0xa3;
1120 btdm8723.ps_tdma_byte[1] = 0x5;
1121 btdm8723.ps_tdma_byte[2] = 0x5;
1122 btdm8723.ps_tdma_byte[3] = 0x2;
1123 btdm8723.ps_tdma_byte[4] = 0x80;
1124 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1125 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1126 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1127 btdm8723.ps_tdma_byte[0] = 0xa3;
1128 btdm8723.ps_tdma_byte[1] = 0xa;
1129 btdm8723.ps_tdma_byte[2] = 0xa;
1130 btdm8723.ps_tdma_byte[3] = 0x2;
1131 btdm8723.ps_tdma_byte[4] = 0x80;
1132 } else {
1133 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1134 "[BTCoex], BT TxRx Counters < 1200\n");
1135 btdm8723.ps_tdma_byte[0] = 0xa3;
1136 btdm8723.ps_tdma_byte[1] = 0xf;
1137 btdm8723.ps_tdma_byte[2] = 0xf;
1138 btdm8723.ps_tdma_byte[3] = 0x2;
1139 btdm8723.ps_tdma_byte[4] = 0x80;
1140 }
1141 }
1142 }
1143
1144 if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw))
1145 btdm8723.dec_bt_pwr = true;
1146
1147 /* Always ignore WlanAct if bHid|bSCOBusy|bSCOeSCO */
1148
1149 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1150 "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n",
1151 rtlhal->hal_coex_8723.bt_inq_page_start_time,
1152 bt_tx_rx_cnt_lvl);
1153 if ((rtlhal->hal_coex_8723.bt_inq_page_start_time) ||
1154 (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) {
1155 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1156 "[BTCoex], Set BT inquiry / page scan 0x3a setting\n");
1157 btdm8723.ps_tdma_on = true;
1158 btdm8723.ps_tdma_byte[0] = 0xa3;
1159 btdm8723.ps_tdma_byte[1] = 0x5;
1160 btdm8723.ps_tdma_byte[2] = 0x5;
1161 btdm8723.ps_tdma_byte[3] = 0x2;
1162 btdm8723.ps_tdma_byte[4] = 0x80;
1163 }
1164
1165 if (rtl8723ae_dm_bt_is_coexist_state_changed(hw))
1166 rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723);
1167}
1168
1169static void rtl8723ae_dm_bt_2_ant_fta2dp(struct ieee80211_hw *hw)
1170{
1171 struct rtl_priv *rtlpriv = rtl_priv(hw);
1172 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1173 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1174 struct btdm_8723 btdm8723;
1175 u8 bt_rssi_state, bt_rssi_state1;
1176 u32 bt_tx_rx_cnt_lvl;
1177
1178 rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723);
1179 btdm8723.rf_rx_lpf_shrink = true;
1180 btdm8723.low_penalty_rate_adaptive = true;
1181 btdm8723.reject_aggre_pkt = false;
1182
1183 bt_tx_rx_cnt_lvl = rtl8723ae_dm_bt_bt_tx_rx_counter_level(hw);
1184
1185 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1186 "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl);
1187
1188 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
1189 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n");
1190 bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2,
1191 37, 0);
1192
1193 /* coex table */
1194 btdm8723.val_0x6c0 = 0x55555555;
1195 btdm8723.val_0x6c8 = 0xffff;
1196 btdm8723.val_0x6cc = 0x3;
1197
1198 /* sw mechanism */
1199 btdm8723.agc_table_en = false;
1200 btdm8723.adc_back_off_on = true;
1201 btdm8723.sw_dac_swing_on = false;
1202
1203 /* fw mechanism */
1204 btdm8723.ps_tdma_on = true;
1205 if ((bt_rssi_state == BT_RSSI_STATE_HIGH) ||
1206 (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) {
1207 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1208 "Wifi rssi high\n");
1209 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1210 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1211 "[BTCoex], BT TxRx Counters >= 1400\n");
1212 btdm8723.ps_tdma_byte[0] = 0xa3;
1213 btdm8723.ps_tdma_byte[1] = 0x5;
1214 btdm8723.ps_tdma_byte[2] = 0x5;
1215 btdm8723.ps_tdma_byte[3] = 0x81;
1216 btdm8723.ps_tdma_byte[4] = 0x80;
1217 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1218 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1219 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1220 btdm8723.ps_tdma_byte[0] = 0xa3;
1221 btdm8723.ps_tdma_byte[1] = 0xa;
1222 btdm8723.ps_tdma_byte[2] = 0xa;
1223 btdm8723.ps_tdma_byte[3] = 0x81;
1224 btdm8723.ps_tdma_byte[4] = 0x80;
1225 } else {
1226 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1227 "[BTCoex], BT TxRx Counters < 1200\n");
1228 btdm8723.ps_tdma_byte[0] = 0xa3;
1229 btdm8723.ps_tdma_byte[1] = 0xf;
1230 btdm8723.ps_tdma_byte[2] = 0xf;
1231 btdm8723.ps_tdma_byte[3] = 0x81;
1232 btdm8723.ps_tdma_byte[4] = 0x80;
1233 }
1234 } else {
1235 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1236 "Wifi rssi low\n");
1237 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1238 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1239 "[BTCoex], BT TxRx Counters >= 1400\n");
1240 btdm8723.ps_tdma_byte[0] = 0xa3;
1241 btdm8723.ps_tdma_byte[1] = 0x5;
1242 btdm8723.ps_tdma_byte[2] = 0x5;
1243 btdm8723.ps_tdma_byte[3] = 0x0;
1244 btdm8723.ps_tdma_byte[4] = 0x80;
1245 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1246 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1247 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1248 btdm8723.ps_tdma_byte[0] = 0xa3;
1249 btdm8723.ps_tdma_byte[1] = 0xa;
1250 btdm8723.ps_tdma_byte[2] = 0xa;
1251 btdm8723.ps_tdma_byte[3] = 0x0;
1252 btdm8723.ps_tdma_byte[4] = 0x80;
1253 } else {
1254 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1255 "[BTCoex], BT TxRx Counters < 1200\n");
1256 btdm8723.ps_tdma_byte[0] = 0xa3;
1257 btdm8723.ps_tdma_byte[1] = 0xf;
1258 btdm8723.ps_tdma_byte[2] = 0xf;
1259 btdm8723.ps_tdma_byte[3] = 0x0;
1260 btdm8723.ps_tdma_byte[4] = 0x80;
1261 }
1262 }
1263 } else {
1264 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1265 "HT20 or Legacy\n");
1266 bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2,
1267 47, 0);
1268 bt_rssi_state1 = rtl8723ae_dm_bt_check_coex_rssi_state1(hw, 2,
1269 27, 0);
1270
1271 /* coex table */
1272 btdm8723.val_0x6c0 = 0x55555555;
1273 btdm8723.val_0x6c8 = 0xffff;
1274 btdm8723.val_0x6cc = 0x3;
1275
1276 /* sw mechanism */
1277 if ((bt_rssi_state == BT_RSSI_STATE_HIGH) ||
1278 (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) {
1279 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1280 "Wifi rssi high\n");
1281 btdm8723.agc_table_en = true;
1282 btdm8723.adc_back_off_on = true;
1283 btdm8723.sw_dac_swing_on = false;
1284 } else {
1285 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1286 "Wifi rssi low\n");
1287 btdm8723.agc_table_en = false;
1288 btdm8723.adc_back_off_on = false;
1289 btdm8723.sw_dac_swing_on = false;
1290 }
1291
1292 /* fw mechanism */
1293 btdm8723.ps_tdma_on = true;
1294 if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) ||
1295 (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) {
1296 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1297 "Wifi rssi-1 high\n");
1298 /* only rssi high we need to do this,
1299 * when rssi low, the value will modified by fw
1300 */
1301 rtl_write_byte(rtlpriv, 0x883, 0x40);
1302 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1303 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1304 "[BTCoex], BT TxRx Counters >= 1400\n");
1305 btdm8723.ps_tdma_byte[0] = 0xa3;
1306 btdm8723.ps_tdma_byte[1] = 0x5;
1307 btdm8723.ps_tdma_byte[2] = 0x5;
1308 btdm8723.ps_tdma_byte[3] = 0x81;
1309 btdm8723.ps_tdma_byte[4] = 0x80;
1310 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1311 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1312 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1313 btdm8723.ps_tdma_byte[0] = 0xa3;
1314 btdm8723.ps_tdma_byte[1] = 0xa;
1315 btdm8723.ps_tdma_byte[2] = 0xa;
1316 btdm8723.ps_tdma_byte[3] = 0x81;
1317 btdm8723.ps_tdma_byte[4] = 0x80;
1318 } else {
1319 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1320 "[BTCoex], BT TxRx Counters < 1200\n");
1321 btdm8723.ps_tdma_byte[0] = 0xa3;
1322 btdm8723.ps_tdma_byte[1] = 0xf;
1323 btdm8723.ps_tdma_byte[2] = 0xf;
1324 btdm8723.ps_tdma_byte[3] = 0x81;
1325 btdm8723.ps_tdma_byte[4] = 0x80;
1326 }
1327 } else {
1328 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1329 "Wifi rssi-1 low\n");
1330 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1331 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1332 "[BTCoex], BT TxRx Counters >= 1400\n");
1333 btdm8723.ps_tdma_byte[0] = 0xa3;
1334 btdm8723.ps_tdma_byte[1] = 0x5;
1335 btdm8723.ps_tdma_byte[2] = 0x5;
1336 btdm8723.ps_tdma_byte[3] = 0x0;
1337 btdm8723.ps_tdma_byte[4] = 0x80;
1338 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1339 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1340 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1341 btdm8723.ps_tdma_byte[0] = 0xa3;
1342 btdm8723.ps_tdma_byte[1] = 0xa;
1343 btdm8723.ps_tdma_byte[2] = 0xa;
1344 btdm8723.ps_tdma_byte[3] = 0x0;
1345 btdm8723.ps_tdma_byte[4] = 0x80;
1346 } else {
1347 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1348 "[BTCoex], BT TxRx Counters < 1200\n");
1349 btdm8723.ps_tdma_byte[0] = 0xa3;
1350 btdm8723.ps_tdma_byte[1] = 0xf;
1351 btdm8723.ps_tdma_byte[2] = 0xf;
1352 btdm8723.ps_tdma_byte[3] = 0x0;
1353 btdm8723.ps_tdma_byte[4] = 0x80;
1354 }
1355 }
1356 }
1357
1358 if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw))
1359 btdm8723.dec_bt_pwr = true;
1360
1361 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1362 "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n",
1363 rtlhal->hal_coex_8723.bt_inq_page_start_time,
1364 bt_tx_rx_cnt_lvl);
1365
1366 if ((rtlhal->hal_coex_8723.bt_inq_page_start_time) ||
1367 (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) {
1368 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1369 "[BTCoex], Set BT inquiry / page scan 0x3a setting\n");
1370 btdm8723.ps_tdma_on = true;
1371 btdm8723.ps_tdma_byte[0] = 0xa3;
1372 btdm8723.ps_tdma_byte[1] = 0x5;
1373 btdm8723.ps_tdma_byte[2] = 0x5;
1374 btdm8723.ps_tdma_byte[3] = 0x83;
1375 btdm8723.ps_tdma_byte[4] = 0x80;
1376 }
1377
1378 if (rtl8723ae_dm_bt_is_coexist_state_changed(hw))
1379 rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723);
1380}
1381
1382static void rtl8723ae_dm_bt_inq_page_monitor(struct ieee80211_hw *hw)
1383{
1384 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1385 struct rtl_priv *rtlpriv = rtl_priv(hw);
1386 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1387 u32 cur_time = jiffies;
1388
1389 if (rtlhal->hal_coex_8723.c2h_bt_inquiry_page) {
1390 /* bt inquiry or page is started. */
1391 if (rtlhal->hal_coex_8723.bt_inq_page_start_time == 0) {
1392 rtlpcipriv->bt_coexist.cstate |=
1393 BT_COEX_STATE_BT_INQ_PAGE;
1394 rtlhal->hal_coex_8723.bt_inq_page_start_time = cur_time;
1395 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1396 "[BTCoex], BT Inquiry/page is started at time : 0x%x\n",
1397 rtlhal->hal_coex_8723.bt_inq_page_start_time);
1398 }
1399 }
1400 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1401 "[BTCoex], BT Inquiry/page started time : 0x%x, cur_time : 0x%x\n",
1402 rtlhal->hal_coex_8723.bt_inq_page_start_time, cur_time);
1403
1404 if (rtlhal->hal_coex_8723.bt_inq_page_start_time) {
1405 if ((((long)cur_time -
1406 (long)rtlhal->hal_coex_8723.bt_inq_page_start_time) / HZ) >=
1407 10) {
1408 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1409 "[BTCoex], BT Inquiry/page >= 10sec!!!");
1410 rtlhal->hal_coex_8723.bt_inq_page_start_time = 0;
1411 rtlpcipriv->bt_coexist.cstate &=
1412 ~BT_COEX_STATE_BT_INQ_PAGE;
1413 }
1414 }
1415}
1416
1417static void rtl8723ae_dm_bt_reset_action_profile_state(struct ieee80211_hw *hw)
1418{
1419 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1420
1421 rtlpcipriv->bt_coexist.cstate &=
1422 ~(BT_COEX_STATE_PROFILE_HID | BT_COEX_STATE_PROFILE_A2DP |
1423 BT_COEX_STATE_PROFILE_PAN | BT_COEX_STATE_PROFILE_SCO);
1424
1425 rtlpcipriv->bt_coexist.cstate &=
1426 ~(BT_COEX_STATE_BTINFO_COMMON |
1427 BT_COEX_STATE_BTINFO_B_HID_SCOESCO |
1428 BT_COEX_STATE_BTINFO_B_FTP_A2DP);
1429}
1430
1431static void _rtl8723ae_dm_bt_coexist_2_ant(struct ieee80211_hw *hw)
1432{
1433 struct rtl_priv *rtlpriv = rtl_priv(hw);
1434 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1435 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1436 u8 bt_retry_cnt;
1437 u8 bt_info_original;
1438 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1439 "[BTCoex] Get bt info by fw!!\n");
1440
1441 _rtl8723_dm_bt_check_wifi_state(hw);
1442
1443 if (rtlhal->hal_coex_8723.c2h_bt_info_req_sent) {
1444 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1445 "[BTCoex] c2h for btInfo not rcvd yet!!\n");
1446 }
1447
1448 bt_retry_cnt = rtlhal->hal_coex_8723.bt_retry_cnt;
1449 bt_info_original = rtlhal->hal_coex_8723.c2h_bt_info_original;
1450
1451 /* when bt inquiry or page scan, we have to set h2c 0x25
1452 * ignore wlanact for continuous 4x2secs
1453 */
1454 rtl8723ae_dm_bt_inq_page_monitor(hw);
1455 rtl8723ae_dm_bt_reset_action_profile_state(hw);
1456
1457 if (rtl8723ae_dm_bt_is_2_ant_common_action(hw)) {
1458 rtlpcipriv->bt_coexist.bt_profile_case = BT_COEX_MECH_COMMON;
1459 rtlpcipriv->bt_coexist.bt_profile_action = BT_COEX_MECH_COMMON;
1460
1461 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1462 "Action 2-Ant common.\n");
1463 } else {
1464 if ((bt_info_original & BTINFO_B_HID) ||
1465 (bt_info_original & BTINFO_B_SCO_BUSY) ||
1466 (bt_info_original & BTINFO_B_SCO_ESCO)) {
1467 rtlpcipriv->bt_coexist.cstate |=
1468 BT_COEX_STATE_BTINFO_B_HID_SCOESCO;
1469 rtlpcipriv->bt_coexist.bt_profile_case =
1470 BT_COEX_MECH_HID_SCO_ESCO;
1471 rtlpcipriv->bt_coexist.bt_profile_action =
1472 BT_COEX_MECH_HID_SCO_ESCO;
1473 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1474 "[BTCoex], BTInfo: bHid|bSCOBusy|bSCOeSCO\n");
1475 rtl8723ae_dm_bt_2_ant_hid_sco_esco(hw);
1476 } else if ((bt_info_original & BTINFO_B_FTP) ||
1477 (bt_info_original & BTINFO_B_A2DP)) {
1478 rtlpcipriv->bt_coexist.cstate |=
1479 BT_COEX_STATE_BTINFO_B_FTP_A2DP;
1480 rtlpcipriv->bt_coexist.bt_profile_case =
1481 BT_COEX_MECH_FTP_A2DP;
1482 rtlpcipriv->bt_coexist.bt_profile_action =
1483 BT_COEX_MECH_FTP_A2DP;
1484 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1485 "BTInfo: bFTP|bA2DP\n");
1486 rtl8723ae_dm_bt_2_ant_fta2dp(hw);
1487 } else {
1488 rtlpcipriv->bt_coexist.cstate |=
1489 BT_COEX_STATE_BTINFO_B_HID_SCOESCO;
1490 rtlpcipriv->bt_coexist.bt_profile_case =
1491 BT_COEX_MECH_NONE;
1492 rtlpcipriv->bt_coexist.bt_profile_action =
1493 BT_COEX_MECH_NONE;
1494 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1495 "[BTCoex], BTInfo: undefined case!!!!\n");
1496 rtl8723ae_dm_bt_2_ant_hid_sco_esco(hw);
1497 }
1498 }
1499}
1500
1501static void _rtl8723ae_dm_bt_coexist_1_ant(struct ieee80211_hw *hw)
1502{
1503}
1504
1505void rtl8723ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw)
1506{
1507 rtl8723ae_dm_bt_set_coex_table(hw, 0x5a5aaaaa, 0xcc, 0x3);
1508 rtl8723ae_dm_bt_set_hw_pta_mode(hw, true);
1509}
1510
1511void rtl8723ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw)
1512{
1513 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, false);
1514 rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
1515 rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
1516 rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, false,
1517 TDMA_2ANT, TDMA_NAV_OFF);
1518 rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, TDMA_2ANT,
1519 TDMA_NAV_OFF, TDMA_DAC_SWING_OFF);
1520 rtl8723ae_dm_bt_set_fw_dac_swing_level(hw, 0);
1521 rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false);
1522 rtl8723ae_dm_bt_set_fw_bt_retry_index(hw, 2);
1523 rtl8723ae_dm_bt_set_fw_wlan_act(hw, 0x10, 0x10);
1524 rtl8723ae_dm_bt_set_fw_dec_bt_pwr(hw, false);
1525}
1526
1527void rtl8723ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw)
1528{
1529 rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF);
1530 rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_OFF);
1531 rtl8723ae_dm_bt_reject_ap_aggregated_packet(hw, false);
1532
1533 rtl8723ae_bt_set_penalty_tx_rate_adap(hw, BT_TX_RATE_ADAPTIVE_NORMAL);
1534 rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, BT_RF_RX_LPF_CORNER_RESUME);
1535 rtl8723ae_dm_bt_set_sw_full_time_dac_swing(hw, false, 0xc0);
1536}
1537
1538static void rtl8723ae_dm_bt_query_bt_information(struct ieee80211_hw *hw)
1539{
1540 struct rtl_priv *rtlpriv = rtl_priv(hw);
1541 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1542 u8 h2c_parameter[1] = {0};
1543
1544 rtlhal->hal_coex_8723.c2h_bt_info_req_sent = true;
1545
1546 h2c_parameter[0] |= BIT(0);
1547
1548 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1549 "Query Bt information, write 0x38 = 0x%x\n",
1550 h2c_parameter[0]);
1551
1552 rtl8723ae_fill_h2c_cmd(hw, 0x38, 1, h2c_parameter);
1553}
1554
1555static void rtl8723ae_dm_bt_bt_hw_counters_monitor(struct ieee80211_hw *hw)
1556{
1557 struct rtl_priv *rtlpriv = rtl_priv(hw);
1558 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1559 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1560 u32 reg_htx_rx, reg_ltx_rx, u32_tmp;
1561 u32 reg_htx, reg_hrx, reg_ltx, reg_lrx;
1562
1563 reg_htx_rx = REG_HIGH_PRIORITY_TXRX;
1564 reg_ltx_rx = REG_LOW_PRIORITY_TXRX;
1565
1566 u32_tmp = rtl_read_dword(rtlpriv, reg_htx_rx);
1567 reg_htx = u32_tmp & MASKLWORD;
1568 reg_hrx = (u32_tmp & MASKHWORD)>>16;
1569
1570 u32_tmp = rtl_read_dword(rtlpriv, reg_ltx_rx);
1571 reg_ltx = u32_tmp & MASKLWORD;
1572 reg_lrx = (u32_tmp & MASKHWORD)>>16;
1573
1574 if (rtlpcipriv->bt_coexist.lps_counter > 1) {
1575 reg_htx %= rtlpcipriv->bt_coexist.lps_counter;
1576 reg_hrx %= rtlpcipriv->bt_coexist.lps_counter;
1577 reg_ltx %= rtlpcipriv->bt_coexist.lps_counter;
1578 reg_lrx %= rtlpcipriv->bt_coexist.lps_counter;
1579 }
1580
1581 rtlhal->hal_coex_8723.high_priority_tx = reg_htx;
1582 rtlhal->hal_coex_8723.high_priority_rx = reg_hrx;
1583 rtlhal->hal_coex_8723.low_priority_tx = reg_ltx;
1584 rtlhal->hal_coex_8723.low_priority_rx = reg_lrx;
1585
1586 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1587 "High Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n",
1588 reg_htx_rx, reg_htx, reg_htx, reg_hrx, reg_hrx);
1589 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1590 "Low Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n",
1591 reg_ltx_rx, reg_ltx, reg_ltx, reg_lrx, reg_lrx);
1592 rtlpcipriv->bt_coexist.lps_counter = 0;
1593}
1594
1595static void rtl8723ae_dm_bt_bt_enable_disable_check(struct ieee80211_hw *hw)
1596{
1597 struct rtl_priv *rtlpriv = rtl_priv(hw);
1598 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1599 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1600 bool bt_alife = true;
1601
1602 if (rtlhal->hal_coex_8723.high_priority_tx == 0 &&
1603 rtlhal->hal_coex_8723.high_priority_rx == 0 &&
1604 rtlhal->hal_coex_8723.low_priority_tx == 0 &&
1605 rtlhal->hal_coex_8723.low_priority_rx == 0)
1606 bt_alife = false;
1607 if (rtlhal->hal_coex_8723.high_priority_tx == 0xeaea &&
1608 rtlhal->hal_coex_8723.high_priority_rx == 0xeaea &&
1609 rtlhal->hal_coex_8723.low_priority_tx == 0xeaea &&
1610 rtlhal->hal_coex_8723.low_priority_rx == 0xeaea)
1611 bt_alife = false;
1612 if (rtlhal->hal_coex_8723.high_priority_tx == 0xffff &&
1613 rtlhal->hal_coex_8723.high_priority_rx == 0xffff &&
1614 rtlhal->hal_coex_8723.low_priority_tx == 0xffff &&
1615 rtlhal->hal_coex_8723.low_priority_rx == 0xffff)
1616 bt_alife = false;
1617 if (bt_alife) {
1618 rtlpcipriv->bt_coexist.bt_active_zero_cnt = 0;
1619 rtlpcipriv->bt_coexist.cur_bt_disabled = false;
1620 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1621 "8723A BT is enabled !!\n");
1622 } else {
1623 rtlpcipriv->bt_coexist.bt_active_zero_cnt++;
1624 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1625 "8723A bt all counters = 0, %d times!!\n",
1626 rtlpcipriv->bt_coexist.bt_active_zero_cnt);
1627 if (rtlpcipriv->bt_coexist.bt_active_zero_cnt >= 2) {
1628 rtlpcipriv->bt_coexist.cur_bt_disabled = true;
1629 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1630 "8723A BT is disabled !!\n");
1631 }
1632 }
1633 if (rtlpcipriv->bt_coexist.pre_bt_disabled !=
1634 rtlpcipriv->bt_coexist.cur_bt_disabled) {
1635 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1636 "8723A BT is from %s to %s!!\n",
1637 (rtlpcipriv->bt_coexist.pre_bt_disabled ?
1638 "disabled" : "enabled"),
1639 (rtlpcipriv->bt_coexist.cur_bt_disabled ?
1640 "disabled" : "enabled"));
1641 rtlpcipriv->bt_coexist.pre_bt_disabled
1642 = rtlpcipriv->bt_coexist.cur_bt_disabled;
1643 }
1644}
1645
1646
1647void rtl8723ae_dm_bt_coexist_8723(struct ieee80211_hw *hw)
1648{
1649 struct rtl_priv *rtlpriv = rtl_priv(hw);
1650 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1651
1652 rtl8723ae_dm_bt_query_bt_information(hw);
1653 rtl8723ae_dm_bt_bt_hw_counters_monitor(hw);
1654 rtl8723ae_dm_bt_bt_enable_disable_check(hw);
1655
1656 if (rtlpcipriv->bt_coexist.bt_ant_num == ANT_X2) {
1657 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1658 "[BTCoex], 2 Ant mechanism\n");
1659 _rtl8723ae_dm_bt_coexist_2_ant(hw);
1660 } else {
1661 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1662 "[BTCoex], 1 Ant mechanism\n");
1663 _rtl8723ae_dm_bt_coexist_1_ant(hw);
1664 }
1665
1666 if (!rtl8723ae_dm_bt_is_same_coexist_state(hw)) {
1667 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1668 "[BTCoex], Coexist State[bitMap] change from 0x%x%8x to 0x%x%8x\n",
1669 rtlpcipriv->bt_coexist.previous_state_h,
1670 rtlpcipriv->bt_coexist.previous_state,
1671 rtlpcipriv->bt_coexist.cstate_h,
1672 rtlpcipriv->bt_coexist.cstate);
1673 rtlpcipriv->bt_coexist.previous_state
1674 = rtlpcipriv->bt_coexist.cstate;
1675 rtlpcipriv->bt_coexist.previous_state_h
1676 = rtlpcipriv->bt_coexist.cstate_h;
1677 }
1678}
1679
1680static void rtl8723ae_dm_bt_parse_bt_info(struct ieee80211_hw *hw,
1681 u8 *tmbuf, u8 len)
1682{
1683 struct rtl_priv *rtlpriv = rtl_priv(hw);
1684 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1685 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1686 u8 bt_info;
1687 u8 i;
1688
1689 rtlhal->hal_coex_8723.c2h_bt_info_req_sent = false;
1690 rtlhal->hal_coex_8723.bt_retry_cnt = 0;
1691 for (i = 0; i < len; i++) {
1692 if (i == 0)
1693 rtlhal->hal_coex_8723.c2h_bt_info_original = tmbuf[i];
1694 else if (i == 1)
1695 rtlhal->hal_coex_8723.bt_retry_cnt = tmbuf[i];
1696 if (i == len-1) {
1697 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1698 "0x%2x]", tmbuf[i]);
1699 } else {
1700 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1701 "0x%2x, ", tmbuf[i]);
1702 }
1703 }
1704 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1705 "BT info bt_info (Data)= 0x%x\n",
1706 rtlhal->hal_coex_8723.c2h_bt_info_original);
1707 bt_info = rtlhal->hal_coex_8723.c2h_bt_info_original;
1708
1709 if (bt_info & BIT(2))
1710 rtlhal->hal_coex_8723.c2h_bt_inquiry_page = true;
1711 else
1712 rtlhal->hal_coex_8723.c2h_bt_inquiry_page = false;
1713
1714 if (bt_info & BTINFO_B_CONNECTION) {
1715 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1716 "[BTC2H], BTInfo: bConnect=true\n");
1717 rtlpcipriv->bt_coexist.bt_busy = true;
1718 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_BT_IDLE;
1719 } else {
1720 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1721 "[BTC2H], BTInfo: bConnect=false\n");
1722 rtlpcipriv->bt_coexist.bt_busy = false;
1723 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BT_IDLE;
1724 }
1725}
1726void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw)
1727{
1728 struct rtl_priv *rtlpriv = rtl_priv(hw);
1729 struct c2h_evt_hdr c2h_event;
1730 u8 *ptmbuf;
1731 u8 index;
1732 u8 u1tmp;
1733
1734 memset(&c2h_event, 0, sizeof(c2h_event));
1735 u1tmp = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL);
1736 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
1737 "&&&&&&: REG_C2HEVT_MSG_NORMAL is 0x%x\n", u1tmp);
1738 c2h_event.cmd_id = u1tmp & 0xF;
1739 c2h_event.cmd_len = (u1tmp & 0xF0) >> 4;
1740 c2h_event.cmd_seq = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + 1);
1741 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
1742 "cmd_id: %d, cmd_len: %d, cmd_seq: %d\n",
1743 c2h_event.cmd_id , c2h_event.cmd_len, c2h_event.cmd_seq);
1744 u1tmp = rtl_read_byte(rtlpriv, 0x01AF);
1745 if (u1tmp == C2H_EVT_HOST_CLOSE) {
1746 return;
1747 } else if (u1tmp != C2H_EVT_FW_CLOSE) {
1748 rtl_write_byte(rtlpriv, 0x1AF, 0x00);
1749 return;
1750 }
1751 ptmbuf = kmalloc(c2h_event.cmd_len, GFP_KERNEL);
1752 if (ptmbuf == NULL) {
1753 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1754 "malloc cmd buf failed\n");
1755 return;
1756 }
1757
1758 /* Read the content */
1759 for (index = 0; index < c2h_event.cmd_len; index++)
1760 ptmbuf[index] = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL +
1761 2 + index);
1762
1763 switch (c2h_event.cmd_id) {
1764 case C2H_BT_RSSI:
1765 break;
1766
1767 case C2H_BT_OP_MODE:
1768 break;
1769
1770 case BT_INFO:
1771 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1772 "BT info Byte[0] (ID) is 0x%x\n", c2h_event.cmd_id);
1773 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1774 "BT info Byte[1] (Seq) is 0x%x\n", c2h_event.cmd_seq);
1775 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1776 "BT info Byte[2] (Data)= 0x%x\n", ptmbuf[0]);
1777
1778 rtl8723ae_dm_bt_parse_bt_info(hw, ptmbuf, c2h_event.cmd_len);
1779 break;
1780 default:
1781 break;
1782 }
1783 kfree(ptmbuf);
1784
1785 rtl_write_byte(rtlpriv, 0x01AF, C2H_EVT_HOST_CLOSE);
1786}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h
new file mode 100644
index 000000000000..4325ecd58f0c
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h
@@ -0,0 +1,151 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 * Larry Finger <Larry.Finger@lwfinger.net>
26 *
27 ****************************************************************************
28 */
29
30#ifndef __RTL8723E_HAL_BTC_H__
31#define __RTL8723E_HAL_BTC_H__
32
33#include "../wifi.h"
34#include "btc.h"
35#include "hal_bt_coexist.h"
36
37#define BT_TXRX_CNT_THRES_1 1200
38#define BT_TXRX_CNT_THRES_2 1400
39#define BT_TXRX_CNT_THRES_3 3000
40#define BT_TXRX_CNT_LEVEL_0 0 /* < 1200 */
41#define BT_TXRX_CNT_LEVEL_1 1 /* >= 1200 && < 1400 */
42#define BT_TXRX_CNT_LEVEL_2 2 /* >= 1400 */
43#define BT_TXRX_CNT_LEVEL_3 3
44
45/* TDMA mode definition */
46#define TDMA_2ANT 0
47#define TDMA_1ANT 1
48#define TDMA_NAV_OFF 0
49#define TDMA_NAV_ON 1
50#define TDMA_DAC_SWING_OFF 0
51#define TDMA_DAC_SWING_ON 1
52
53/* PTA mode related definition */
54#define BT_PTA_MODE_OFF 0
55#define BT_PTA_MODE_ON 1
56
57/* Penalty Tx Rate Adaptive */
58#define BT_TX_RATE_ADAPTIVE_NORMAL 0
59#define BT_TX_RATE_ADAPTIVE_LOW_PENALTY 1
60
61/* RF Corner */
62#define BT_RF_RX_LPF_CORNER_RESUME 0
63#define BT_RF_RX_LPF_CORNER_SHRINK 1
64
65#define C2H_EVT_HOST_CLOSE 0x00
66#define C2H_EVT_FW_CLOSE 0xFF
67
68enum bt_traffic_mode {
69 BT_MOTOR_EXT_BE = 0x00,
70 BT_MOTOR_EXT_GUL = 0x01,
71 BT_MOTOR_EXT_GUB = 0x02,
72 BT_MOTOR_EXT_GULB = 0x03
73};
74
75enum bt_traffic_mode_profile {
76 BT_PROFILE_NONE,
77 BT_PROFILE_A2DP,
78 BT_PROFILE_PAN,
79 BT_PROFILE_HID,
80 BT_PROFILE_SCO
81};
82
83enum hci_ext_bt_operation {
84 HCI_BT_OP_NONE = 0x0,
85 HCI_BT_OP_INQUIRE_START = 0x1,
86 HCI_BT_OP_INQUIRE_FINISH = 0x2,
87 HCI_BT_OP_PAGING_START = 0x3,
88 HCI_BT_OP_PAGING_SUCCESS = 0x4,
89 HCI_BT_OP_PAGING_UNSUCCESS = 0x5,
90 HCI_BT_OP_PAIRING_START = 0x6,
91 HCI_BT_OP_PAIRING_FINISH = 0x7,
92 HCI_BT_OP_BT_DEV_ENABLE = 0x8,
93 HCI_BT_OP_BT_DEV_DISABLE = 0x9,
94 HCI_BT_OP_MAX,
95};
96
97enum bt_spec {
98 BT_SPEC_1_0_b = 0x00,
99 BT_SPEC_1_1 = 0x01,
100 BT_SPEC_1_2 = 0x02,
101 BT_SPEC_2_0_EDR = 0x03,
102 BT_SPEC_2_1_EDR = 0x04,
103 BT_SPEC_3_0_HS = 0x05,
104 BT_SPEC_4_0 = 0x06
105};
106
107struct c2h_evt_hdr {
108 u8 cmd_id;
109 u8 cmd_len;
110 u8 cmd_seq;
111};
112
113enum bt_state {
114 BT_INFO_STATE_DISABLED = 0,
115 BT_INFO_STATE_NO_CONNECTION = 1,
116 BT_INFO_STATE_CONNECT_IDLE = 2,
117 BT_INFO_STATE_INQ_OR_PAG = 3,
118 BT_INFO_STATE_ACL_ONLY_BUSY = 4,
119 BT_INFO_STATE_SCO_ONLY_BUSY = 5,
120 BT_INFO_STATE_ACL_SCO_BUSY = 6,
121 BT_INFO_STATE_HID_BUSY = 7,
122 BT_INFO_STATE_HID_SCO_BUSY = 8,
123 BT_INFO_STATE_MAX = 7
124};
125
126enum rtl8723ae_c2h_evt {
127 C2H_DBG = 0,
128 C2H_TSF = 1,
129 C2H_AP_RPT_RSP = 2,
130 C2H_CCX_TX_RPT = 3, /* The FW notify the report of the specific */
131 /* tx packet. */
132 C2H_BT_RSSI = 4,
133 C2H_BT_OP_MODE = 5,
134 C2H_HW_INFO_EXCH = 10,
135 C2H_C2H_H2C_TEST = 11,
136 BT_INFO = 12,
137 MAX_C2HEVENT
138};
139
140void rtl8723ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw);
141void rtl8723ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw);
142void rtl8723ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw);
143void rtl8723ae_dm_bt_coexist_8723(struct ieee80211_hw *hw);
144void rtl8723ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw,
145 struct btdm_8723 *p_btdm);
146void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw);
147void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw,
148 bool mstatus);
149void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw);
150
151#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
new file mode 100644
index 000000000000..0a8c03863fb2
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -0,0 +1,2380 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 "../efuse.h"
32#include "../base.h"
33#include "../regd.h"
34#include "../cam.h"
35#include "../ps.h"
36#include "../pci.h"
37#include "reg.h"
38#include "def.h"
39#include "phy.h"
40#include "dm.h"
41#include "fw.h"
42#include "led.h"
43#include "hw.h"
44#include "pwrseqcmd.h"
45#include "pwrseq.h"
46#include "btc.h"
47
48static void _rtl8723ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
49 u8 set_bits, u8 clear_bits)
50{
51 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
52 struct rtl_priv *rtlpriv = rtl_priv(hw);
53
54 rtlpci->reg_bcn_ctrl_val |= set_bits;
55 rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
56
57 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
58}
59
60static void _rtl8723ae_stop_tx_beacon(struct ieee80211_hw *hw)
61{
62 struct rtl_priv *rtlpriv = rtl_priv(hw);
63 u8 tmp1byte;
64
65 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
66 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
67 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
68 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
69 tmp1byte &= ~(BIT(0));
70 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
71}
72
73static void _rtl8723ae_resume_tx_beacon(struct ieee80211_hw *hw)
74{
75 struct rtl_priv *rtlpriv = rtl_priv(hw);
76 u8 tmp1byte;
77
78 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
79 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
80 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
81 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
82 tmp1byte |= BIT(1);
83 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
84}
85
86static void _rtl8723ae_enable_bcn_sufunc(struct ieee80211_hw *hw)
87{
88 _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(1));
89}
90
91static void _rtl8723ae_disable_bcn_sufunc(struct ieee80211_hw *hw)
92{
93 _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(1), 0);
94}
95
96void rtl8723ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
97{
98 struct rtl_priv *rtlpriv = rtl_priv(hw);
99 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
100 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
101
102 switch (variable) {
103 case HW_VAR_RCR:
104 *((u32 *) (val)) = rtlpci->receive_config;
105 break;
106 case HW_VAR_RF_STATE:
107 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
108 break;
109 case HW_VAR_FWLPS_RF_ON:{
110 enum rf_pwrstate rfState;
111 u32 val_rcr;
112
113 rtlpriv->cfg->ops->get_hw_reg(hw,
114 HW_VAR_RF_STATE,
115 (u8 *) (&rfState));
116 if (rfState == ERFOFF) {
117 *((bool *) (val)) = true;
118 } else {
119 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
120 val_rcr &= 0x00070000;
121 if (val_rcr)
122 *((bool *) (val)) = false;
123 else
124 *((bool *) (val)) = true;
125 }
126 break; }
127 case HW_VAR_FW_PSMODE_STATUS:
128 *((bool *) (val)) = ppsc->fw_current_inpsmode;
129 break;
130 case HW_VAR_CORRECT_TSF:{
131 u64 tsf;
132 u32 *ptsf_low = (u32 *)&tsf;
133 u32 *ptsf_high = ((u32 *)&tsf) + 1;
134
135 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
136 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
137
138 *((u64 *) (val)) = tsf;
139
140 break; }
141 default:
142 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
143 "switch case not process\n");
144 break;
145 }
146}
147
148void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
149{
150 struct rtl_priv *rtlpriv = rtl_priv(hw);
151 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
152 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
153 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
154 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
155 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
156 u8 idx;
157
158 switch (variable) {
159 case HW_VAR_ETHER_ADDR:
160 for (idx = 0; idx < ETH_ALEN; idx++) {
161 rtl_write_byte(rtlpriv, (REG_MACID + idx),
162 val[idx]);
163 }
164 break;
165 case HW_VAR_BASIC_RATE:{
166 u16 rate_cfg = ((u16 *) val)[0];
167 u8 rate_index = 0;
168 rate_cfg = rate_cfg & 0x15f;
169 rate_cfg |= 0x01;
170 rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);
171 rtl_write_byte(rtlpriv, REG_RRSR + 1,
172 (rate_cfg >> 8) & 0xff);
173 while (rate_cfg > 0x1) {
174 rate_cfg = (rate_cfg >> 1);
175 rate_index++;
176 }
177 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL,
178 rate_index);
179 break; }
180 case HW_VAR_BSSID:
181 for (idx = 0; idx < ETH_ALEN; idx++) {
182 rtl_write_byte(rtlpriv, (REG_BSSID + idx),
183 val[idx]);
184 }
185 break;
186 case HW_VAR_SIFS:
187 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
188 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
189
190 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
191 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
192
193 if (!mac->ht_enable)
194 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
195 0x0e0e);
196 else
197 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
198 *((u16 *) val));
199 break;
200 case HW_VAR_SLOT_TIME:{
201 u8 e_aci;
202
203 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
204 "HW_VAR_SLOT_TIME %x\n", val[0]);
205
206 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
207
208 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
209 rtlpriv->cfg->ops->set_hw_reg(hw,
210 HW_VAR_AC_PARAM,
211 (u8 *) (&e_aci));
212 }
213 break; }
214 case HW_VAR_ACK_PREAMBLE:{
215 u8 reg_tmp;
216 u8 short_preamble = (bool) (*(u8 *) val);
217 reg_tmp = (mac->cur_40_prime_sc) << 5;
218 if (short_preamble)
219 reg_tmp |= 0x80;
220
221 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp);
222 break; }
223 case HW_VAR_AMPDU_MIN_SPACE:{
224 u8 min_spacing_to_set;
225 u8 sec_min_space;
226
227 min_spacing_to_set = *((u8 *) val);
228 if (min_spacing_to_set <= 7) {
229 sec_min_space = 0;
230
231 if (min_spacing_to_set < sec_min_space)
232 min_spacing_to_set = sec_min_space;
233
234 mac->min_space_cfg = ((mac->min_space_cfg &
235 0xf8) |
236 min_spacing_to_set);
237
238 *val = min_spacing_to_set;
239
240 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
241 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
242 mac->min_space_cfg);
243
244 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
245 mac->min_space_cfg);
246 }
247 break; }
248 case HW_VAR_SHORTGI_DENSITY:{
249 u8 density_to_set;
250
251 density_to_set = *((u8 *) val);
252 mac->min_space_cfg |= (density_to_set << 3);
253
254 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
255 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
256 mac->min_space_cfg);
257
258 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
259 mac->min_space_cfg);
260
261 break; }
262 case HW_VAR_AMPDU_FACTOR:{
263 u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
264 u8 regtoset_bt[4] = {0x31, 0x74, 0x42, 0x97};
265 u8 factor_toset;
266 u8 *p_regtoset = NULL;
267 u8 index;
268
269 if ((pcipriv->bt_coexist.bt_coexistence) &&
270 (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4))
271 p_regtoset = regtoset_bt;
272 else
273 p_regtoset = regtoset_normal;
274
275 factor_toset = *((u8 *) val);
276 if (factor_toset <= 3) {
277 factor_toset = (1 << (factor_toset + 2));
278 if (factor_toset > 0xf)
279 factor_toset = 0xf;
280
281 for (index = 0; index < 4; index++) {
282 if ((p_regtoset[index] & 0xf0) >
283 (factor_toset << 4))
284 p_regtoset[index] =
285 (p_regtoset[index] & 0x0f) |
286 (factor_toset << 4);
287
288 if ((p_regtoset[index] & 0x0f) >
289 factor_toset)
290 p_regtoset[index] =
291 (p_regtoset[index] & 0xf0) |
292 (factor_toset);
293
294 rtl_write_byte(rtlpriv,
295 (REG_AGGLEN_LMT + index),
296 p_regtoset[index]);
297
298 }
299
300 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
301 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
302 factor_toset);
303 }
304 break; }
305 case HW_VAR_AC_PARAM:{
306 u8 e_aci = *((u8 *) val);
307 rtl8723ae_dm_init_edca_turbo(hw);
308
309 if (rtlpci->acm_method != eAcmWay2_SW)
310 rtlpriv->cfg->ops->set_hw_reg(hw,
311 HW_VAR_ACM_CTRL,
312 (u8 *) (&e_aci));
313 break; }
314 case HW_VAR_ACM_CTRL:{
315 u8 e_aci = *((u8 *) val);
316 union aci_aifsn *p_aci_aifsn =
317 (union aci_aifsn *)(&(mac->ac[0].aifs));
318 u8 acm = p_aci_aifsn->f.acm;
319 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
320
321 acm_ctrl |= ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
322
323 if (acm) {
324 switch (e_aci) {
325 case AC0_BE:
326 acm_ctrl |= AcmHw_BeqEn;
327 break;
328 case AC2_VI:
329 acm_ctrl |= AcmHw_ViqEn;
330 break;
331 case AC3_VO:
332 acm_ctrl |= AcmHw_VoqEn;
333 break;
334 default:
335 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
336 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
337 acm);
338 break;
339 }
340 } else {
341 switch (e_aci) {
342 case AC0_BE:
343 acm_ctrl &= (~AcmHw_BeqEn);
344 break;
345 case AC2_VI:
346 acm_ctrl &= (~AcmHw_ViqEn);
347 break;
348 case AC3_VO:
349 acm_ctrl &= (~AcmHw_BeqEn);
350 break;
351 default:
352 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
353 "switch case not processed\n");
354 break;
355 }
356 }
357
358 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
359 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
360 acm_ctrl);
361 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
362 break; }
363 case HW_VAR_RCR:
364 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]);
365 rtlpci->receive_config = ((u32 *) (val))[0];
366 break;
367 case HW_VAR_RETRY_LIMIT:{
368 u8 retry_limit = ((u8 *) (val))[0];
369
370 rtl_write_word(rtlpriv, REG_RL,
371 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
372 retry_limit << RETRY_LIMIT_LONG_SHIFT);
373 break; }
374 case HW_VAR_DUAL_TSF_RST:
375 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
376 break;
377 case HW_VAR_EFUSE_BYTES:
378 rtlefuse->efuse_usedbytes = *((u16 *) val);
379 break;
380 case HW_VAR_EFUSE_USAGE:
381 rtlefuse->efuse_usedpercentage = *((u8 *) val);
382 break;
383 case HW_VAR_IO_CMD:
384 rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val));
385 break;
386 case HW_VAR_WPA_CONFIG:
387 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val));
388 break;
389 case HW_VAR_SET_RPWM:{
390 u8 rpwm_val;
391
392 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
393 udelay(1);
394
395 if (rpwm_val & BIT(7)) {
396 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
397 (*(u8 *) val));
398 } else {
399 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
400 ((*(u8 *) val) | BIT(7)));
401 }
402
403 break; }
404 case HW_VAR_H2C_FW_PWRMODE:{
405 u8 psmode = (*(u8 *) val);
406
407 if (psmode != FW_PS_ACTIVE_MODE)
408 rtl8723ae_dm_rf_saving(hw, true);
409
410 rtl8723ae_set_fw_pwrmode_cmd(hw, (*(u8 *) val));
411 break; }
412 case HW_VAR_FW_PSMODE_STATUS:
413 ppsc->fw_current_inpsmode = *((bool *) val);
414 break;
415 case HW_VAR_H2C_FW_JOINBSSRPT:{
416 u8 mstatus = (*(u8 *) val);
417 u8 tmp_regcr, tmp_reg422;
418 bool recover = false;
419
420 if (mstatus == RT_MEDIA_CONNECT) {
421 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
422
423 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
424 rtl_write_byte(rtlpriv, REG_CR + 1,
425 (tmp_regcr | BIT(0)));
426
427 _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(3));
428 _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(4), 0);
429
430 tmp_reg422 = rtl_read_byte(rtlpriv,
431 REG_FWHW_TXQ_CTRL + 2);
432 if (tmp_reg422 & BIT(6))
433 recover = true;
434 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
435 tmp_reg422 & (~BIT(6)));
436
437 rtl8723ae_set_fw_rsvdpagepkt(hw, 0);
438
439 _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(3), 0);
440 _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(4));
441
442 if (recover)
443 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
444 tmp_reg422);
445
446 rtl_write_byte(rtlpriv, REG_CR + 1,
447 (tmp_regcr & ~(BIT(0))));
448 }
449 rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val));
450
451 break; }
452 case HW_VAR_AID:{
453 u16 u2btmp;
454 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
455 u2btmp &= 0xC000;
456 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp |
457 mac->assoc_id));
458 break; }
459 case HW_VAR_CORRECT_TSF:{
460 u8 btype_ibss = ((u8 *) (val))[0];
461
462 if (btype_ibss == true)
463 _rtl8723ae_stop_tx_beacon(hw);
464
465 _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(3));
466
467 rtl_write_dword(rtlpriv, REG_TSFTR,
468 (u32) (mac->tsf & 0xffffffff));
469 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
470 (u32) ((mac->tsf >> 32) & 0xffffffff));
471
472 _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(3), 0);
473
474 if (btype_ibss == true)
475 _rtl8723ae_resume_tx_beacon(hw);
476 break; }
477 default:
478 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
479 "switch case not processed\n");
480 break;
481 }
482}
483
484static bool _rtl8723ae_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
485{
486 struct rtl_priv *rtlpriv = rtl_priv(hw);
487 bool status = true;
488 long count = 0;
489 u32 value = _LLT_INIT_ADDR(address) |
490 _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
491
492 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
493
494 do {
495 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
496 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
497 break;
498
499 if (count > POLLING_LLT_THRESHOLD) {
500 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
501 "Failed to polling write LLT done at address %d!\n",
502 address);
503 status = false;
504 break;
505 }
506 } while (++count);
507
508 return status;
509}
510
511static bool _rtl8723ae_llt_table_init(struct ieee80211_hw *hw)
512{
513 struct rtl_priv *rtlpriv = rtl_priv(hw);
514 unsigned short i;
515 u8 txpktbuf_bndy;
516 u8 maxPage;
517 bool status;
518 u8 ubyte;
519
520 maxPage = 255;
521 txpktbuf_bndy = 246;
522
523 rtl_write_byte(rtlpriv, REG_CR, 0x8B);
524
525 rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000);
526
527 rtl_write_dword(rtlpriv, REG_RQPN, 0x80ac1c29);
528 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x03);
529
530 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy));
531 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
532
533 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
534 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
535
536 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
537 rtl_write_byte(rtlpriv, REG_PBP, 0x11);
538 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
539
540 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
541 status = _rtl8723ae_llt_write(hw, i, i + 1);
542 if (true != status)
543 return status;
544 }
545
546 status = _rtl8723ae_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
547 if (true != status)
548 return status;
549
550 for (i = txpktbuf_bndy; i < maxPage; i++) {
551 status = _rtl8723ae_llt_write(hw, i, (i + 1));
552 if (true != status)
553 return status;
554 }
555
556 status = _rtl8723ae_llt_write(hw, maxPage, txpktbuf_bndy);
557 if (true != status)
558 return status;
559
560 rtl_write_byte(rtlpriv, REG_CR, 0xff);
561 ubyte = rtl_read_byte(rtlpriv, REG_RQPN + 3);
562 rtl_write_byte(rtlpriv, REG_RQPN + 3, ubyte | BIT(7));
563
564 return true;
565}
566
567static void _rtl8723ae_gen_refresh_led_state(struct ieee80211_hw *hw)
568{
569 struct rtl_priv *rtlpriv = rtl_priv(hw);
570 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
571 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
572 struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
573
574 if (rtlpriv->rtlhal.up_first_time)
575 return;
576
577 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
578 rtl8723ae_sw_led_on(hw, pLed0);
579 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
580 rtl8723ae_sw_led_on(hw, pLed0);
581 else
582 rtl8723ae_sw_led_off(hw, pLed0);
583}
584
585static bool _rtl8712e_init_mac(struct ieee80211_hw *hw)
586{
587 struct rtl_priv *rtlpriv = rtl_priv(hw);
588 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
589 unsigned char bytetmp;
590 unsigned short wordtmp;
591 u16 retry = 0;
592 u16 tmpu2b;
593 bool mac_func_enable;
594
595 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
596 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
597 if (bytetmp == 0xFF)
598 mac_func_enable = true;
599 else
600 mac_func_enable = false;
601
602
603 /* HW Power on sequence */
604 if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
605 PWR_INTF_PCI_MSK, Rtl8723_NIC_ENABLE_FLOW))
606 return false;
607
608 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+2);
609 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+2, bytetmp | BIT(4));
610
611 /* eMAC time out function enable, 0x369[7]=1 */
612 bytetmp = rtl_read_byte(rtlpriv, 0x369);
613 rtl_write_byte(rtlpriv, 0x369, bytetmp | BIT(7));
614
615 /* ePHY reg 0x1e bit[4]=1 using MDIO interface,
616 * we should do this before Enabling ASPM backdoor.
617 */
618 do {
619 rtl_write_word(rtlpriv, 0x358, 0x5e);
620 udelay(100);
621 rtl_write_word(rtlpriv, 0x356, 0xc280);
622 rtl_write_word(rtlpriv, 0x354, 0xc290);
623 rtl_write_word(rtlpriv, 0x358, 0x3e);
624 udelay(100);
625 rtl_write_word(rtlpriv, 0x358, 0x5e);
626 udelay(100);
627 tmpu2b = rtl_read_word(rtlpriv, 0x356);
628 retry++;
629 } while (tmpu2b != 0xc290 && retry < 100);
630
631 if (retry >= 100) {
632 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
633 "InitMAC(): ePHY configure fail!!!\n");
634 return false;
635 }
636
637 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
638 rtl_write_word(rtlpriv, REG_CR + 1, 0x06);
639
640 if (!mac_func_enable) {
641 if (_rtl8723ae_llt_table_init(hw) == false)
642 return false;
643 }
644
645 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
646 rtl_write_byte(rtlpriv, REG_HISRE, 0xff);
647
648 rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff);
649
650 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0xf;
651 wordtmp |= 0xF771;
652 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
653
654 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
655 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
656 rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
657 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
658
659 rtl_write_byte(rtlpriv, 0x4d0, 0x0);
660
661 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
662 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
663 DMA_BIT_MASK(32));
664 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
665 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
666 DMA_BIT_MASK(32));
667 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
668 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
669 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
670 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
671 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
672 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
673 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
674 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
675 rtl_write_dword(rtlpriv, REG_HQ_DESA,
676 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
677 DMA_BIT_MASK(32));
678 rtl_write_dword(rtlpriv, REG_RX_DESA,
679 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
680 DMA_BIT_MASK(32));
681
682 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x74);
683
684 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
685
686 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
687 rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6));
688 do {
689 retry++;
690 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
691 } while ((retry < 200) && (bytetmp & BIT(7)));
692
693 _rtl8723ae_gen_refresh_led_state(hw);
694
695 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
696
697 return true;
698}
699
700static void _rtl8723ae_hw_configure(struct ieee80211_hw *hw)
701{
702 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
703 struct rtl_priv *rtlpriv = rtl_priv(hw);
704 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
705 u8 reg_bw_opmode;
706 u32 reg_ratr, reg_prsr;
707
708 reg_bw_opmode = BW_OPMODE_20MHZ;
709 reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG |
710 RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
711 reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
712
713 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8);
714
715 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
716
717 rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr);
718
719 rtl_write_byte(rtlpriv, REG_SLOT, 0x09);
720
721 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0);
722
723 rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80);
724
725 rtl_write_word(rtlpriv, REG_RL, 0x0707);
726
727 rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802);
728
729 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
730
731 rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
732 rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
733 rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
734 rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
735
736 if ((pcipriv->bt_coexist.bt_coexistence) &&
737 (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4))
738 rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x97427431);
739 else
740 rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841);
741
742 rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2);
743
744 rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff);
745
746 rtlpci->reg_bcn_ctrl_val = 0x1f;
747 rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
748
749 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
750
751 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
752
753 rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);
754 rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
755
756 if ((pcipriv->bt_coexist.bt_coexistence) &&
757 (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) {
758 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
759 rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0402);
760 } else {
761 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
762 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
763 }
764
765 if ((pcipriv->bt_coexist.bt_coexistence) &&
766 (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4))
767 rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
768 else
769 rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666);
770
771 rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
772
773 rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010);
774 rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010);
775
776 rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010);
777
778 rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010);
779
780 rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff);
781 rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff);
782
783 rtl_write_dword(rtlpriv, 0x394, 0x1);
784}
785
786static void _rtl8723ae_enable_aspm_back_door(struct ieee80211_hw *hw)
787{
788 struct rtl_priv *rtlpriv = rtl_priv(hw);
789 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
790
791 rtl_write_byte(rtlpriv, 0x34b, 0x93);
792 rtl_write_word(rtlpriv, 0x350, 0x870c);
793 rtl_write_byte(rtlpriv, 0x352, 0x1);
794
795 if (ppsc->support_backdoor)
796 rtl_write_byte(rtlpriv, 0x349, 0x1b);
797 else
798 rtl_write_byte(rtlpriv, 0x349, 0x03);
799
800 rtl_write_word(rtlpriv, 0x350, 0x2718);
801 rtl_write_byte(rtlpriv, 0x352, 0x1);
802}
803
804void rtl8723ae_enable_hw_security_config(struct ieee80211_hw *hw)
805{
806 struct rtl_priv *rtlpriv = rtl_priv(hw);
807 u8 sec_reg_value;
808
809 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
810 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
811 rtlpriv->sec.pairwise_enc_algorithm,
812 rtlpriv->sec.group_enc_algorithm);
813
814 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
815 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
816 "not open hw encryption\n");
817 return;
818 }
819
820 sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable;
821
822 if (rtlpriv->sec.use_defaultkey) {
823 sec_reg_value |= SCR_TxUseDK;
824 sec_reg_value |= SCR_RxUseDK;
825 }
826
827 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
828
829 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
830
831 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
832 "The SECR-value %x\n", sec_reg_value);
833
834 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
835
836}
837
838int rtl8723ae_hw_init(struct ieee80211_hw *hw)
839{
840 struct rtl_priv *rtlpriv = rtl_priv(hw);
841 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
842 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
843 struct rtl_phy *rtlphy = &(rtlpriv->phy);
844 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
845 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
846 bool rtstatus = true;
847 int err;
848 u8 tmp_u1b;
849
850 rtlpriv->rtlhal.being_init_adapter = true;
851 rtlpriv->intf_ops->disable_aspm(hw);
852 rtstatus = _rtl8712e_init_mac(hw);
853 if (rtstatus != true) {
854 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
855 err = 1;
856 return err;
857 }
858
859 err = rtl8723ae_download_fw(hw);
860 if (err) {
861 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
862 "Failed to download FW. Init HW without FW now..\n");
863 err = 1;
864 rtlhal->fw_ready = false;
865 return err;
866 } else {
867 rtlhal->fw_ready = true;
868 }
869
870 rtlhal->last_hmeboxnum = 0;
871 rtl8723ae_phy_mac_config(hw);
872 /* because the last function modifies RCR, we update
873 * rcr var here, or TP will be unstable as ther receive_config
874 * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx
875 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
876 */
877 rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
878 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
879 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
880
881 rtl8723ae_phy_bb_config(hw);
882 rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
883 rtl8723ae_phy_rf_config(hw);
884 if (IS_VENDOR_UMC_A_CUT(rtlhal->version)) {
885 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255);
886 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00);
887 } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
888 rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE);
889 rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31);
890 rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425);
891 rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200);
892 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053);
893 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201);
894 }
895 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
896 RF_CHNLBW, RFREG_OFFSET_MASK);
897 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
898 RF_CHNLBW, RFREG_OFFSET_MASK);
899 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
900 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
901 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
902 _rtl8723ae_hw_configure(hw);
903 rtl_cam_reset_all_entry(hw);
904 rtl8723ae_enable_hw_security_config(hw);
905
906 ppsc->rfpwr_state = ERFON;
907
908 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
909 _rtl8723ae_enable_aspm_back_door(hw);
910 rtlpriv->intf_ops->enable_aspm(hw);
911
912 rtl8723ae_bt_hw_init(hw);
913
914 if (ppsc->rfpwr_state == ERFON) {
915 rtl8723ae_phy_set_rfpath_switch(hw, 1);
916 if (rtlphy->iqk_initialized) {
917 rtl8723ae_phy_iq_calibrate(hw, true);
918 } else {
919 rtl8723ae_phy_iq_calibrate(hw, false);
920 rtlphy->iqk_initialized = true;
921 }
922
923 rtl8723ae_phy_lc_calibrate(hw);
924 }
925
926 tmp_u1b = efuse_read_1byte(hw, 0x1FA);
927 if (!(tmp_u1b & BIT(0))) {
928 rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
929 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n");
930 }
931
932 if (!(tmp_u1b & BIT(4))) {
933 tmp_u1b = rtl_read_byte(rtlpriv, 0x16) & 0x0F;
934 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80);
935 udelay(10);
936 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90);
937 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");
938 }
939 rtl8723ae_dm_init(hw);
940 rtlpriv->rtlhal.being_init_adapter = false;
941 return err;
942}
943
944static enum version_8723e _rtl8723ae_read_chip_version(struct ieee80211_hw *hw)
945{
946 struct rtl_priv *rtlpriv = rtl_priv(hw);
947 struct rtl_phy *rtlphy = &(rtlpriv->phy);
948 enum version_8723e version = 0x0000;
949 u32 value32;
950
951 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
952 if (value32 & TRP_VAUX_EN) {
953 version = (enum version_8723e)(version |
954 ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0));
955 /* RTL8723 with BT function. */
956 version = (enum version_8723e)(version |
957 ((value32 & BT_FUNC) ? CHIP_8723 : 0));
958
959 } else {
960 /* Normal mass production chip. */
961 version = (enum version_8723e) NORMAL_CHIP;
962 version = (enum version_8723e)(version |
963 ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0));
964 /* RTL8723 with BT function. */
965 version = (enum version_8723e)(version |
966 ((value32 & BT_FUNC) ? CHIP_8723 : 0));
967 if (IS_CHIP_VENDOR_UMC(version))
968 version = (enum version_8723e)(version |
969 ((value32 & CHIP_VER_RTL_MASK)));/* IC version (CUT) */
970 if (IS_8723_SERIES(version)) {
971 value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS);
972 /* ROM code version */
973 version = (enum version_8723e)(version |
974 ((value32 & RF_RL_ID)>>20));
975 }
976 }
977
978 if (IS_8723_SERIES(version)) {
979 value32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
980 rtlphy->polarity_ctl = ((value32 & WL_HWPDN_SL) ?
981 RT_POLARITY_HIGH_ACT :
982 RT_POLARITY_LOW_ACT);
983 }
984 switch (version) {
985 case VERSION_TEST_UMC_CHIP_8723:
986 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
987 "Chip Version ID: VERSION_TEST_UMC_CHIP_8723.\n");
988 break;
989 case VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT:
990 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
991 "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT.\n");
992 break;
993 case VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT:
994 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
995 "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT.\n");
996 break;
997 default:
998 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
999 "Chip Version ID: Unknown. Bug?\n");
1000 break;
1001 }
1002
1003 if (IS_8723_SERIES(version))
1004 rtlphy->rf_type = RF_1T1R;
1005
1006 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n",
1007 (rtlphy->rf_type == RF_2T2R) ? "RF_2T2R" : "RF_1T1R");
1008
1009 return version;
1010}
1011
1012static int _rtl8723ae_set_media_status(struct ieee80211_hw *hw,
1013 enum nl80211_iftype type)
1014{
1015 struct rtl_priv *rtlpriv = rtl_priv(hw);
1016 u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1017 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1018
1019 rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0);
1020 RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD,
1021 "clear 0x550 when set HW_VAR_MEDIA_STATUS\n");
1022
1023 if (type == NL80211_IFTYPE_UNSPECIFIED ||
1024 type == NL80211_IFTYPE_STATION) {
1025 _rtl8723ae_stop_tx_beacon(hw);
1026 _rtl8723ae_enable_bcn_sufunc(hw);
1027 } else if (type == NL80211_IFTYPE_ADHOC ||
1028 type == NL80211_IFTYPE_AP) {
1029 _rtl8723ae_resume_tx_beacon(hw);
1030 _rtl8723ae_disable_bcn_sufunc(hw);
1031 } else {
1032 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1033 "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
1034 type);
1035 }
1036
1037 switch (type) {
1038 case NL80211_IFTYPE_UNSPECIFIED:
1039 bt_msr |= MSR_NOLINK;
1040 ledaction = LED_CTL_LINK;
1041 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1042 "Set Network type to NO LINK!\n");
1043 break;
1044 case NL80211_IFTYPE_ADHOC:
1045 bt_msr |= MSR_ADHOC;
1046 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1047 "Set Network type to Ad Hoc!\n");
1048 break;
1049 case NL80211_IFTYPE_STATION:
1050 bt_msr |= MSR_INFRA;
1051 ledaction = LED_CTL_LINK;
1052 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1053 "Set Network type to STA!\n");
1054 break;
1055 case NL80211_IFTYPE_AP:
1056 bt_msr |= MSR_AP;
1057 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1058 "Set Network type to AP!\n");
1059 break;
1060 default:
1061 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1062 "Network type %d not supported!\n",
1063 type);
1064 return 1;
1065 break;
1066
1067 }
1068
1069 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1070 rtlpriv->cfg->ops->led_control(hw, ledaction);
1071 if ((bt_msr & 0x03) == MSR_AP)
1072 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1073 else
1074 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1075 return 0;
1076}
1077
1078void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1079{
1080 struct rtl_priv *rtlpriv = rtl_priv(hw);
1081 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1082 u32 reg_rcr = rtlpci->receive_config;
1083
1084 if (rtlpriv->psc.rfpwr_state != ERFON)
1085 return;
1086
1087 if (check_bssid == true) {
1088 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1089 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1090 (u8 *)(&reg_rcr));
1091 _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(4));
1092 } else if (check_bssid == false) {
1093 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1094 _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(4), 0);
1095 rtlpriv->cfg->ops->set_hw_reg(hw,
1096 HW_VAR_RCR, (u8 *) (&reg_rcr));
1097 }
1098}
1099
1100int rtl8723ae_set_network_type(struct ieee80211_hw *hw,
1101 enum nl80211_iftype type)
1102{
1103 struct rtl_priv *rtlpriv = rtl_priv(hw);
1104
1105 if (_rtl8723ae_set_media_status(hw, type))
1106 return -EOPNOTSUPP;
1107
1108 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1109 if (type != NL80211_IFTYPE_AP)
1110 rtl8723ae_set_check_bssid(hw, true);
1111 } else {
1112 rtl8723ae_set_check_bssid(hw, false);
1113 }
1114 return 0;
1115}
1116
1117/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */
1118void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci)
1119{
1120 struct rtl_priv *rtlpriv = rtl_priv(hw);
1121
1122 rtl8723ae_dm_init_edca_turbo(hw);
1123 switch (aci) {
1124 case AC1_BK:
1125 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1126 break;
1127 case AC0_BE:
1128 /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4ac_param); */
1129 break;
1130 case AC2_VI:
1131 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1132 break;
1133 case AC3_VO:
1134 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1135 break;
1136 default:
1137 RT_ASSERT(false, "invalid aci: %d !\n", aci);
1138 break;
1139 }
1140}
1141
1142void rtl8723ae_enable_interrupt(struct ieee80211_hw *hw)
1143{
1144 struct rtl_priv *rtlpriv = rtl_priv(hw);
1145 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1146
1147 rtl_write_dword(rtlpriv, 0x3a8, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1148 rtl_write_dword(rtlpriv, 0x3ac, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1149 rtlpci->irq_enabled = true;
1150}
1151
1152void rtl8723ae_disable_interrupt(struct ieee80211_hw *hw)
1153{
1154 struct rtl_priv *rtlpriv = rtl_priv(hw);
1155 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1156
1157 rtl_write_dword(rtlpriv, 0x3a8, IMR8190_DISABLED);
1158 rtl_write_dword(rtlpriv, 0x3ac, IMR8190_DISABLED);
1159 rtlpci->irq_enabled = false;
1160 synchronize_irq(rtlpci->pdev->irq);
1161}
1162
1163static void _rtl8723ae_poweroff_adapter(struct ieee80211_hw *hw)
1164{
1165 struct rtl_priv *rtlpriv = rtl_priv(hw);
1166 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1167 u8 u1tmp;
1168
1169 /* Combo (PCIe + USB) Card and PCIe-MF Card */
1170 /* 1. Run LPS WL RFOFF flow */
1171 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1172 PWR_INTF_PCI_MSK, Rtl8723_NIC_LPS_ENTER_FLOW);
1173
1174 /* 2. 0x1F[7:0] = 0 */
1175 /* turn off RF */
1176 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
1177 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready)
1178 rtl8723ae_firmware_selfreset(hw);
1179
1180 /* Reset MCU. Suggested by Filen. */
1181 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
1182 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1tmp & (~BIT(2))));
1183
1184 /* g. MCUFWDL 0x80[1:0]=0 */
1185 /* reset MCU ready status */
1186 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1187
1188 /* HW card disable configuration. */
1189 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1190 PWR_INTF_PCI_MSK, Rtl8723_NIC_DISABLE_FLOW);
1191
1192 /* Reset MCU IO Wrapper */
1193 u1tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1194 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1tmp & (~BIT(0))));
1195 u1tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1196 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1tmp | BIT(0));
1197
1198 /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1199 /* lock ISO/CLK/Power control register */
1200 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1201}
1202
1203void rtl8723ae_card_disable(struct ieee80211_hw *hw)
1204{
1205 struct rtl_priv *rtlpriv = rtl_priv(hw);
1206 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1207 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1208 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1209 enum nl80211_iftype opmode;
1210
1211 mac->link_state = MAC80211_NOLINK;
1212 opmode = NL80211_IFTYPE_UNSPECIFIED;
1213 _rtl8723ae_set_media_status(hw, opmode);
1214 if (rtlpci->driver_is_goingto_unload ||
1215 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1216 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1217 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1218 _rtl8723ae_poweroff_adapter(hw);
1219
1220 /* after power off we should do iqk again */
1221 rtlpriv->phy.iqk_initialized = false;
1222}
1223
1224void rtl8723ae_interrupt_recognized(struct ieee80211_hw *hw,
1225 u32 *p_inta, u32 *p_intb)
1226{
1227 struct rtl_priv *rtlpriv = rtl_priv(hw);
1228 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1229
1230 *p_inta = rtl_read_dword(rtlpriv, 0x3a0) & rtlpci->irq_mask[0];
1231 rtl_write_dword(rtlpriv, 0x3a0, *p_inta);
1232}
1233
1234void rtl8723ae_set_beacon_related_registers(struct ieee80211_hw *hw)
1235{
1236
1237 struct rtl_priv *rtlpriv = rtl_priv(hw);
1238 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1239 u16 bcn_interval, atim_window;
1240
1241 bcn_interval = mac->beacon_interval;
1242 atim_window = 2; /*FIX MERGE */
1243 rtl8723ae_disable_interrupt(hw);
1244 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1245 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1246 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1247 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1248 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1249 rtl_write_byte(rtlpriv, 0x606, 0x30);
1250 rtl8723ae_enable_interrupt(hw);
1251}
1252
1253void rtl8723ae_set_beacon_interval(struct ieee80211_hw *hw)
1254{
1255 struct rtl_priv *rtlpriv = rtl_priv(hw);
1256 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1257 u16 bcn_interval = mac->beacon_interval;
1258
1259 RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1260 "beacon_interval:%d\n", bcn_interval);
1261 rtl8723ae_disable_interrupt(hw);
1262 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1263 rtl8723ae_enable_interrupt(hw);
1264}
1265
1266void rtl8723ae_update_interrupt_mask(struct ieee80211_hw *hw,
1267 u32 add_msr, u32 rm_msr)
1268{
1269 struct rtl_priv *rtlpriv = rtl_priv(hw);
1270 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1271
1272 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1273 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1274
1275 if (add_msr)
1276 rtlpci->irq_mask[0] |= add_msr;
1277 if (rm_msr)
1278 rtlpci->irq_mask[0] &= (~rm_msr);
1279 rtl8723ae_disable_interrupt(hw);
1280 rtl8723ae_enable_interrupt(hw);
1281}
1282
1283static u8 _rtl8723ae_get_chnl_group(u8 chnl)
1284{
1285 u8 group;
1286
1287 if (chnl < 3)
1288 group = 0;
1289 else if (chnl < 9)
1290 group = 1;
1291 else
1292 group = 2;
1293 return group;
1294}
1295
1296static void _rtl8723ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1297 bool autoload_fail,
1298 u8 *hwinfo)
1299{
1300 struct rtl_priv *rtlpriv = rtl_priv(hw);
1301 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1302 u8 rf_path, index, tempval;
1303 u16 i;
1304
1305 for (rf_path = 0; rf_path < 1; rf_path++) {
1306 for (i = 0; i < 3; i++) {
1307 if (!autoload_fail) {
1308 rtlefuse->eeprom_chnlarea_txpwr_cck
1309 [rf_path][i] =
1310 hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i];
1311 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1312 [rf_path][i] =
1313 hwinfo[EEPROM_TXPOWERHT40_1S + rf_path *
1314 3 + i];
1315 } else {
1316 rtlefuse->eeprom_chnlarea_txpwr_cck
1317 [rf_path][i] =
1318 EEPROM_DEFAULT_TXPOWERLEVEL;
1319 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1320 [rf_path][i] =
1321 EEPROM_DEFAULT_TXPOWERLEVEL;
1322 }
1323 }
1324 }
1325
1326 for (i = 0; i < 3; i++) {
1327 if (!autoload_fail)
1328 tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i];
1329 else
1330 tempval = EEPROM_DEFAULT_HT40_2SDIFF;
1331 rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] =
1332 (tempval & 0xf);
1333 rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] =
1334 ((tempval & 0xf0) >> 4);
1335 }
1336
1337 for (rf_path = 0; rf_path < 2; rf_path++)
1338 for (i = 0; i < 3; i++)
1339 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1340 "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
1341 i, rtlefuse->eeprom_chnlarea_txpwr_cck
1342 [rf_path][i]);
1343 for (rf_path = 0; rf_path < 2; rf_path++)
1344 for (i = 0; i < 3; i++)
1345 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1346 "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
1347 rf_path, i,
1348 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1349 [rf_path][i]);
1350 for (rf_path = 0; rf_path < 2; rf_path++)
1351 for (i = 0; i < 3; i++)
1352 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1353 "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
1354 rf_path, i,
1355 rtlefuse->eprom_chnl_txpwr_ht40_2sdf
1356 [rf_path][i]);
1357
1358 for (rf_path = 0; rf_path < 2; rf_path++) {
1359 for (i = 0; i < 14; i++) {
1360 index = _rtl8723ae_get_chnl_group((u8) i);
1361
1362 rtlefuse->txpwrlevel_cck[rf_path][i] =
1363 rtlefuse->eeprom_chnlarea_txpwr_cck
1364 [rf_path][index];
1365 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1366 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1367 [rf_path][index];
1368
1369 if ((rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1370 [rf_path][index] -
1371 rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path]
1372 [index]) > 0) {
1373 rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
1374 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1375 [rf_path][index] -
1376 rtlefuse->eprom_chnl_txpwr_ht40_2sdf
1377 [rf_path][index];
1378 } else {
1379 rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0;
1380 }
1381 }
1382
1383 for (i = 0; i < 14; i++) {
1384 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1385 "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
1386 "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
1387 rtlefuse->txpwrlevel_cck[rf_path][i],
1388 rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
1389 rtlefuse->txpwrlevel_ht40_2s[rf_path][i]);
1390 }
1391 }
1392
1393 for (i = 0; i < 3; i++) {
1394 if (!autoload_fail) {
1395 rtlefuse->eeprom_pwrlimit_ht40[i] =
1396 hwinfo[EEPROM_TXPWR_GROUP + i];
1397 rtlefuse->eeprom_pwrlimit_ht20[i] =
1398 hwinfo[EEPROM_TXPWR_GROUP + 3 + i];
1399 } else {
1400 rtlefuse->eeprom_pwrlimit_ht40[i] = 0;
1401 rtlefuse->eeprom_pwrlimit_ht20[i] = 0;
1402 }
1403 }
1404
1405 for (rf_path = 0; rf_path < 2; rf_path++) {
1406 for (i = 0; i < 14; i++) {
1407 index = _rtl8723ae_get_chnl_group((u8) i);
1408
1409 if (rf_path == RF90_PATH_A) {
1410 rtlefuse->pwrgroup_ht20[rf_path][i] =
1411 (rtlefuse->eeprom_pwrlimit_ht20[index] &
1412 0xf);
1413 rtlefuse->pwrgroup_ht40[rf_path][i] =
1414 (rtlefuse->eeprom_pwrlimit_ht40[index] &
1415 0xf);
1416 } else if (rf_path == RF90_PATH_B) {
1417 rtlefuse->pwrgroup_ht20[rf_path][i] =
1418 ((rtlefuse->eeprom_pwrlimit_ht20[index] &
1419 0xf0) >> 4);
1420 rtlefuse->pwrgroup_ht40[rf_path][i] =
1421 ((rtlefuse->eeprom_pwrlimit_ht40[index] &
1422 0xf0) >> 4);
1423 }
1424
1425 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1426 "RF-%d pwrgroup_ht20[%d] = 0x%x\n", rf_path, i,
1427 rtlefuse->pwrgroup_ht20[rf_path][i]);
1428 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1429 "RF-%d pwrgroup_ht40[%d] = 0x%x\n", rf_path, i,
1430 rtlefuse->pwrgroup_ht40[rf_path][i]);
1431 }
1432 }
1433
1434 for (i = 0; i < 14; i++) {
1435 index = _rtl8723ae_get_chnl_group((u8) i);
1436
1437 if (!autoload_fail)
1438 tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index];
1439 else
1440 tempval = EEPROM_DEFAULT_HT20_DIFF;
1441
1442 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF);
1443 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] =
1444 ((tempval >> 4) & 0xF);
1445
1446 if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3))
1447 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0;
1448
1449 if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3))
1450 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0;
1451
1452 index = _rtl8723ae_get_chnl_group((u8) i);
1453
1454 if (!autoload_fail)
1455 tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index];
1456 else
1457 tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF;
1458
1459 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF);
1460 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] =
1461 ((tempval >> 4) & 0xF);
1462 }
1463
1464 rtlefuse->legacy_ht_txpowerdiff =
1465 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7];
1466
1467 for (i = 0; i < 14; i++)
1468 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1469 "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
1470 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
1471 for (i = 0; i < 14; i++)
1472 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1473 "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
1474 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
1475 for (i = 0; i < 14; i++)
1476 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1477 "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
1478 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
1479 for (i = 0; i < 14; i++)
1480 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1481 "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
1482 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
1483
1484 if (!autoload_fail)
1485 rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
1486 else
1487 rtlefuse->eeprom_regulatory = 0;
1488 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1489 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
1490
1491 if (!autoload_fail)
1492 rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A];
1493 else
1494 rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI;
1495 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1496 "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
1497 rtlefuse->eeprom_tssi[RF90_PATH_A],
1498 rtlefuse->eeprom_tssi[RF90_PATH_B]);
1499
1500 if (!autoload_fail)
1501 tempval = hwinfo[EEPROM_THERMAL_METER];
1502 else
1503 tempval = EEPROM_DEFAULT_THERMALMETER;
1504 rtlefuse->eeprom_thermalmeter = (tempval & 0x1f);
1505
1506 if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail)
1507 rtlefuse->apk_thermalmeterignore = true;
1508
1509 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
1510 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1511 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
1512}
1513
1514static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,
1515 bool pseudo_test)
1516{
1517 struct rtl_priv *rtlpriv = rtl_priv(hw);
1518 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1519 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1520 u16 i, usvalue;
1521 u8 hwinfo[HWSET_MAX_SIZE];
1522 u16 eeprom_id;
1523
1524 if (pseudo_test) {
1525 /* need add */
1526 return;
1527 }
1528 if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
1529 rtl_efuse_shadow_map_update(hw);
1530
1531 memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
1532 HWSET_MAX_SIZE);
1533 } else if (rtlefuse->epromtype == EEPROM_93C46) {
1534 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1535 "RTL819X Not boot from eeprom, check it !!");
1536 }
1537
1538 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
1539 hwinfo, HWSET_MAX_SIZE);
1540
1541 eeprom_id = *((u16 *)&hwinfo[0]);
1542 if (eeprom_id != RTL8190_EEPROM_ID) {
1543 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1544 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
1545 rtlefuse->autoload_failflag = true;
1546 } else {
1547 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1548 rtlefuse->autoload_failflag = false;
1549 }
1550
1551 if (rtlefuse->autoload_failflag == true)
1552 return;
1553
1554 rtlefuse->eeprom_vid = *(u16 *) &hwinfo[EEPROM_VID];
1555 rtlefuse->eeprom_did = *(u16 *) &hwinfo[EEPROM_DID];
1556 rtlefuse->eeprom_svid = *(u16 *) &hwinfo[EEPROM_SVID];
1557 rtlefuse->eeprom_smid = *(u16 *) &hwinfo[EEPROM_SMID];
1558 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1559 "EEPROMId = 0x%4x\n", eeprom_id);
1560 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1561 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
1562 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1563 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
1564 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1565 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
1566 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1567 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
1568
1569 for (i = 0; i < 6; i += 2) {
1570 usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
1571 *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
1572 }
1573
1574 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1575 "dev_addr: %pM\n", rtlefuse->dev_addr);
1576
1577 _rtl8723ae_read_txpower_info_from_hwpg(hw,
1578 rtlefuse->autoload_failflag, hwinfo);
1579
1580 rtl8723ae_read_bt_coexist_info_from_hwpg(hw,
1581 rtlefuse->autoload_failflag, hwinfo);
1582
1583 rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
1584 rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
1585 rtlefuse->txpwr_fromeprom = true;
1586 rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
1587
1588 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1589 "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
1590
1591 /* set channel paln to world wide 13 */
1592 rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
1593
1594 if (rtlhal->oem_id == RT_CID_DEFAULT) {
1595 switch (rtlefuse->eeprom_oemid) {
1596 case EEPROM_CID_DEFAULT:
1597 if (rtlefuse->eeprom_did == 0x8176) {
1598 if (CHK_SVID_SMID(0x10EC, 0x6151) ||
1599 CHK_SVID_SMID(0x10EC, 0x6152) ||
1600 CHK_SVID_SMID(0x10EC, 0x6154) ||
1601 CHK_SVID_SMID(0x10EC, 0x6155) ||
1602 CHK_SVID_SMID(0x10EC, 0x6177) ||
1603 CHK_SVID_SMID(0x10EC, 0x6178) ||
1604 CHK_SVID_SMID(0x10EC, 0x6179) ||
1605 CHK_SVID_SMID(0x10EC, 0x6180) ||
1606 CHK_SVID_SMID(0x10EC, 0x8151) ||
1607 CHK_SVID_SMID(0x10EC, 0x8152) ||
1608 CHK_SVID_SMID(0x10EC, 0x8154) ||
1609 CHK_SVID_SMID(0x10EC, 0x8155) ||
1610 CHK_SVID_SMID(0x10EC, 0x8181) ||
1611 CHK_SVID_SMID(0x10EC, 0x8182) ||
1612 CHK_SVID_SMID(0x10EC, 0x8184) ||
1613 CHK_SVID_SMID(0x10EC, 0x8185) ||
1614 CHK_SVID_SMID(0x10EC, 0x9151) ||
1615 CHK_SVID_SMID(0x10EC, 0x9152) ||
1616 CHK_SVID_SMID(0x10EC, 0x9154) ||
1617 CHK_SVID_SMID(0x10EC, 0x9155) ||
1618 CHK_SVID_SMID(0x10EC, 0x9181) ||
1619 CHK_SVID_SMID(0x10EC, 0x9182) ||
1620 CHK_SVID_SMID(0x10EC, 0x9184) ||
1621 CHK_SVID_SMID(0x10EC, 0x9185))
1622 rtlhal->oem_id = RT_CID_TOSHIBA;
1623 else if (rtlefuse->eeprom_svid == 0x1025)
1624 rtlhal->oem_id = RT_CID_819x_Acer;
1625 else if (CHK_SVID_SMID(0x10EC, 0x6191) ||
1626 CHK_SVID_SMID(0x10EC, 0x6192) ||
1627 CHK_SVID_SMID(0x10EC, 0x6193) ||
1628 CHK_SVID_SMID(0x10EC, 0x7191) ||
1629 CHK_SVID_SMID(0x10EC, 0x7192) ||
1630 CHK_SVID_SMID(0x10EC, 0x7193) ||
1631 CHK_SVID_SMID(0x10EC, 0x8191) ||
1632 CHK_SVID_SMID(0x10EC, 0x8192) ||
1633 CHK_SVID_SMID(0x10EC, 0x8193))
1634 rtlhal->oem_id = RT_CID_819x_SAMSUNG;
1635 else if (CHK_SVID_SMID(0x10EC, 0x8195) ||
1636 CHK_SVID_SMID(0x10EC, 0x9195) ||
1637 CHK_SVID_SMID(0x10EC, 0x7194) ||
1638 CHK_SVID_SMID(0x10EC, 0x8200) ||
1639 CHK_SVID_SMID(0x10EC, 0x8201) ||
1640 CHK_SVID_SMID(0x10EC, 0x8202) ||
1641 CHK_SVID_SMID(0x10EC, 0x9200))
1642 rtlhal->oem_id = RT_CID_819x_Lenovo;
1643 else if (CHK_SVID_SMID(0x10EC, 0x8197) ||
1644 CHK_SVID_SMID(0x10EC, 0x9196))
1645 rtlhal->oem_id = RT_CID_819x_CLEVO;
1646 else if (CHK_SVID_SMID(0x1028, 0x8194) ||
1647 CHK_SVID_SMID(0x1028, 0x8198) ||
1648 CHK_SVID_SMID(0x1028, 0x9197) ||
1649 CHK_SVID_SMID(0x1028, 0x9198))
1650 rtlhal->oem_id = RT_CID_819x_DELL;
1651 else if (CHK_SVID_SMID(0x103C, 0x1629))
1652 rtlhal->oem_id = RT_CID_819x_HP;
1653 else if (CHK_SVID_SMID(0x1A32, 0x2315))
1654 rtlhal->oem_id = RT_CID_819x_QMI;
1655 else if (CHK_SVID_SMID(0x10EC, 0x8203))
1656 rtlhal->oem_id = RT_CID_819x_PRONETS;
1657 else if (CHK_SVID_SMID(0x1043, 0x84B5))
1658 rtlhal->oem_id =
1659 RT_CID_819x_Edimax_ASUS;
1660 else
1661 rtlhal->oem_id = RT_CID_DEFAULT;
1662 } else if (rtlefuse->eeprom_did == 0x8178) {
1663 if (CHK_SVID_SMID(0x10EC, 0x6181) ||
1664 CHK_SVID_SMID(0x10EC, 0x6182) ||
1665 CHK_SVID_SMID(0x10EC, 0x6184) ||
1666 CHK_SVID_SMID(0x10EC, 0x6185) ||
1667 CHK_SVID_SMID(0x10EC, 0x7181) ||
1668 CHK_SVID_SMID(0x10EC, 0x7182) ||
1669 CHK_SVID_SMID(0x10EC, 0x7184) ||
1670 CHK_SVID_SMID(0x10EC, 0x7185) ||
1671 CHK_SVID_SMID(0x10EC, 0x8181) ||
1672 CHK_SVID_SMID(0x10EC, 0x8182) ||
1673 CHK_SVID_SMID(0x10EC, 0x8184) ||
1674 CHK_SVID_SMID(0x10EC, 0x8185) ||
1675 CHK_SVID_SMID(0x10EC, 0x9181) ||
1676 CHK_SVID_SMID(0x10EC, 0x9182) ||
1677 CHK_SVID_SMID(0x10EC, 0x9184) ||
1678 CHK_SVID_SMID(0x10EC, 0x9185))
1679 rtlhal->oem_id = RT_CID_TOSHIBA;
1680 else if (rtlefuse->eeprom_svid == 0x1025)
1681 rtlhal->oem_id = RT_CID_819x_Acer;
1682 else if (CHK_SVID_SMID(0x10EC, 0x8186))
1683 rtlhal->oem_id = RT_CID_819x_PRONETS;
1684 else if (CHK_SVID_SMID(0x1043, 0x8486))
1685 rtlhal->oem_id =
1686 RT_CID_819x_Edimax_ASUS;
1687 else
1688 rtlhal->oem_id = RT_CID_DEFAULT;
1689 } else {
1690 rtlhal->oem_id = RT_CID_DEFAULT;
1691 }
1692 break;
1693 case EEPROM_CID_TOSHIBA:
1694 rtlhal->oem_id = RT_CID_TOSHIBA;
1695 break;
1696 case EEPROM_CID_CCX:
1697 rtlhal->oem_id = RT_CID_CCX;
1698 break;
1699 case EEPROM_CID_QMI:
1700 rtlhal->oem_id = RT_CID_819x_QMI;
1701 break;
1702 case EEPROM_CID_WHQL:
1703 break;
1704 default:
1705 rtlhal->oem_id = RT_CID_DEFAULT;
1706 break;
1707
1708 }
1709 }
1710}
1711
1712static void _rtl8723ae_hal_customized_behavior(struct ieee80211_hw *hw)
1713{
1714 struct rtl_priv *rtlpriv = rtl_priv(hw);
1715 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1716 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1717
1718 switch (rtlhal->oem_id) {
1719 case RT_CID_819x_HP:
1720 pcipriv->ledctl.led_opendrain = true;
1721 break;
1722 case RT_CID_819x_Lenovo:
1723 case RT_CID_DEFAULT:
1724 case RT_CID_TOSHIBA:
1725 case RT_CID_CCX:
1726 case RT_CID_819x_Acer:
1727 case RT_CID_WHQL:
1728 default:
1729 break;
1730 }
1731 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1732 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
1733}
1734
1735void rtl8723ae_read_eeprom_info(struct ieee80211_hw *hw)
1736{
1737 struct rtl_priv *rtlpriv = rtl_priv(hw);
1738 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1739 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1740 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1741 u8 tmp_u1b;
1742 u32 value32;
1743
1744 value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST]);
1745 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1746 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST], value32);
1747
1748 rtlhal->version = _rtl8723ae_read_chip_version(hw);
1749
1750 if (get_rf_type(rtlphy) == RF_1T1R)
1751 rtlpriv->dm.rfpath_rxenable[0] = true;
1752 else
1753 rtlpriv->dm.rfpath_rxenable[0] =
1754 rtlpriv->dm.rfpath_rxenable[1] = true;
1755 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
1756 rtlhal->version);
1757
1758 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
1759 if (tmp_u1b & BIT(4)) {
1760 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
1761 rtlefuse->epromtype = EEPROM_93C46;
1762 } else {
1763 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
1764 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
1765 }
1766 if (tmp_u1b & BIT(5)) {
1767 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1768 rtlefuse->autoload_failflag = false;
1769 _rtl8723ae_read_adapter_info(hw, false);
1770 } else {
1771 rtlefuse->autoload_failflag = true;
1772 _rtl8723ae_read_adapter_info(hw, false);
1773 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
1774 }
1775 _rtl8723ae_hal_customized_behavior(hw);
1776}
1777
1778static void rtl8723ae_update_hal_rate_table(struct ieee80211_hw *hw,
1779 struct ieee80211_sta *sta)
1780{
1781 struct rtl_priv *rtlpriv = rtl_priv(hw);
1782 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1783 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1784 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1785 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1786 u32 ratr_value;
1787 u8 ratr_index = 0;
1788 u8 nmode = mac->ht_enable;
1789 u8 mimo_ps = IEEE80211_SMPS_OFF;
1790 u8 curtxbw_40mhz = mac->bw_40;
1791 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
1792 1 : 0;
1793 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1794 1 : 0;
1795 enum wireless_mode wirelessmode = mac->mode;
1796
1797 if (rtlhal->current_bandtype == BAND_ON_5G)
1798 ratr_value = sta->supp_rates[1] << 4;
1799 else
1800 ratr_value = sta->supp_rates[0];
1801 if (mac->opmode == NL80211_IFTYPE_ADHOC)
1802 ratr_value = 0xfff;
1803 ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
1804 sta->ht_cap.mcs.rx_mask[0] << 12);
1805 switch (wirelessmode) {
1806 case WIRELESS_MODE_B:
1807 if (ratr_value & 0x0000000c)
1808 ratr_value &= 0x0000000d;
1809 else
1810 ratr_value &= 0x0000000f;
1811 break;
1812 case WIRELESS_MODE_G:
1813 ratr_value &= 0x00000FF5;
1814 break;
1815 case WIRELESS_MODE_N_24G:
1816 case WIRELESS_MODE_N_5G:
1817 nmode = 1;
1818 if (mimo_ps == IEEE80211_SMPS_STATIC) {
1819 ratr_value &= 0x0007F005;
1820 } else {
1821 u32 ratr_mask;
1822
1823 if (get_rf_type(rtlphy) == RF_1T2R ||
1824 get_rf_type(rtlphy) == RF_1T1R)
1825 ratr_mask = 0x000ff005;
1826 else
1827 ratr_mask = 0x0f0ff005;
1828
1829 ratr_value &= ratr_mask;
1830 }
1831 break;
1832 default:
1833 if (rtlphy->rf_type == RF_1T2R)
1834 ratr_value &= 0x000ff0ff;
1835 else
1836 ratr_value &= 0x0f0ff0ff;
1837
1838 break;
1839 }
1840
1841 if ((pcipriv->bt_coexist.bt_coexistence) &&
1842 (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) &&
1843 (pcipriv->bt_coexist.bt_cur_state) &&
1844 (pcipriv->bt_coexist.bt_ant_isolation) &&
1845 ((pcipriv->bt_coexist.bt_service == BT_SCO) ||
1846 (pcipriv->bt_coexist.bt_service == BT_BUSY)))
1847 ratr_value &= 0x0fffcfc0;
1848 else
1849 ratr_value &= 0x0FFFFFFF;
1850
1851 if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||
1852 (!curtxbw_40mhz && curshortgi_20mhz)))
1853 ratr_value |= 0x10000000;
1854
1855 rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
1856
1857 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
1858 "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0));
1859}
1860
1861static void rtl8723ae_update_hal_rate_mask(struct ieee80211_hw *hw,
1862 struct ieee80211_sta *sta, u8 rssi_level)
1863{
1864 struct rtl_priv *rtlpriv = rtl_priv(hw);
1865 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1866 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1867 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1868 struct rtl_sta_info *sta_entry = NULL;
1869 u32 ratr_bitmap;
1870 u8 ratr_index;
1871 u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
1872 ? 1 : 0;
1873 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
1874 1 : 0;
1875 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1876 1 : 0;
1877 enum wireless_mode wirelessmode = 0;
1878 bool shortgi = false;
1879 u8 rate_mask[5];
1880 u8 macid = 0;
1881 u8 mimo_ps = IEEE80211_SMPS_OFF;
1882
1883 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
1884 wirelessmode = sta_entry->wireless_mode;
1885 if (mac->opmode == NL80211_IFTYPE_STATION)
1886 curtxbw_40mhz = mac->bw_40;
1887 else if (mac->opmode == NL80211_IFTYPE_AP ||
1888 mac->opmode == NL80211_IFTYPE_ADHOC)
1889 macid = sta->aid + 1;
1890
1891 if (rtlhal->current_bandtype == BAND_ON_5G)
1892 ratr_bitmap = sta->supp_rates[1] << 4;
1893 else
1894 ratr_bitmap = sta->supp_rates[0];
1895 if (mac->opmode == NL80211_IFTYPE_ADHOC)
1896 ratr_bitmap = 0xfff;
1897 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
1898 sta->ht_cap.mcs.rx_mask[0] << 12);
1899 switch (wirelessmode) {
1900 case WIRELESS_MODE_B:
1901 ratr_index = RATR_INX_WIRELESS_B;
1902 if (ratr_bitmap & 0x0000000c)
1903 ratr_bitmap &= 0x0000000d;
1904 else
1905 ratr_bitmap &= 0x0000000f;
1906 break;
1907 case WIRELESS_MODE_G:
1908 ratr_index = RATR_INX_WIRELESS_GB;
1909
1910 if (rssi_level == 1)
1911 ratr_bitmap &= 0x00000f00;
1912 else if (rssi_level == 2)
1913 ratr_bitmap &= 0x00000ff0;
1914 else
1915 ratr_bitmap &= 0x00000ff5;
1916 break;
1917 case WIRELESS_MODE_A:
1918 ratr_index = RATR_INX_WIRELESS_A;
1919 ratr_bitmap &= 0x00000ff0;
1920 break;
1921 case WIRELESS_MODE_N_24G:
1922 case WIRELESS_MODE_N_5G:
1923 ratr_index = RATR_INX_WIRELESS_NGB;
1924
1925 if (mimo_ps == IEEE80211_SMPS_STATIC) {
1926 if (rssi_level == 1)
1927 ratr_bitmap &= 0x00070000;
1928 else if (rssi_level == 2)
1929 ratr_bitmap &= 0x0007f000;
1930 else
1931 ratr_bitmap &= 0x0007f005;
1932 } else {
1933 if (rtlphy->rf_type == RF_1T2R ||
1934 rtlphy->rf_type == RF_1T1R) {
1935 if (curtxbw_40mhz) {
1936 if (rssi_level == 1)
1937 ratr_bitmap &= 0x000f0000;
1938 else if (rssi_level == 2)
1939 ratr_bitmap &= 0x000ff000;
1940 else
1941 ratr_bitmap &= 0x000ff015;
1942 } else {
1943 if (rssi_level == 1)
1944 ratr_bitmap &= 0x000f0000;
1945 else if (rssi_level == 2)
1946 ratr_bitmap &= 0x000ff000;
1947 else
1948 ratr_bitmap &= 0x000ff005;
1949 }
1950 } else {
1951 if (curtxbw_40mhz) {
1952 if (rssi_level == 1)
1953 ratr_bitmap &= 0x0f0f0000;
1954 else if (rssi_level == 2)
1955 ratr_bitmap &= 0x0f0ff000;
1956 else
1957 ratr_bitmap &= 0x0f0ff015;
1958 } else {
1959 if (rssi_level == 1)
1960 ratr_bitmap &= 0x0f0f0000;
1961 else if (rssi_level == 2)
1962 ratr_bitmap &= 0x0f0ff000;
1963 else
1964 ratr_bitmap &= 0x0f0ff005;
1965 }
1966 }
1967 }
1968
1969 if ((curtxbw_40mhz && curshortgi_40mhz) ||
1970 (!curtxbw_40mhz && curshortgi_20mhz)) {
1971 if (macid == 0)
1972 shortgi = true;
1973 else if (macid == 1)
1974 shortgi = false;
1975 }
1976 break;
1977 default:
1978 ratr_index = RATR_INX_WIRELESS_NGB;
1979
1980 if (rtlphy->rf_type == RF_1T2R)
1981 ratr_bitmap &= 0x000ff0ff;
1982 else
1983 ratr_bitmap &= 0x0f0ff0ff;
1984 break;
1985 }
1986 sta_entry->ratr_index = ratr_index;
1987
1988 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
1989 "ratr_bitmap :%x\n", ratr_bitmap);
1990 /* convert ratr_bitmap to le byte array */
1991 rate_mask[0] = ratr_bitmap;
1992 rate_mask[1] = (ratr_bitmap >>= 8);
1993 rate_mask[2] = (ratr_bitmap >>= 8);
1994 rate_mask[3] = ((ratr_bitmap >> 8) & 0x0f) | (ratr_index << 4);
1995 rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
1996 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
1997 "Rate_index:%x, ratr_bitmap: %*phC\n",
1998 ratr_index, 5, rate_mask);
1999 rtl8723ae_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
2000}
2001
2002void rtl8723ae_update_hal_rate_tbl(struct ieee80211_hw *hw,
2003 struct ieee80211_sta *sta, u8 rssi_level)
2004{
2005 struct rtl_priv *rtlpriv = rtl_priv(hw);
2006
2007 if (rtlpriv->dm.useramask)
2008 rtl8723ae_update_hal_rate_mask(hw, sta, rssi_level);
2009 else
2010 rtl8723ae_update_hal_rate_table(hw, sta);
2011}
2012
2013void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw)
2014{
2015 struct rtl_priv *rtlpriv = rtl_priv(hw);
2016 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2017 u16 sifs_timer;
2018
2019 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
2020 (u8 *)&mac->slot_time);
2021 if (!mac->ht_enable)
2022 sifs_timer = 0x0a0a;
2023 else
2024 sifs_timer = 0x1010;
2025 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2026}
2027
2028bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2029{
2030 struct rtl_priv *rtlpriv = rtl_priv(hw);
2031 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2032 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2033 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2034 u8 u1tmp;
2035 bool actuallyset = false;
2036
2037 if (rtlpriv->rtlhal.being_init_adapter)
2038 return false;
2039
2040 if (ppsc->swrf_processing)
2041 return false;
2042
2043 spin_lock(&rtlpriv->locks.rf_ps_lock);
2044 if (ppsc->rfchange_inprogress) {
2045 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2046 return false;
2047 } else {
2048 ppsc->rfchange_inprogress = true;
2049 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2050 }
2051
2052 cur_rfstate = ppsc->rfpwr_state;
2053
2054 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2055 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2)&~(BIT(1)));
2056
2057 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2058
2059 if (rtlphy->polarity_ctl)
2060 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2061 else
2062 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2063
2064 if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) {
2065 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2066 "GPIOChangeRF - HW Radio ON, RF ON\n");
2067
2068 e_rfpowerstate_toset = ERFON;
2069 ppsc->hwradiooff = false;
2070 actuallyset = true;
2071 } else if ((ppsc->hwradiooff == false)
2072 && (e_rfpowerstate_toset == ERFOFF)) {
2073 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2074 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2075
2076 e_rfpowerstate_toset = ERFOFF;
2077 ppsc->hwradiooff = true;
2078 actuallyset = true;
2079 }
2080
2081 if (actuallyset) {
2082 spin_lock(&rtlpriv->locks.rf_ps_lock);
2083 ppsc->rfchange_inprogress = false;
2084 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2085 } else {
2086 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2087 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2088
2089 spin_lock(&rtlpriv->locks.rf_ps_lock);
2090 ppsc->rfchange_inprogress = false;
2091 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2092 }
2093
2094 *valid = 1;
2095 return !ppsc->hwradiooff;
2096}
2097
2098void rtl8723ae_set_key(struct ieee80211_hw *hw, u32 key_index,
2099 u8 *p_macaddr, bool is_group, u8 enc_algo,
2100 bool is_wepkey, bool clear_all)
2101{
2102 struct rtl_priv *rtlpriv = rtl_priv(hw);
2103 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2104 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2105 u8 *macaddr = p_macaddr;
2106 u32 entry_id = 0;
2107 bool is_pairwise = false;
2108 static u8 cam_const_addr[4][6] = {
2109 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2110 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2111 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2112 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2113 };
2114 static u8 cam_const_broad[] = {
2115 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2116 };
2117
2118 if (clear_all) {
2119 u8 idx = 0;
2120 u8 cam_offset = 0;
2121 u8 clear_number = 5;
2122
2123 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2124
2125 for (idx = 0; idx < clear_number; idx++) {
2126 rtl_cam_mark_invalid(hw, cam_offset + idx);
2127 rtl_cam_empty_entry(hw, cam_offset + idx);
2128
2129 if (idx < 5) {
2130 memset(rtlpriv->sec.key_buf[idx], 0,
2131 MAX_KEY_LEN);
2132 rtlpriv->sec.key_len[idx] = 0;
2133 }
2134 }
2135 } else {
2136 switch (enc_algo) {
2137 case WEP40_ENCRYPTION:
2138 enc_algo = CAM_WEP40;
2139 break;
2140 case WEP104_ENCRYPTION:
2141 enc_algo = CAM_WEP104;
2142 break;
2143 case TKIP_ENCRYPTION:
2144 enc_algo = CAM_TKIP;
2145 break;
2146 case AESCCMP_ENCRYPTION:
2147 enc_algo = CAM_AES;
2148 break;
2149 default:
2150 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2151 "switch case not processed\n");
2152 enc_algo = CAM_TKIP;
2153 break;
2154 }
2155
2156 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2157 macaddr = cam_const_addr[key_index];
2158 entry_id = key_index;
2159 } else {
2160 if (is_group) {
2161 macaddr = cam_const_broad;
2162 entry_id = key_index;
2163 } else {
2164 if (mac->opmode == NL80211_IFTYPE_AP) {
2165 entry_id = rtl_cam_get_free_entry(hw,
2166 macaddr);
2167 if (entry_id >= TOTAL_CAM_ENTRY) {
2168 RT_TRACE(rtlpriv, COMP_SEC,
2169 DBG_EMERG,
2170 "Can not find free hw security cam entry\n");
2171 return;
2172 }
2173 } else {
2174 entry_id = CAM_PAIRWISE_KEY_POSITION;
2175 }
2176
2177 key_index = PAIRWISE_KEYIDX;
2178 is_pairwise = true;
2179 }
2180 }
2181
2182 if (rtlpriv->sec.key_len[key_index] == 0) {
2183 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2184 "delete one entry, entry_id is %d\n",
2185 entry_id);
2186 if (mac->opmode == NL80211_IFTYPE_AP)
2187 rtl_cam_del_entry(hw, p_macaddr);
2188 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2189 } else {
2190 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2191 "add one entry\n");
2192 if (is_pairwise) {
2193 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2194 "set Pairwiase key\n");
2195
2196 rtl_cam_add_one_entry(hw, macaddr, key_index,
2197 entry_id, enc_algo,
2198 CAM_CONFIG_NO_USEDK,
2199 rtlpriv->sec.key_buf[key_index]);
2200 } else {
2201 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2202 "set group key\n");
2203
2204 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2205 rtl_cam_add_one_entry(hw,
2206 rtlefuse->dev_addr,
2207 PAIRWISE_KEYIDX,
2208 CAM_PAIRWISE_KEY_POSITION,
2209 enc_algo,
2210 CAM_CONFIG_NO_USEDK,
2211 rtlpriv->sec.key_buf
2212 [entry_id]);
2213 }
2214
2215 rtl_cam_add_one_entry(hw, macaddr, key_index,
2216 entry_id, enc_algo,
2217 CAM_CONFIG_NO_USEDK,
2218 rtlpriv->sec.key_buf[entry_id]);
2219 }
2220
2221 }
2222 }
2223}
2224
2225static void rtl8723ae_bt_var_init(struct ieee80211_hw *hw)
2226{
2227 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2228 struct rtl_priv *rtlpriv = rtl_priv(hw);
2229
2230 pcipriv->bt_coexist.bt_coexistence =
2231 pcipriv->bt_coexist.eeprom_bt_coexist;
2232 pcipriv->bt_coexist.bt_ant_num =
2233 pcipriv->bt_coexist.eeprom_bt_ant_num;
2234 pcipriv->bt_coexist.bt_coexist_type =
2235 pcipriv->bt_coexist.eeprom_bt_type;
2236
2237 pcipriv->bt_coexist.bt_ant_isolation =
2238 pcipriv->bt_coexist.eeprom_bt_ant_isol;
2239
2240 pcipriv->bt_coexist.bt_radio_shared_type =
2241 pcipriv->bt_coexist.eeprom_bt_radio_shared;
2242
2243 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2244 "BT Coexistance = 0x%x\n",
2245 pcipriv->bt_coexist.bt_coexistence);
2246
2247 if (pcipriv->bt_coexist.bt_coexistence) {
2248 pcipriv->bt_coexist.bt_busy_traffic = false;
2249 pcipriv->bt_coexist.bt_traffic_mode_set = false;
2250 pcipriv->bt_coexist.bt_non_traffic_mode_set = false;
2251
2252 pcipriv->bt_coexist.cstate = 0;
2253 pcipriv->bt_coexist.previous_state = 0;
2254
2255 if (pcipriv->bt_coexist.bt_ant_num == ANT_X2) {
2256 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2257 "BlueTooth BT_Ant_Num = Antx2\n");
2258 } else if (pcipriv->bt_coexist.bt_ant_num == ANT_X1) {
2259 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2260 "BlueTooth BT_Ant_Num = Antx1\n");
2261 }
2262
2263 switch (pcipriv->bt_coexist.bt_coexist_type) {
2264 case BT_2WIRE:
2265 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2266 "BlueTooth BT_CoexistType = BT_2Wire\n");
2267 break;
2268 case BT_ISSC_3WIRE:
2269 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2270 "BlueTooth BT_CoexistType = BT_ISSC_3Wire\n");
2271 break;
2272 case BT_ACCEL:
2273 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2274 "BlueTooth BT_CoexistType = BT_ACCEL\n");
2275 break;
2276 case BT_CSR_BC4:
2277 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2278 "BlueTooth BT_CoexistType = BT_CSR_BC4\n");
2279 break;
2280 case BT_CSR_BC8:
2281 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2282 "BlueTooth BT_CoexistType = BT_CSR_BC8\n");
2283 break;
2284 case BT_RTL8756:
2285 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2286 "BlueTooth BT_CoexistType = BT_RTL8756\n");
2287 break;
2288 default:
2289 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2290 "BlueTooth BT_CoexistType = Unknown\n");
2291 break;
2292 }
2293 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2294 "BlueTooth BT_Ant_isolation = %d\n",
2295 pcipriv->bt_coexist.bt_ant_isolation);
2296 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2297 "BT_RadioSharedType = 0x%x\n",
2298 pcipriv->bt_coexist.bt_radio_shared_type);
2299 pcipriv->bt_coexist.bt_active_zero_cnt = 0;
2300 pcipriv->bt_coexist.cur_bt_disabled = false;
2301 pcipriv->bt_coexist.pre_bt_disabled = false;
2302 }
2303}
2304
2305void rtl8723ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2306 bool auto_load_fail, u8 *hwinfo)
2307{
2308 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2309 struct rtl_priv *rtlpriv = rtl_priv(hw);
2310 u8 value;
2311 u32 tmpu_32;
2312
2313 if (!auto_load_fail) {
2314 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2315 if (tmpu_32 & BIT(18))
2316 pcipriv->bt_coexist.eeprom_bt_coexist = 1;
2317 else
2318 pcipriv->bt_coexist.eeprom_bt_coexist = 0;
2319 value = hwinfo[RF_OPTION4];
2320 pcipriv->bt_coexist.eeprom_bt_type = BT_RTL8723A;
2321 pcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1);
2322 pcipriv->bt_coexist.eeprom_bt_ant_isol = ((value & 0x10) >> 4);
2323 pcipriv->bt_coexist.eeprom_bt_radio_shared =
2324 ((value & 0x20) >> 5);
2325 } else {
2326 pcipriv->bt_coexist.eeprom_bt_coexist = 0;
2327 pcipriv->bt_coexist.eeprom_bt_type = BT_RTL8723A;
2328 pcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2;
2329 pcipriv->bt_coexist.eeprom_bt_ant_isol = 0;
2330 pcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED;
2331 }
2332
2333 rtl8723ae_bt_var_init(hw);
2334}
2335
2336void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw)
2337{
2338 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2339
2340 /* 0:Low, 1:High, 2:From Efuse. */
2341 pcipriv->bt_coexist.reg_bt_iso = 2;
2342 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2343 pcipriv->bt_coexist.reg_bt_sco = 3;
2344 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2345 pcipriv->bt_coexist.reg_bt_sco = 0;
2346}
2347
2348
2349void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw)
2350{
2351}
2352
2353void rtl8723ae_suspend(struct ieee80211_hw *hw)
2354{
2355}
2356
2357void rtl8723ae_resume(struct ieee80211_hw *hw)
2358{
2359}
2360
2361/* Turn on AAP (RCR:bit 0) for promicuous mode. */
2362void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw,
2363 bool allow_all_da, bool write_into_reg)
2364{
2365 struct rtl_priv *rtlpriv = rtl_priv(hw);
2366 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2367
2368 if (allow_all_da) /* Set BIT0 */
2369 rtlpci->receive_config |= RCR_AAP;
2370 else /* Clear BIT0 */
2371 rtlpci->receive_config &= ~RCR_AAP;
2372
2373 if (write_into_reg)
2374 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
2375
2376
2377 RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD,
2378 "receive_config=0x%08X, write_into_reg=%d\n",
2379 rtlpci->receive_config, write_into_reg);
2380}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h
new file mode 100644
index 000000000000..6fa24f79b1d7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h
@@ -0,0 +1,73 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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#ifndef __RTL8723E_HW_H__
31#define __RTL8723E_HW_H__
32
33#define CHK_SVID_SMID(_val1, _val2) \
34 ((rtlefuse->eeprom_svid == (_val1)) && \
35 (rtlefuse->eeprom_smid == (_val2)))
36
37void rtl8723ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
38void rtl8723ae_read_eeprom_info(struct ieee80211_hw *hw);
39
40void rtl8723ae_interrupt_recognized(struct ieee80211_hw *hw,
41 u32 *p_inta, u32 *p_intb);
42int rtl8723ae_hw_init(struct ieee80211_hw *hw);
43void rtl8723ae_card_disable(struct ieee80211_hw *hw);
44void rtl8723ae_enable_interrupt(struct ieee80211_hw *hw);
45void rtl8723ae_disable_interrupt(struct ieee80211_hw *hw);
46int rtl8723ae_set_network_type(struct ieee80211_hw *hw,
47 enum nl80211_iftype type);
48void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
49void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci);
50void rtl8723ae_set_beacon_related_registers(struct ieee80211_hw *hw);
51void rtl8723ae_set_beacon_interval(struct ieee80211_hw *hw);
52void rtl8723ae_update_interrupt_mask(struct ieee80211_hw *hw,
53 u32 add_msr, u32 rm_msr);
54void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
55void rtl8723ae_update_hal_rate_tbl(struct ieee80211_hw *hw,
56 struct ieee80211_sta *sta, u8 rssi_level);
57void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw);
58bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
59void rtl8723ae_enable_hw_security_config(struct ieee80211_hw *hw);
60void rtl8723ae_set_key(struct ieee80211_hw *hw, u32 key_index,
61 u8 *p_macaddr, bool is_group, u8 enc_algo,
62 bool is_wepkey, bool clear_all);
63
64void rtl8723ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
65 bool autoload_fail, u8 *hwinfo);
66void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw);
67void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw);
68void rtl8723ae_suspend(struct ieee80211_hw *hw);
69void rtl8723ae_resume(struct ieee80211_hw *hw);
70void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw,
71 bool allow_all_da, bool write_into_reg);
72
73#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/led.c b/drivers/net/wireless/rtlwifi/rtl8723ae/led.c
new file mode 100644
index 000000000000..9c4e1d811187
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/led.c
@@ -0,0 +1,151 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 "reg.h"
33#include "led.h"
34
35static void _rtl8723ae_init_led(struct ieee80211_hw *hw,
36 struct rtl_led *pled, enum rtl_led_pin ledpin)
37{
38 pled->hw = hw;
39 pled->ledpin = ledpin;
40 pled->ledon = false;
41}
42
43void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
44{
45 struct rtl_priv *rtlpriv = rtl_priv(hw);
46 u8 ledcfg;
47
48 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
49 "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
50
51 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
52
53 switch (pled->ledpin) {
54 case LED_PIN_GPIO0:
55 break;
56 case LED_PIN_LED0:
57 rtl_write_byte(rtlpriv,
58 REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6));
59 break;
60 case LED_PIN_LED1:
61 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
62 break;
63 default:
64 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
65 "switch case not processed\n");
66 break;
67 }
68 pled->ledon = true;
69}
70
71void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
72{
73 struct rtl_priv *rtlpriv = rtl_priv(hw);
74 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
75 u8 ledcfg;
76
77 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
78 "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
79
80 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
81
82 switch (pled->ledpin) {
83 case LED_PIN_GPIO0:
84 break;
85 case LED_PIN_LED0:
86 ledcfg &= 0xf0;
87 if (pcipriv->ledctl.led_opendrain)
88 rtl_write_byte(rtlpriv, REG_LEDCFG2,
89 (ledcfg | BIT(1) | BIT(5) | BIT(6)));
90 else
91 rtl_write_byte(rtlpriv, REG_LEDCFG2,
92 (ledcfg | BIT(3) | BIT(5) | BIT(6)));
93 break;
94 case LED_PIN_LED1:
95 ledcfg &= 0x0f;
96 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3)));
97 break;
98 default:
99 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
100 "switch case not processed\n");
101 break;
102 }
103 pled->ledon = false;
104}
105
106void rtl8723ae_init_sw_leds(struct ieee80211_hw *hw)
107{
108 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
109
110 _rtl8723ae_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
111 _rtl8723ae_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
112}
113
114static void _rtl8723ae_sw_led_control(struct ieee80211_hw *hw,
115 enum led_ctl_mode ledaction)
116{
117 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
118 struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
119
120 switch (ledaction) {
121 case LED_CTL_POWER_ON:
122 case LED_CTL_LINK:
123 case LED_CTL_NO_LINK:
124 rtl8723ae_sw_led_on(hw, pLed0);
125 break;
126 case LED_CTL_POWER_OFF:
127 rtl8723ae_sw_led_off(hw, pLed0);
128 break;
129 default:
130 break;
131 }
132}
133
134void rtl8723ae_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
135{
136 struct rtl_priv *rtlpriv = rtl_priv(hw);
137 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
138
139 if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
140 (ledaction == LED_CTL_TX ||
141 ledaction == LED_CTL_RX ||
142 ledaction == LED_CTL_SITE_SURVEY ||
143 ledaction == LED_CTL_LINK ||
144 ledaction == LED_CTL_NO_LINK ||
145 ledaction == LED_CTL_START_TO_LINK ||
146 ledaction == LED_CTL_POWER_ON)) {
147 return;
148 }
149 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction);
150 _rtl8723ae_sw_led_control(hw, ledaction);
151}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/led.h b/drivers/net/wireless/rtlwifi/rtl8723ae/led.h
new file mode 100644
index 000000000000..2cb88e78f62a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/led.h
@@ -0,0 +1,39 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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#ifndef __RTL92CE_LED_H__
31#define __RTL92CE_LED_H__
32
33void rtl8723ae_init_sw_leds(struct ieee80211_hw *hw);
34void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
35void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
36void rtl8723ae_led_control(struct ieee80211_hw *hw,
37 enum led_ctl_mode ledaction);
38
39#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
new file mode 100644
index 000000000000..39cc7938eedf
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
@@ -0,0 +1,2044 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 "../ps.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "rf.h"
37#include "dm.h"
38#include "table.h"
39
40/* static forward definitions */
41static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
42 enum radio_path rfpath, u32 offset);
43static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
44 enum radio_path rfpath,
45 u32 offset, u32 data);
46static u32 _phy_rf_serial_read(struct ieee80211_hw *hw,
47 enum radio_path rfpath, u32 offset);
48static void _phy_rf_serial_write(struct ieee80211_hw *hw,
49 enum radio_path rfpath, u32 offset, u32 data);
50static u32 _phy_calculate_bit_shift(u32 bitmask);
51static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
52static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw);
53static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype);
54static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype);
55static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw);
56static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
57 u32 cmdtableidx, u32 cmdtablesz,
58 enum swchnlcmd_id cmdid,
59 u32 para1, u32 para2,
60 u32 msdelay);
61static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
62 u8 *stage, u8 *step, u32 *delay);
63static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
64 enum wireless_mode wirelessmode,
65 long power_indbm);
66static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
67 enum wireless_mode wirelessmode, u8 txpwridx);
68static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw);
69
70u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
71 u32 bitmask)
72{
73 struct rtl_priv *rtlpriv = rtl_priv(hw);
74 u32 returnvalue, originalvalue, bitshift;
75
76 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
77 "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
78 originalvalue = rtl_read_dword(rtlpriv, regaddr);
79 bitshift = _phy_calculate_bit_shift(bitmask);
80 returnvalue = (originalvalue & bitmask) >> bitshift;
81
82 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
83 "BBR MASK=0x%x Addr[0x%x]=0x%x\n", bitmask, regaddr,
84 originalvalue);
85
86 return returnvalue;
87}
88
89void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw,
90 u32 regaddr, u32 bitmask, u32 data)
91{
92 struct rtl_priv *rtlpriv = rtl_priv(hw);
93 u32 originalvalue, bitshift;
94
95 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
96 "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr,
97 bitmask, data);
98
99 if (bitmask != MASKDWORD) {
100 originalvalue = rtl_read_dword(rtlpriv, regaddr);
101 bitshift = _phy_calculate_bit_shift(bitmask);
102 data = ((originalvalue & (~bitmask)) | (data << bitshift));
103 }
104
105 rtl_write_dword(rtlpriv, regaddr, data);
106
107 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
108 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
109 regaddr, bitmask, data);
110}
111
112u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,
113 enum radio_path rfpath, u32 regaddr, u32 bitmask)
114{
115 struct rtl_priv *rtlpriv = rtl_priv(hw);
116 u32 original_value, readback_value, bitshift;
117 struct rtl_phy *rtlphy = &(rtlpriv->phy);
118 unsigned long flags;
119
120 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
121 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
122 regaddr, rfpath, bitmask);
123
124 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
125
126 if (rtlphy->rf_mode != RF_OP_BY_FW)
127 original_value = _phy_rf_serial_read(hw, rfpath, regaddr);
128 else
129 original_value = _phy_fw_rf_serial_read(hw, rfpath, regaddr);
130
131 bitshift = _phy_calculate_bit_shift(bitmask);
132 readback_value = (original_value & bitmask) >> bitshift;
133
134 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
135
136 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
137 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
138 regaddr, rfpath, bitmask, original_value);
139
140 return readback_value;
141}
142
143void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw,
144 enum radio_path rfpath,
145 u32 regaddr, u32 bitmask, u32 data)
146{
147 struct rtl_priv *rtlpriv = rtl_priv(hw);
148 struct rtl_phy *rtlphy = &(rtlpriv->phy);
149 u32 original_value, bitshift;
150 unsigned long flags;
151
152 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
153 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
154 regaddr, bitmask, data, rfpath);
155
156 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
157
158 if (rtlphy->rf_mode != RF_OP_BY_FW) {
159 if (bitmask != RFREG_OFFSET_MASK) {
160 original_value = _phy_rf_serial_read(hw, rfpath,
161 regaddr);
162 bitshift = _phy_calculate_bit_shift(bitmask);
163 data = ((original_value & (~bitmask)) |
164 (data << bitshift));
165 }
166
167 _phy_rf_serial_write(hw, rfpath, regaddr, data);
168 } else {
169 if (bitmask != RFREG_OFFSET_MASK) {
170 original_value = _phy_fw_rf_serial_read(hw, rfpath,
171 regaddr);
172 bitshift = _phy_calculate_bit_shift(bitmask);
173 data = ((original_value & (~bitmask)) |
174 (data << bitshift));
175 }
176 _phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
177 }
178
179 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
180
181 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
182 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
183 regaddr, bitmask, data, rfpath);
184}
185
186static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
187 enum radio_path rfpath, u32 offset)
188{
189 RT_ASSERT(false, "deprecated!\n");
190 return 0;
191}
192
193static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
194 enum radio_path rfpath,
195 u32 offset, u32 data)
196{
197 RT_ASSERT(false, "deprecated!\n");
198}
199
200static u32 _phy_rf_serial_read(struct ieee80211_hw *hw,
201 enum radio_path rfpath, u32 offset)
202{
203 struct rtl_priv *rtlpriv = rtl_priv(hw);
204 struct rtl_phy *rtlphy = &(rtlpriv->phy);
205 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
206 u32 newoffset;
207 u32 tmplong, tmplong2;
208 u8 rfpi_enable = 0;
209 u32 retvalue;
210
211 offset &= 0x3f;
212 newoffset = offset;
213 if (RT_CANNOT_IO(hw)) {
214 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
215 return 0xFFFFFFFF;
216 }
217 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
218 if (rfpath == RF90_PATH_A)
219 tmplong2 = tmplong;
220 else
221 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
222 tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
223 (newoffset << 23) | BLSSIREADEDGE;
224 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
225 tmplong & (~BLSSIREADEDGE));
226 mdelay(1);
227 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
228 mdelay(1);
229 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
230 tmplong | BLSSIREADEDGE);
231 mdelay(1);
232 if (rfpath == RF90_PATH_A)
233 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
234 BIT(8));
235 else if (rfpath == RF90_PATH_B)
236 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
237 BIT(8));
238 if (rfpi_enable)
239 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
240 BLSSIREADBACKDATA);
241 else
242 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
243 BLSSIREADBACKDATA);
244 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
245 rfpath, pphyreg->rf_rb, retvalue);
246 return retvalue;
247}
248
249static void _phy_rf_serial_write(struct ieee80211_hw *hw,
250 enum radio_path rfpath, u32 offset, u32 data)
251{
252 u32 data_and_addr;
253 u32 newoffset;
254 struct rtl_priv *rtlpriv = rtl_priv(hw);
255 struct rtl_phy *rtlphy = &(rtlpriv->phy);
256 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
257
258 if (RT_CANNOT_IO(hw)) {
259 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
260 return;
261 }
262 offset &= 0x3f;
263 newoffset = offset;
264 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
265 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
266 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
267 rfpath, pphyreg->rf3wire_offset, data_and_addr);
268}
269
270static u32 _phy_calculate_bit_shift(u32 bitmask)
271{
272 u32 i;
273
274 for (i = 0; i <= 31; i++) {
275 if (((bitmask >> i) & 0x1) == 1)
276 break;
277 }
278 return i;
279}
280
281static void _rtl8723ae_phy_bb_config_1t(struct ieee80211_hw *hw)
282{
283 rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
284 rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
285 rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
286 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
287 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
288 rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
289 rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
290 rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
291 rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
292 rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
293}
294
295bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw)
296{
297 struct rtl_priv *rtlpriv = rtl_priv(hw);
298 bool rtstatus = _phy_cfg_mac_w_header(hw);
299 rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
300 return rtstatus;
301}
302
303bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw)
304{
305 bool rtstatus = true;
306 struct rtl_priv *rtlpriv = rtl_priv(hw);
307 u8 tmpu1b;
308 u8 reg_hwparafile = 1;
309
310 _phy_init_bb_rf_reg_def(hw);
311
312 /* 1. 0x28[1] = 1 */
313 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL);
314 udelay(2);
315 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1)));
316 udelay(2);
317 /* 2. 0x29[7:0] = 0xFF */
318 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff);
319 udelay(2);
320
321 /* 3. 0x02[1:0] = 2b'11 */
322 tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
323 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, (tmpu1b |
324 FEN_BB_GLB_RSTn | FEN_BBRSTB));
325
326 /* 4. 0x25[6] = 0 */
327 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1);
328 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b&(~BIT(6))));
329
330 /* 5. 0x24[20] = 0 Advised by SD3 Alex Wang. 2011.02.09. */
331 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2);
332 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b&(~BIT(4))));
333
334 /* 6. 0x1f[7:0] = 0x07 */
335 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07);
336
337 if (reg_hwparafile == 1)
338 rtstatus = _phy_bb8192c_config_parafile(hw);
339 return rtstatus;
340}
341
342bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw)
343{
344 return rtl8723ae_phy_rf6052_config(hw);
345}
346
347static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
348{
349 struct rtl_priv *rtlpriv = rtl_priv(hw);
350 struct rtl_phy *rtlphy = &(rtlpriv->phy);
351 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
352 bool rtstatus;
353
354 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
355 rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_PHY_REG);
356 if (rtstatus != true) {
357 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
358 return false;
359 }
360
361 if (rtlphy->rf_type == RF_1T2R) {
362 _rtl8723ae_phy_bb_config_1t(hw);
363 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
364 }
365 if (rtlefuse->autoload_failflag == false) {
366 rtlphy->pwrgroup_cnt = 0;
367 rtstatus = _phy_cfg_bb_w_pgheader(hw, BASEBAND_CONFIG_PHY_REG);
368 }
369 if (rtstatus != true) {
370 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
371 return false;
372 }
373 rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_AGC_TAB);
374 if (rtstatus != true) {
375 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
376 return false;
377 }
378 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
379 RFPGA0_XA_HSSIPARAMETER2, 0x200));
380 return true;
381}
382
383static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw)
384{
385 struct rtl_priv *rtlpriv = rtl_priv(hw);
386 u32 i;
387 u32 arraylength;
388 u32 *ptrarray;
389
390 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n");
391 arraylength = RTL8723E_MACARRAYLENGTH;
392 ptrarray = RTL8723EMAC_ARRAY;
393
394 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
395 "Img:RTL8192CEMAC_2T_ARRAY\n");
396 for (i = 0; i < arraylength; i = i + 2)
397 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
398 return true;
399}
400
401static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype)
402{
403 int i;
404 u32 *phy_regarray_table;
405 u32 *agctab_array_table;
406 u16 phy_reg_arraylen, agctab_arraylen;
407 struct rtl_priv *rtlpriv = rtl_priv(hw);
408
409 agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH;
410 agctab_array_table = RTL8723EAGCTAB_1TARRAY;
411 phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH;
412 phy_regarray_table = RTL8723EPHY_REG_1TARRAY;
413 if (configtype == BASEBAND_CONFIG_PHY_REG) {
414 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
415 if (phy_regarray_table[i] == 0xfe)
416 mdelay(50);
417 else if (phy_regarray_table[i] == 0xfd)
418 mdelay(5);
419 else if (phy_regarray_table[i] == 0xfc)
420 mdelay(1);
421 else if (phy_regarray_table[i] == 0xfb)
422 udelay(50);
423 else if (phy_regarray_table[i] == 0xfa)
424 udelay(5);
425 else if (phy_regarray_table[i] == 0xf9)
426 udelay(1);
427 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
428 phy_regarray_table[i + 1]);
429 udelay(1);
430 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
431 "The phy_regarray_table[0] is %x"
432 " Rtl819XPHY_REGArray[1] is %x\n",
433 phy_regarray_table[i],
434 phy_regarray_table[i + 1]);
435 }
436 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
437 for (i = 0; i < agctab_arraylen; i = i + 2) {
438 rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
439 agctab_array_table[i + 1]);
440 udelay(1);
441 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
442 "The agctab_array_table[0] is "
443 "%x Rtl819XPHY_REGArray[1] is %x\n",
444 agctab_array_table[i],
445 agctab_array_table[i + 1]);
446 }
447 }
448 return true;
449}
450
451static void _st_pwrIdx_dfrate_off(struct ieee80211_hw *hw, u32 regaddr,
452 u32 bitmask, u32 data)
453{
454 struct rtl_priv *rtlpriv = rtl_priv(hw);
455 struct rtl_phy *rtlphy = &(rtlpriv->phy);
456
457 switch (regaddr) {
458 case RTXAGC_A_RATE18_06:
459 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0] = data;
460 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
461 "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
462 rtlphy->pwrgroup_cnt,
463 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0]);
464 break;
465 case RTXAGC_A_RATE54_24:
466 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1] = data;
467 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
468 "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
469 rtlphy->pwrgroup_cnt,
470 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1]);
471 break;
472 case RTXAGC_A_CCK1_MCS32:
473 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6] = data;
474 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
475 "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
476 rtlphy->pwrgroup_cnt,
477 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6]);
478 break;
479 case RTXAGC_B_CCK11_A_CCK2_11:
480 if (bitmask == 0xffffff00) {
481 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7] = data;
482 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
483 "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
484 rtlphy->pwrgroup_cnt,
485 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7]);
486 }
487 if (bitmask == 0x000000ff) {
488 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15] = data;
489 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
490 "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
491 rtlphy->pwrgroup_cnt,
492 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15]);
493 }
494 break;
495 case RTXAGC_A_MCS03_MCS00:
496 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2] = data;
497 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
498 "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
499 rtlphy->pwrgroup_cnt,
500 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2]);
501 break;
502 case RTXAGC_A_MCS07_MCS04:
503 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3] = data;
504 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
505 "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
506 rtlphy->pwrgroup_cnt,
507 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3]);
508 break;
509 case RTXAGC_A_MCS11_MCS08:
510 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4] = data;
511 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
512 "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
513 rtlphy->pwrgroup_cnt,
514 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4]);
515 break;
516 case RTXAGC_A_MCS15_MCS12:
517 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5] = data;
518 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
519 "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
520 rtlphy->pwrgroup_cnt,
521 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5]);
522 break;
523 case RTXAGC_B_RATE18_06:
524 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8] = data;
525 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
526 "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
527 rtlphy->pwrgroup_cnt,
528 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8]);
529 break;
530 case RTXAGC_B_RATE54_24:
531 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9] = data;
532 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
533 "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
534 rtlphy->pwrgroup_cnt,
535 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9]);
536 break;
537 case RTXAGC_B_CCK1_55_MCS32:
538 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14] = data;
539 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
540 "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
541 rtlphy->pwrgroup_cnt,
542 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14]);
543 break;
544 case RTXAGC_B_MCS03_MCS00:
545 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10] = data;
546 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
547 "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
548 rtlphy->pwrgroup_cnt,
549 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10]);
550 break;
551 case RTXAGC_B_MCS07_MCS04:
552 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11] = data;
553 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
554 "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
555 rtlphy->pwrgroup_cnt,
556 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11]);
557 break;
558 case RTXAGC_B_MCS11_MCS08:
559 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12] = data;
560 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
561 "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
562 rtlphy->pwrgroup_cnt,
563 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12]);
564 break;
565 case RTXAGC_B_MCS15_MCS12:
566 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13] = data;
567 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
568 "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
569 rtlphy->pwrgroup_cnt,
570 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13]);
571 rtlphy->pwrgroup_cnt++;
572 break;
573 }
574}
575
576static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype)
577{
578 struct rtl_priv *rtlpriv = rtl_priv(hw);
579 int i;
580 u32 *phy_regarray_table_pg;
581 u16 phy_regarray_pg_len;
582
583 phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH;
584 phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG;
585
586 if (configtype == BASEBAND_CONFIG_PHY_REG) {
587 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
588 if (phy_regarray_table_pg[i] == 0xfe)
589 mdelay(50);
590 else if (phy_regarray_table_pg[i] == 0xfd)
591 mdelay(5);
592 else if (phy_regarray_table_pg[i] == 0xfc)
593 mdelay(1);
594 else if (phy_regarray_table_pg[i] == 0xfb)
595 udelay(50);
596 else if (phy_regarray_table_pg[i] == 0xfa)
597 udelay(5);
598 else if (phy_regarray_table_pg[i] == 0xf9)
599 udelay(1);
600
601 _st_pwrIdx_dfrate_off(hw, phy_regarray_table_pg[i],
602 phy_regarray_table_pg[i + 1],
603 phy_regarray_table_pg[i + 2]);
604 }
605 } else {
606 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
607 "configtype != BaseBand_Config_PHY_REG\n");
608 }
609 return true;
610}
611
612bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
613 enum radio_path rfpath)
614{
615 struct rtl_priv *rtlpriv = rtl_priv(hw);
616 int i;
617 bool rtstatus = true;
618 u32 *radioa_array_table;
619 u32 *radiob_array_table;
620 u16 radioa_arraylen, radiob_arraylen;
621
622 radioa_arraylen = Rtl8723ERADIOA_1TARRAYLENGTH;
623 radioa_array_table = RTL8723E_RADIOA_1TARRAY;
624 radiob_arraylen = RTL8723E_RADIOB_1TARRAYLENGTH;
625 radiob_array_table = RTL8723E_RADIOB_1TARRAY;
626
627 rtstatus = true;
628
629 switch (rfpath) {
630 case RF90_PATH_A:
631 for (i = 0; i < radioa_arraylen; i = i + 2) {
632 if (radioa_array_table[i] == 0xfe)
633 mdelay(50);
634 else if (radioa_array_table[i] == 0xfd)
635 mdelay(5);
636 else if (radioa_array_table[i] == 0xfc)
637 mdelay(1);
638 else if (radioa_array_table[i] == 0xfb)
639 udelay(50);
640 else if (radioa_array_table[i] == 0xfa)
641 udelay(5);
642 else if (radioa_array_table[i] == 0xf9)
643 udelay(1);
644 else {
645 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
646 RFREG_OFFSET_MASK,
647 radioa_array_table[i + 1]);
648 udelay(1);
649 }
650 }
651 break;
652 case RF90_PATH_B:
653 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
654 "switch case not process\n");
655 break;
656 case RF90_PATH_C:
657 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
658 "switch case not process\n");
659 break;
660 case RF90_PATH_D:
661 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
662 "switch case not process\n");
663 break;
664 }
665 return true;
666}
667
668void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
669{
670 struct rtl_priv *rtlpriv = rtl_priv(hw);
671 struct rtl_phy *rtlphy = &(rtlpriv->phy);
672
673 rtlphy->default_initialgain[0] =
674 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
675 rtlphy->default_initialgain[1] =
676 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
677 rtlphy->default_initialgain[2] =
678 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
679 rtlphy->default_initialgain[3] =
680 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
681
682 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
683 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
684 rtlphy->default_initialgain[0],
685 rtlphy->default_initialgain[1],
686 rtlphy->default_initialgain[2],
687 rtlphy->default_initialgain[3]);
688
689 rtlphy->framesync = (u8) rtl_get_bbreg(hw,
690 ROFDM0_RXDETECTOR3, MASKBYTE0);
691 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
692 ROFDM0_RXDETECTOR2, MASKDWORD);
693
694 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
695 "Default framesync (0x%x) = 0x%x\n",
696 ROFDM0_RXDETECTOR3, rtlphy->framesync);
697}
698
699static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw)
700{
701 struct rtl_priv *rtlpriv = rtl_priv(hw);
702 struct rtl_phy *rtlphy = &(rtlpriv->phy);
703
704 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
705 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
706 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
707 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
708
709 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
710 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
711 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
712 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
713
714 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
715 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
716
717 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
718 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
719
720 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
721 RFPGA0_XA_LSSIPARAMETER;
722 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
723 RFPGA0_XB_LSSIPARAMETER;
724
725 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER;
726 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER;
727 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
728 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
729
730 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
731 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
732 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
733 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
734
735 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
736 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
737
738 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
739 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
740
741 rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
742 rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
743 rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
744 rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
745
746 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
747 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
748 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
749 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
750
751 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
752 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
753 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
754 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
755
756 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
757 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
758 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE;
759 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
760
761 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
762 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
763 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
764 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
765
766 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
767 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
768 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
769 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
770
771 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
772 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
773 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
774 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
775
776 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
777 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
778 rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
779 rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
780
781 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
782 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
783}
784
785void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
786{
787 struct rtl_priv *rtlpriv = rtl_priv(hw);
788 struct rtl_phy *rtlphy = &(rtlpriv->phy);
789 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
790 u8 txpwr_level;
791 long txpwr_dbm;
792
793 txpwr_level = rtlphy->cur_cck_txpwridx;
794 txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level);
795 txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
796 rtlefuse->legacy_ht_txpowerdiff;
797 if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm)
798 txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
799 txpwr_level);
800 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
801 if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) >
802 txpwr_dbm)
803 txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
804 txpwr_level);
805 *powerlevel = txpwr_dbm;
806}
807
808static void _rtl8723ae_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
809 u8 *cckpowerlevel, u8 *ofdmpowerlevel)
810{
811 struct rtl_priv *rtlpriv = rtl_priv(hw);
812 struct rtl_phy *rtlphy = &(rtlpriv->phy);
813 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
814 u8 index = (channel - 1);
815
816 cckpowerlevel[RF90_PATH_A] =
817 rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
818 cckpowerlevel[RF90_PATH_B] =
819 rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
820 if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
821 ofdmpowerlevel[RF90_PATH_A] =
822 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
823 ofdmpowerlevel[RF90_PATH_B] =
824 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
825 } else if (get_rf_type(rtlphy) == RF_2T2R) {
826 ofdmpowerlevel[RF90_PATH_A] =
827 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
828 ofdmpowerlevel[RF90_PATH_B] =
829 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
830 }
831}
832
833static void _rtl8723ae_ccxpower_index_check(struct ieee80211_hw *hw,
834 u8 channel, u8 *cckpowerlevel,
835 u8 *ofdmpowerlevel)
836{
837 struct rtl_priv *rtlpriv = rtl_priv(hw);
838 struct rtl_phy *rtlphy = &(rtlpriv->phy);
839
840 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
841 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
842}
843
844void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
845{
846 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
847 u8 cckpowerlevel[2], ofdmpowerlevel[2];
848
849 if (rtlefuse->txpwr_fromeprom == false)
850 return;
851 _rtl8723ae_get_txpower_index(hw, channel, &cckpowerlevel[0],
852 &ofdmpowerlevel[0]);
853 _rtl8723ae_ccxpower_index_check(hw, channel, &cckpowerlevel[0],
854 &ofdmpowerlevel[0]);
855 rtl8723ae_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
856 rtl8723ae_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
857}
858
859bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
860{
861 struct rtl_priv *rtlpriv = rtl_priv(hw);
862 struct rtl_phy *rtlphy = &(rtlpriv->phy);
863 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
864 u8 idx;
865 u8 rf_path;
866 u8 ccktxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_B,
867 power_indbm);
868 u8 ofdmtxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_N_24G,
869 power_indbm);
870 if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
871 ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
872 else
873 ofdmtxpwridx = 0;
874 RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
875 "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
876 power_indbm, ccktxpwridx, ofdmtxpwridx);
877 for (idx = 0; idx < 14; idx++) {
878 for (rf_path = 0; rf_path < 2; rf_path++) {
879 rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
880 rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
881 ofdmtxpwridx;
882 rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
883 ofdmtxpwridx;
884 }
885 }
886 rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
887 return true;
888}
889
890static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
891 enum wireless_mode wirelessmode,
892 long power_indbm)
893{
894 u8 txpwridx;
895 long offset;
896
897 switch (wirelessmode) {
898 case WIRELESS_MODE_B:
899 offset = -7;
900 break;
901 case WIRELESS_MODE_G:
902 case WIRELESS_MODE_N_24G:
903 offset = -8;
904 break;
905 default:
906 offset = -8;
907 break;
908 }
909
910 if ((power_indbm - offset) > 0)
911 txpwridx = (u8) ((power_indbm - offset) * 2);
912 else
913 txpwridx = 0;
914
915 if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
916 txpwridx = MAX_TXPWR_IDX_NMODE_92S;
917
918 return txpwridx;
919}
920
921static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
922 enum wireless_mode wirelessmode, u8 txpwridx)
923{
924 long offset;
925 long pwrout_dbm;
926
927 switch (wirelessmode) {
928 case WIRELESS_MODE_B:
929 offset = -7;
930 break;
931 case WIRELESS_MODE_G:
932 case WIRELESS_MODE_N_24G:
933 offset = -8;
934 break;
935 default:
936 offset = -8;
937 break;
938 }
939 pwrout_dbm = txpwridx / 2 + offset;
940 return pwrout_dbm;
941}
942
943void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
944{
945 struct rtl_priv *rtlpriv = rtl_priv(hw);
946 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
947 enum io_type iotype;
948
949 if (!is_hal_stop(rtlhal)) {
950 switch (operation) {
951 case SCAN_OPT_BACKUP:
952 iotype = IO_CMD_PAUSE_DM_BY_SCAN;
953 rtlpriv->cfg->ops->set_hw_reg(hw,
954 HW_VAR_IO_CMD,
955 (u8 *)&iotype);
956
957 break;
958 case SCAN_OPT_RESTORE:
959 iotype = IO_CMD_RESUME_DM_BY_SCAN;
960 rtlpriv->cfg->ops->set_hw_reg(hw,
961 HW_VAR_IO_CMD,
962 (u8 *)&iotype);
963 break;
964 default:
965 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
966 "Unknown Scan Backup operation.\n");
967 break;
968 }
969 }
970}
971
972void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
973{
974 struct rtl_priv *rtlpriv = rtl_priv(hw);
975 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
976 struct rtl_phy *rtlphy = &(rtlpriv->phy);
977 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
978 u8 reg_bw_opmode;
979 u8 reg_prsr_rsc;
980
981 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
982 "Switch to %s bandwidth\n",
983 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
984 "20MHz" : "40MHz");
985
986 if (is_hal_stop(rtlhal)) {
987 rtlphy->set_bwmode_inprogress = false;
988 return;
989 }
990
991 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
992 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
993
994 switch (rtlphy->current_chan_bw) {
995 case HT_CHANNEL_WIDTH_20:
996 reg_bw_opmode |= BW_OPMODE_20MHZ;
997 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
998 break;
999 case HT_CHANNEL_WIDTH_20_40:
1000 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1001 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1002 reg_prsr_rsc =
1003 (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
1004 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1005 break;
1006 default:
1007 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1008 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1009 break;
1010 }
1011
1012 switch (rtlphy->current_chan_bw) {
1013 case HT_CHANNEL_WIDTH_20:
1014 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1015 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1016 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
1017 break;
1018 case HT_CHANNEL_WIDTH_20_40:
1019 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1020 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1021
1022 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1023 (mac->cur_40_prime_sc >> 1));
1024 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1025 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
1026
1027 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1028 (mac->cur_40_prime_sc ==
1029 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1030 break;
1031 default:
1032 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1033 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1034 break;
1035 }
1036 rtl8723ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1037 rtlphy->set_bwmode_inprogress = false;
1038 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
1039}
1040
1041void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw,
1042 enum nl80211_channel_type ch_type)
1043{
1044 struct rtl_priv *rtlpriv = rtl_priv(hw);
1045 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1046 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1047 u8 tmp_bw = rtlphy->current_chan_bw;
1048
1049 if (rtlphy->set_bwmode_inprogress)
1050 return;
1051 rtlphy->set_bwmode_inprogress = true;
1052 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1053 rtl8723ae_phy_set_bw_mode_callback(hw);
1054 } else {
1055 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1056 "FALSE driver sleep or unload\n");
1057 rtlphy->set_bwmode_inprogress = false;
1058 rtlphy->current_chan_bw = tmp_bw;
1059 }
1060}
1061
1062void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1063{
1064 struct rtl_priv *rtlpriv = rtl_priv(hw);
1065 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1066 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1067 u32 delay;
1068
1069 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1070 "switch to channel%d\n", rtlphy->current_channel);
1071 if (is_hal_stop(rtlhal))
1072 return;
1073 do {
1074 if (!rtlphy->sw_chnl_inprogress)
1075 break;
1076 if (!_phy_sw_chnl_step_by_step
1077 (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
1078 &rtlphy->sw_chnl_step, &delay)) {
1079 if (delay > 0)
1080 mdelay(delay);
1081 else
1082 continue;
1083 } else {
1084 rtlphy->sw_chnl_inprogress = false;
1085 }
1086 break;
1087 } while (true);
1088 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
1089}
1090
1091u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw)
1092{
1093 struct rtl_priv *rtlpriv = rtl_priv(hw);
1094 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1095 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1096
1097 if (rtlphy->sw_chnl_inprogress)
1098 return 0;
1099 if (rtlphy->set_bwmode_inprogress)
1100 return 0;
1101 RT_ASSERT((rtlphy->current_channel <= 14),
1102 "WIRELESS_MODE_G but channel>14");
1103 rtlphy->sw_chnl_inprogress = true;
1104 rtlphy->sw_chnl_stage = 0;
1105 rtlphy->sw_chnl_step = 0;
1106 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1107 rtl8723ae_phy_sw_chnl_callback(hw);
1108 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1109 "sw_chnl_inprogress false schdule workitem\n");
1110 rtlphy->sw_chnl_inprogress = false;
1111 } else {
1112 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1113 "sw_chnl_inprogress false driver sleep or unload\n");
1114 rtlphy->sw_chnl_inprogress = false;
1115 }
1116 return 1;
1117}
1118
1119static void _rtl8723ae_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel)
1120{
1121 struct rtl_priv *rtlpriv = rtl_priv(hw);
1122 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1123 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1124
1125 if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
1126 if (channel == 6 && rtlphy->current_chan_bw ==
1127 HT_CHANNEL_WIDTH_20)
1128 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
1129 0x00255);
1130 else{
1131 u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A,
1132 RF_RX_G1, RFREG_OFFSET_MASK);
1133 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
1134 backupRF0x1A);
1135 }
1136 }
1137}
1138
1139static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
1140 u8 *stage, u8 *step, u32 *delay)
1141{
1142 struct rtl_priv *rtlpriv = rtl_priv(hw);
1143 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1144 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1145 u32 precommoncmdcnt;
1146 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1147 u32 postcommoncmdcnt;
1148 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1149 u32 rfdependcmdcnt;
1150 struct swchnlcmd *currentcmd = NULL;
1151 u8 rfpath;
1152 u8 num_total_rfpath = rtlphy->num_total_rfpath;
1153
1154 precommoncmdcnt = 0;
1155 _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1156 MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL,
1157 0, 0, 0);
1158 _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1159 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1160 postcommoncmdcnt = 0;
1161
1162 _phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1163 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
1164 rfdependcmdcnt = 0;
1165
1166 RT_ASSERT((channel >= 1 && channel <= 14),
1167 "illegal channel for Zebra: %d\n", channel);
1168
1169 _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1170 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
1171 RF_CHNLBW, channel, 10);
1172
1173 _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1174 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
1175
1176 do {
1177 switch (*stage) {
1178 case 0:
1179 currentcmd = &precommoncmd[*step];
1180 break;
1181 case 1:
1182 currentcmd = &rfdependcmd[*step];
1183 break;
1184 case 2:
1185 currentcmd = &postcommoncmd[*step];
1186 break;
1187 }
1188
1189 if (currentcmd->cmdid == CMDID_END) {
1190 if ((*stage) == 2) {
1191 return true;
1192 } else {
1193 (*stage)++;
1194 (*step) = 0;
1195 continue;
1196 }
1197 }
1198
1199 switch (currentcmd->cmdid) {
1200 case CMDID_SET_TXPOWEROWER_LEVEL:
1201 rtl8723ae_phy_set_txpower_level(hw, channel);
1202 break;
1203 case CMDID_WRITEPORT_ULONG:
1204 rtl_write_dword(rtlpriv, currentcmd->para1,
1205 currentcmd->para2);
1206 break;
1207 case CMDID_WRITEPORT_USHORT:
1208 rtl_write_word(rtlpriv, currentcmd->para1,
1209 (u16) currentcmd->para2);
1210 break;
1211 case CMDID_WRITEPORT_UCHAR:
1212 rtl_write_byte(rtlpriv, currentcmd->para1,
1213 (u8) currentcmd->para2);
1214 break;
1215 case CMDID_RF_WRITEREG:
1216 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1217 rtlphy->rfreg_chnlval[rfpath] =
1218 ((rtlphy->rfreg_chnlval[rfpath] &
1219 0xfffffc00) | currentcmd->para2);
1220
1221 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1222 currentcmd->para1,
1223 RFREG_OFFSET_MASK,
1224 rtlphy->rfreg_chnlval[rfpath]);
1225 }
1226 _rtl8723ae_phy_sw_rf_seting(hw, channel);
1227 break;
1228 default:
1229 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1230 "switch case not process\n");
1231 break;
1232 }
1233
1234 break;
1235 } while (true);
1236
1237 (*delay) = currentcmd->msdelay;
1238 (*step)++;
1239 return false;
1240}
1241
1242static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
1243 u32 cmdtableidx, u32 cmdtablesz,
1244 enum swchnlcmd_id cmdid, u32 para1,
1245 u32 para2, u32 msdelay)
1246{
1247 struct swchnlcmd *pcmd;
1248
1249 if (cmdtable == NULL) {
1250 RT_ASSERT(false, "cmdtable cannot be NULL.\n");
1251 return false;
1252 }
1253
1254 if (cmdtableidx >= cmdtablesz)
1255 return false;
1256
1257 pcmd = cmdtable + cmdtableidx;
1258 pcmd->cmdid = cmdid;
1259 pcmd->para1 = para1;
1260 pcmd->para2 = para2;
1261 pcmd->msdelay = msdelay;
1262 return true;
1263}
1264
1265static u8 _rtl8723ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1266{
1267 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
1268 u8 result = 0x00;
1269
1270 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
1271 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
1272 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
1273 rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
1274 config_pathb ? 0x28160202 : 0x28160502);
1275
1276 if (config_pathb) {
1277 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
1278 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
1279 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
1280 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
1281 }
1282
1283 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
1284 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1285 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1286
1287 mdelay(IQK_DELAY_TIME);
1288
1289 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1290 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1291 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1292 reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1293
1294 if (!(reg_eac & BIT(28)) &&
1295 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1296 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1297 result |= 0x01;
1298 else
1299 return result;
1300
1301 if (!(reg_eac & BIT(27)) &&
1302 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1303 (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1304 result |= 0x02;
1305 return result;
1306}
1307
1308static u8 _rtl8723ae_phy_path_b_iqk(struct ieee80211_hw *hw)
1309{
1310 u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
1311 u8 result = 0x00;
1312
1313 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
1314 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
1315 mdelay(IQK_DELAY_TIME);
1316 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1317 reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
1318 reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
1319 reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
1320 reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
1321
1322 if (!(reg_eac & BIT(31)) &&
1323 (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
1324 (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
1325 result |= 0x01;
1326 else
1327 return result;
1328 if (!(reg_eac & BIT(30)) &&
1329 (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
1330 (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
1331 result |= 0x02;
1332 return result;
1333}
1334
1335static void phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, bool iqk_ok,
1336 long result[][8], u8 final_candidate,
1337 bool btxonly)
1338{
1339 u32 oldval_0, x, tx0_a, reg;
1340 long y, tx0_c;
1341
1342 if (final_candidate == 0xFF) {
1343 return;
1344 } else if (iqk_ok) {
1345 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1346 MASKDWORD) >> 22) & 0x3FF;
1347 x = result[final_candidate][0];
1348 if ((x & 0x00000200) != 0)
1349 x = x | 0xFFFFFC00;
1350 tx0_a = (x * oldval_0) >> 8;
1351 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
1352 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
1353 ((x * oldval_0 >> 7) & 0x1));
1354 y = result[final_candidate][1];
1355 if ((y & 0x00000200) != 0)
1356 y = y | 0xFFFFFC00;
1357 tx0_c = (y * oldval_0) >> 8;
1358 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1359 ((tx0_c & 0x3C0) >> 6));
1360 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
1361 (tx0_c & 0x3F));
1362 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
1363 ((y * oldval_0 >> 7) & 0x1));
1364 if (btxonly)
1365 return;
1366 reg = result[final_candidate][2];
1367 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1368 reg = result[final_candidate][3] & 0x3F;
1369 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1370 reg = (result[final_candidate][3] >> 6) & 0xF;
1371 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1372 }
1373}
1374
1375static void phy_save_adda_regs(struct ieee80211_hw *hw,
1376 u32 *addareg, u32 *addabackup,
1377 u32 registernum)
1378{
1379 u32 i;
1380
1381 for (i = 0; i < registernum; i++)
1382 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1383}
1384
1385static void phy_save_mac_regs(struct ieee80211_hw *hw, u32 *macreg,
1386 u32 *macbackup)
1387{
1388 struct rtl_priv *rtlpriv = rtl_priv(hw);
1389 u32 i;
1390
1391 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1392 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1393 macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1394}
1395
1396static void phy_reload_adda_regs(struct ieee80211_hw *hw, u32 *addareg,
1397 u32 *addabackup, u32 regiesternum)
1398{
1399 u32 i;
1400
1401 for (i = 0; i < regiesternum; i++)
1402 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
1403}
1404
1405static void phy_reload_mac_regs(struct ieee80211_hw *hw, u32 *macreg,
1406 u32 *macbackup)
1407{
1408 struct rtl_priv *rtlpriv = rtl_priv(hw);
1409 u32 i;
1410
1411 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1412 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1413 rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1414}
1415
1416static void _rtl8723ae_phy_path_adda_on(struct ieee80211_hw *hw,
1417 u32 *addareg, bool is_patha_on,
1418 bool is2t)
1419{
1420 u32 pathOn;
1421 u32 i;
1422
1423 pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1424 if (false == is2t) {
1425 pathOn = 0x0bdb25a0;
1426 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1427 } else {
1428 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn);
1429 }
1430
1431 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1432 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn);
1433}
1434
1435static void _rtl8723ae_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1436 u32 *macreg, u32 *macbackup)
1437{
1438 struct rtl_priv *rtlpriv = rtl_priv(hw);
1439 u32 i = 0;
1440
1441 rtl_write_byte(rtlpriv, macreg[i], 0x3F);
1442
1443 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1444 rtl_write_byte(rtlpriv, macreg[i],
1445 (u8) (macbackup[i] & (~BIT(3))));
1446 rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1447}
1448
1449static void _rtl8723ae_phy_path_a_standby(struct ieee80211_hw *hw)
1450{
1451 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1452 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1453 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1454}
1455
1456static void _rtl8723ae_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1457{
1458 u32 mode;
1459
1460 mode = pi_mode ? 0x01000100 : 0x01000000;
1461 rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1462 rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1463}
1464
1465static bool phy_simularity_comp(struct ieee80211_hw *hw, long result[][8],
1466 u8 c1, u8 c2)
1467{
1468 u32 i, j, diff, simularity_bitmap, bound;
1469
1470 u8 final_candidate[2] = { 0xFF, 0xFF };
1471 bool bresult = true;
1472
1473 bound = 4;
1474
1475 simularity_bitmap = 0;
1476
1477 for (i = 0; i < bound; i++) {
1478 diff = (result[c1][i] > result[c2][i]) ?
1479 (result[c1][i] - result[c2][i]) :
1480 (result[c2][i] - result[c1][i]);
1481
1482 if (diff > MAX_TOLERANCE) {
1483 if ((i == 2 || i == 6) && !simularity_bitmap) {
1484 if (result[c1][i] + result[c1][i + 1] == 0)
1485 final_candidate[(i / 4)] = c2;
1486 else if (result[c2][i] + result[c2][i + 1] == 0)
1487 final_candidate[(i / 4)] = c1;
1488 else
1489 simularity_bitmap = simularity_bitmap |
1490 (1 << i);
1491 } else
1492 simularity_bitmap =
1493 simularity_bitmap | (1 << i);
1494 }
1495 }
1496
1497 if (simularity_bitmap == 0) {
1498 for (i = 0; i < (bound / 4); i++) {
1499 if (final_candidate[i] != 0xFF) {
1500 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1501 result[3][j] =
1502 result[final_candidate[i]][j];
1503 bresult = false;
1504 }
1505 }
1506 return bresult;
1507 } else if (!(simularity_bitmap & 0x0F)) {
1508 for (i = 0; i < 4; i++)
1509 result[3][i] = result[c1][i];
1510 return false;
1511 } else {
1512 return false;
1513 }
1514
1515}
1516
1517static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,
1518 long result[][8], u8 t, bool is2t)
1519{
1520 struct rtl_priv *rtlpriv = rtl_priv(hw);
1521 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1522 u32 i;
1523 u8 patha_ok, pathb_ok;
1524 u32 adda_reg[IQK_ADDA_REG_NUM] = {
1525 0x85c, 0xe6c, 0xe70, 0xe74,
1526 0xe78, 0xe7c, 0xe80, 0xe84,
1527 0xe88, 0xe8c, 0xed0, 0xed4,
1528 0xed8, 0xedc, 0xee0, 0xeec
1529 };
1530 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1531 0x522, 0x550, 0x551, 0x040
1532 };
1533 const u32 retrycount = 2;
1534 u32 bbvalue;
1535
1536 if (t == 0) {
1537 bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD);
1538
1539 phy_save_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16);
1540 phy_save_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup);
1541 }
1542 _rtl8723ae_phy_path_adda_on(hw, adda_reg, true, is2t);
1543 if (t == 0) {
1544 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1545 RFPGA0_XA_HSSIPARAMETER1,
1546 BIT(8));
1547 }
1548
1549 if (!rtlphy->rfpi_enable)
1550 _rtl8723ae_phy_pi_mode_switch(hw, true);
1551 if (t == 0) {
1552 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1553 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1554 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1555 }
1556 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1557 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1558 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1559 if (is2t) {
1560 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1561 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1562 }
1563 _rtl8723ae_phy_mac_setting_calibration(hw, iqk_mac_reg,
1564 rtlphy->iqk_mac_backup);
1565 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1566 if (is2t)
1567 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1568 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1569 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1570 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1571 for (i = 0; i < retrycount; i++) {
1572 patha_ok = _rtl8723ae_phy_path_a_iqk(hw, is2t);
1573 if (patha_ok == 0x03) {
1574 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1575 0x3FF0000) >> 16;
1576 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1577 0x3FF0000) >> 16;
1578 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1579 0x3FF0000) >> 16;
1580 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1581 0x3FF0000) >> 16;
1582 break;
1583 } else if (i == (retrycount - 1) && patha_ok == 0x01)
1584
1585 result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1586 MASKDWORD) & 0x3FF0000) >> 16;
1587 result[t][1] =
1588 (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1589
1590 }
1591
1592 if (is2t) {
1593 _rtl8723ae_phy_path_a_standby(hw);
1594 _rtl8723ae_phy_path_adda_on(hw, adda_reg, false, is2t);
1595 for (i = 0; i < retrycount; i++) {
1596 pathb_ok = _rtl8723ae_phy_path_b_iqk(hw);
1597 if (pathb_ok == 0x03) {
1598 result[t][4] =
1599 (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
1600 0x3FF0000) >> 16;
1601 result[t][5] =
1602 (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1603 0x3FF0000) >> 16;
1604 result[t][6] =
1605 (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1606 0x3FF0000) >> 16;
1607 result[t][7] =
1608 (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1609 0x3FF0000) >> 16;
1610 break;
1611 } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1612 result[t][4] =
1613 (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
1614 0x3FF0000) >> 16;
1615 }
1616 result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1617 0x3FF0000) >> 16;
1618 }
1619 }
1620 rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1621 rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1622 rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1623 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1624 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1625 if (is2t)
1626 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1627 if (t != 0) {
1628 if (!rtlphy->rfpi_enable)
1629 _rtl8723ae_phy_pi_mode_switch(hw, false);
1630 phy_reload_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16);
1631 phy_reload_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup);
1632 }
1633}
1634
1635static void _rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1636{
1637 struct rtl_priv *rtlpriv = rtl_priv(hw);
1638 u8 tmpreg;
1639 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1640
1641 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1642
1643 if ((tmpreg & 0x70) != 0)
1644 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1645 else
1646 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1647
1648 if ((tmpreg & 0x70) != 0) {
1649 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1650
1651 if (is2t)
1652 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1653 MASK12BITS);
1654
1655 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1656 (rf_a_mode & 0x8FFFF) | 0x10000);
1657
1658 if (is2t)
1659 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1660 (rf_b_mode & 0x8FFFF) | 0x10000);
1661 }
1662 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1663
1664 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
1665
1666 mdelay(100);
1667
1668 if ((tmpreg & 0x70) != 0) {
1669 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1670 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1671
1672 if (is2t)
1673 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1674 rf_b_mode);
1675 } else {
1676 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1677 }
1678}
1679
1680static void _rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1681 bool bmain, bool is2t)
1682{
1683 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1684
1685 if (is_hal_stop(rtlhal)) {
1686 rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
1687 rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1688 }
1689 if (is2t) {
1690 if (bmain)
1691 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1692 BIT(5) | BIT(6), 0x1);
1693 else
1694 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1695 BIT(5) | BIT(6), 0x2);
1696 } else {
1697 if (bmain)
1698 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
1699 else
1700 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
1701
1702 }
1703}
1704
1705#undef IQK_ADDA_REG_NUM
1706#undef IQK_DELAY_TIME
1707
1708void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1709{
1710 struct rtl_priv *rtlpriv = rtl_priv(hw);
1711 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1712 long result[4][8];
1713 u8 i, final_candidate;
1714 bool patha_ok, pathb_ok;
1715 long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
1716 reg_ecc, reg_tmp = 0;
1717 bool is12simular, is13simular, is23simular;
1718 bool start_conttx = false, singletone = false;
1719 u32 iqk_bb_reg[10] = {
1720 ROFDM0_XARXIQIMBALANCE,
1721 ROFDM0_XBRXIQIMBALANCE,
1722 ROFDM0_ECCATHRESHOLD,
1723 ROFDM0_AGCRSSITABLE,
1724 ROFDM0_XATXIQIMBALANCE,
1725 ROFDM0_XBTXIQIMBALANCE,
1726 ROFDM0_XCTXIQIMBALANCE,
1727 ROFDM0_XCTXAFE,
1728 ROFDM0_XDTXAFE,
1729 ROFDM0_RXIQEXTANTA
1730 };
1731
1732 if (recovery) {
1733 phy_reload_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10);
1734 return;
1735 }
1736 if (start_conttx || singletone)
1737 return;
1738 for (i = 0; i < 8; i++) {
1739 result[0][i] = 0;
1740 result[1][i] = 0;
1741 result[2][i] = 0;
1742 result[3][i] = 0;
1743 }
1744 final_candidate = 0xff;
1745 patha_ok = false;
1746 pathb_ok = false;
1747 is12simular = false;
1748 is23simular = false;
1749 is13simular = false;
1750 for (i = 0; i < 3; i++) {
1751 _rtl8723ae_phy_iq_calibrate(hw, result, i, false);
1752 if (i == 1) {
1753 is12simular = phy_simularity_comp(hw, result, 0, 1);
1754 if (is12simular) {
1755 final_candidate = 0;
1756 break;
1757 }
1758 }
1759 if (i == 2) {
1760 is13simular = phy_simularity_comp(hw, result, 0, 2);
1761 if (is13simular) {
1762 final_candidate = 0;
1763 break;
1764 }
1765 is23simular = phy_simularity_comp(hw, result, 1, 2);
1766 if (is23simular) {
1767 final_candidate = 1;
1768 } else {
1769 for (i = 0; i < 8; i++)
1770 reg_tmp += result[3][i];
1771
1772 if (reg_tmp != 0)
1773 final_candidate = 3;
1774 else
1775 final_candidate = 0xFF;
1776 }
1777 }
1778 }
1779 for (i = 0; i < 4; i++) {
1780 reg_e94 = result[i][0];
1781 reg_e9c = result[i][1];
1782 reg_ea4 = result[i][2];
1783 reg_eac = result[i][3];
1784 reg_eb4 = result[i][4];
1785 reg_ebc = result[i][5];
1786 reg_ec4 = result[i][6];
1787 reg_ecc = result[i][7];
1788 }
1789 if (final_candidate != 0xff) {
1790 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
1791 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
1792 reg_ea4 = result[final_candidate][2];
1793 reg_eac = result[final_candidate][3];
1794 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
1795 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
1796 reg_ec4 = result[final_candidate][6];
1797 reg_ecc = result[final_candidate][7];
1798 patha_ok = pathb_ok = true;
1799 } else {
1800 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
1801 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
1802 }
1803 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1804 phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1805 final_candidate, (reg_ea4 == 0));
1806 phy_save_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10);
1807}
1808
1809void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw)
1810{
1811 bool start_conttx = false, singletone = false;
1812
1813 if (start_conttx || singletone)
1814 return;
1815 _rtl8723ae_phy_lc_calibrate(hw, false);
1816}
1817
1818void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1819{
1820 _rtl8723ae_phy_set_rfpath_switch(hw, bmain, false);
1821}
1822
1823bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1824{
1825 struct rtl_priv *rtlpriv = rtl_priv(hw);
1826 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1827 bool postprocessing = false;
1828
1829 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1830 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1831 iotype, rtlphy->set_io_inprogress);
1832 do {
1833 switch (iotype) {
1834 case IO_CMD_RESUME_DM_BY_SCAN:
1835 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1836 "[IO CMD] Resume DM after scan.\n");
1837 postprocessing = true;
1838 break;
1839 case IO_CMD_PAUSE_DM_BY_SCAN:
1840 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1841 "[IO CMD] Pause DM before scan.\n");
1842 postprocessing = true;
1843 break;
1844 default:
1845 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1846 "switch case not process\n");
1847 break;
1848 }
1849 } while (false);
1850 if (postprocessing && !rtlphy->set_io_inprogress) {
1851 rtlphy->set_io_inprogress = true;
1852 rtlphy->current_io_type = iotype;
1853 } else {
1854 return false;
1855 }
1856 rtl8723ae_phy_set_io(hw);
1857 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
1858 return true;
1859}
1860
1861static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw)
1862{
1863 struct rtl_priv *rtlpriv = rtl_priv(hw);
1864 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1865 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1866
1867 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1868 "--->Cmd(%#x), set_io_inprogress(%d)\n",
1869 rtlphy->current_io_type, rtlphy->set_io_inprogress);
1870 switch (rtlphy->current_io_type) {
1871 case IO_CMD_RESUME_DM_BY_SCAN:
1872 dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
1873 rtl8723ae_dm_write_dig(hw);
1874 rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
1875 break;
1876 case IO_CMD_PAUSE_DM_BY_SCAN:
1877 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
1878 dm_digtable->cur_igvalue = 0x17;
1879 rtl8723ae_dm_write_dig(hw);
1880 break;
1881 default:
1882 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1883 "switch case not process\n");
1884 break;
1885 }
1886 rtlphy->set_io_inprogress = false;
1887 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1888 "<---(%#x)\n", rtlphy->current_io_type);
1889}
1890
1891static void rtl8723ae_phy_set_rf_on(struct ieee80211_hw *hw)
1892{
1893 struct rtl_priv *rtlpriv = rtl_priv(hw);
1894
1895 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
1896 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1897 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1898 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1899 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1900 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1901}
1902
1903static void _rtl8723ae_phy_set_rf_sleep(struct ieee80211_hw *hw)
1904{
1905 struct rtl_priv *rtlpriv = rtl_priv(hw);
1906 u32 u4b_tmp;
1907 u8 delay = 5;
1908
1909 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1910 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1911 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1912 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1913 while (u4b_tmp != 0 && delay > 0) {
1914 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
1915 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1916 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1917 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1918 delay--;
1919 }
1920 if (delay == 0) {
1921 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1922 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1923 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1924 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1925 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1926 "Switch RF timeout !!!.\n");
1927 return;
1928 }
1929 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1930 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
1931}
1932
1933static bool _rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
1934 enum rf_pwrstate rfpwr_state)
1935{
1936 struct rtl_priv *rtlpriv = rtl_priv(hw);
1937 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1938 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1939 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1940 struct rtl8192_tx_ring *ring = NULL;
1941 bool bresult = true;
1942 u8 i, queue_id;
1943
1944 switch (rfpwr_state) {
1945 case ERFON:
1946 if ((ppsc->rfpwr_state == ERFOFF) &&
1947 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
1948 bool rtstatus;
1949 u32 InitializeCount = 0;
1950 do {
1951 InitializeCount++;
1952 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1953 "IPS Set eRf nic enable\n");
1954 rtstatus = rtl_ps_enable_nic(hw);
1955 } while ((rtstatus != true) && (InitializeCount < 10));
1956 RT_CLEAR_PS_LEVEL(ppsc,
1957 RT_RF_OFF_LEVL_HALT_NIC);
1958 } else {
1959 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1960 "Set ERFON sleeped:%d ms\n",
1961 jiffies_to_msecs(jiffies -
1962 ppsc->last_sleep_jiffies));
1963 ppsc->last_awake_jiffies = jiffies;
1964 rtl8723ae_phy_set_rf_on(hw);
1965 }
1966 if (mac->link_state == MAC80211_LINKED) {
1967 rtlpriv->cfg->ops->led_control(hw,
1968 LED_CTL_LINK);
1969 } else {
1970 rtlpriv->cfg->ops->led_control(hw,
1971 LED_CTL_NO_LINK);
1972 }
1973 break;
1974 case ERFOFF:
1975 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
1976 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1977 "IPS Set eRf nic disable\n");
1978 rtl_ps_disable_nic(hw);
1979 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1980 } else {
1981 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
1982 rtlpriv->cfg->ops->led_control(hw,
1983 LED_CTL_NO_LINK);
1984 } else {
1985 rtlpriv->cfg->ops->led_control(hw,
1986 LED_CTL_POWER_OFF);
1987 }
1988 }
1989 break;
1990 case ERFSLEEP:
1991 if (ppsc->rfpwr_state == ERFOFF)
1992 break;
1993 for (queue_id = 0, i = 0;
1994 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
1995 ring = &pcipriv->dev.tx_ring[queue_id];
1996 if (skb_queue_len(&ring->queue) == 0) {
1997 queue_id++;
1998 continue;
1999 } else {
2000 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2001 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2002 (i + 1), queue_id,
2003 skb_queue_len(&ring->queue));
2004
2005 udelay(10);
2006 i++;
2007 }
2008 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2009 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2010 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2011 MAX_DOZE_WAITING_TIMES_9x,
2012 queue_id,
2013 skb_queue_len(&ring->queue));
2014 break;
2015 }
2016 }
2017 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2018 "Set ERFSLEEP awaked:%d ms\n",
2019 jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
2020 ppsc->last_sleep_jiffies = jiffies;
2021 _rtl8723ae_phy_set_rf_sleep(hw);
2022 break;
2023 default:
2024 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2025 "switch case not processed\n");
2026 bresult = false;
2027 break;
2028 }
2029 if (bresult)
2030 ppsc->rfpwr_state = rfpwr_state;
2031 return bresult;
2032}
2033
2034bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
2035 enum rf_pwrstate rfpwr_state)
2036{
2037 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2038 bool bresult = false;
2039
2040 if (rfpwr_state == ppsc->rfpwr_state)
2041 return bresult;
2042 bresult = _rtl8723ae_phy_set_rf_power_state(hw, rfpwr_state);
2043 return bresult;
2044}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
new file mode 100644
index 000000000000..e7a59eba351a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
@@ -0,0 +1,224 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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#ifndef __RTL92C_PHY_H__
31#define __RTL92C_PHY_H__
32
33#define MAX_PRECMD_CNT 16
34#define MAX_RFDEPENDCMD_CNT 16
35#define MAX_POSTCMD_CNT 16
36
37#define MAX_DOZE_WAITING_TIMES_9x 64
38
39#define RT_CANNOT_IO(hw) false
40#define HIGHPOWER_RADIOA_ARRAYLEN 22
41
42#define MAX_TOLERANCE 5
43#define IQK_DELAY_TIME 1
44
45#define APK_BB_REG_NUM 5
46#define APK_AFE_REG_NUM 16
47#define APK_CURVE_REG_NUM 4
48#define PATH_NUM 2
49
50#define LOOP_LIMIT 5
51#define MAX_STALL_TIME 50
52#define AntennaDiversityValue 0x80
53#define MAX_TXPWR_IDX_NMODE_92S 63
54#define Reset_Cnt_Limit 3
55
56#define IQK_MAC_REG_NUM 4
57
58#define RF6052_MAX_PATH 2
59
60#define CT_OFFSET_MAC_ADDR 0X16
61
62#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
63#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
64#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66
65#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
66#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
67
68#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
69#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
70
71#define CT_OFFSET_CHANNEL_PLAH 0x75
72#define CT_OFFSET_THERMAL_METER 0x78
73#define CT_OFFSET_RF_OPTION 0x79
74#define CT_OFFSET_VERSION 0x7E
75#define CT_OFFSET_CUSTOMER_ID 0x7F
76
77#define RTL92C_MAX_PATH_NUM 2
78
79enum swchnlcmd_id {
80 CMDID_END,
81 CMDID_SET_TXPOWEROWER_LEVEL,
82 CMDID_BBREGWRITE10,
83 CMDID_WRITEPORT_ULONG,
84 CMDID_WRITEPORT_USHORT,
85 CMDID_WRITEPORT_UCHAR,
86 CMDID_RF_WRITEREG,
87};
88
89struct swchnlcmd {
90 enum swchnlcmd_id cmdid;
91 u32 para1;
92 u32 para2;
93 u32 msdelay;
94};
95
96enum hw90_block_e {
97 HW90_BLOCK_MAC = 0,
98 HW90_BLOCK_PHY0 = 1,
99 HW90_BLOCK_PHY1 = 2,
100 HW90_BLOCK_RF = 3,
101 HW90_BLOCK_MAXIMUM = 4,
102};
103
104enum baseband_config_type {
105 BASEBAND_CONFIG_PHY_REG = 0,
106 BASEBAND_CONFIG_AGC_TAB = 1,
107};
108
109enum ra_offset_area {
110 RA_OFFSET_LEGACY_OFDM1,
111 RA_OFFSET_LEGACY_OFDM2,
112 RA_OFFSET_HT_OFDM1,
113 RA_OFFSET_HT_OFDM2,
114 RA_OFFSET_HT_OFDM3,
115 RA_OFFSET_HT_OFDM4,
116 RA_OFFSET_HT_CCK,
117};
118
119enum antenna_path {
120 ANTENNA_NONE,
121 ANTENNA_D,
122 ANTENNA_C,
123 ANTENNA_CD,
124 ANTENNA_B,
125 ANTENNA_BD,
126 ANTENNA_BC,
127 ANTENNA_BCD,
128 ANTENNA_A,
129 ANTENNA_AD,
130 ANTENNA_AC,
131 ANTENNA_ACD,
132 ANTENNA_AB,
133 ANTENNA_ABD,
134 ANTENNA_ABC,
135 ANTENNA_ABCD
136};
137
138struct r_antenna_select_ofdm {
139 u32 r_tx_antenna:4;
140 u32 r_ant_l:4;
141 u32 r_ant_non_ht:4;
142 u32 r_ant_ht1:4;
143 u32 r_ant_ht2:4;
144 u32 r_ant_ht_s1:4;
145 u32 r_ant_non_ht_s1:4;
146 u32 ofdm_txsc:2;
147 u32 reserved:2;
148};
149
150struct r_antenna_select_cck {
151 u8 r_cckrx_enable_2:2;
152 u8 r_cckrx_enable:2;
153 u8 r_ccktx_enable:4;
154};
155
156struct efuse_contents {
157 u8 mac_addr[ETH_ALEN];
158 u8 cck_tx_power_idx[6];
159 u8 ht40_1s_tx_power_idx[6];
160 u8 ht40_2s_tx_power_idx_diff[3];
161 u8 ht20_tx_power_idx_diff[3];
162 u8 ofdm_tx_power_idx_diff[3];
163 u8 ht40_max_power_offset[3];
164 u8 ht20_max_power_offset[3];
165 u8 channel_plan;
166 u8 thermal_meter;
167 u8 rf_option[5];
168 u8 version;
169 u8 oem_id;
170 u8 regulatory;
171};
172
173struct tx_power_struct {
174 u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
175 u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
176 u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
177 u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
178 u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
179 u8 legacy_ht_txpowerdiff;
180 u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
181 u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
182 u8 pwrgroup_cnt;
183 u32 mcs_original_offset[4][16];
184};
185
186extern u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw,
187 u32 regaddr, u32 bitmask);
188extern void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw,
189 u32 regaddr, u32 bitmask, u32 data);
190extern u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,
191 enum radio_path rfpath, u32 regaddr,
192 u32 bitmask);
193extern void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw,
194 enum radio_path rfpath, u32 regaddr,
195 u32 bitmask, u32 data);
196extern bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw);
197extern bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw);
198extern bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw);
199extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
200 enum radio_path rfpath);
201extern void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
202extern void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw,
203 long *powerlevel);
204extern void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw,
205 u8 channel);
206extern bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw,
207 long power_indbm);
208extern void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw,
209 u8 operation);
210extern void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
211extern void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw,
212 enum nl80211_channel_type ch_type);
213extern void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw);
214extern u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw);
215extern void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);
216void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw);
217void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
218bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
219 enum radio_path rfpath);
220bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
221extern bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
222 enum rf_pwrstate rfpwr_state);
223
224#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c
new file mode 100644
index 000000000000..df6ca9a57f7f
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c
@@ -0,0 +1,109 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 "pwrseqcmd.h"
31#include "pwrseq.h"
32
33/* drivers should parse arrays below and do the corresponding actions */
34
35/*3 Power on Array*/
36struct wlan_pwr_cfg rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STPS
37 + RTL8723A_TRANS_END_STPS] = {
38 RTL8723A_TRANS_CARDEMU_TO_ACT,
39 RTL8723A_TRANS_END
40};
41
42/*3Radio off GPIO Array */
43struct wlan_pwr_cfg rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
44 + RTL8723A_TRANS_END_STPS] = {
45 RTL8723A_TRANS_ACT_TO_CARDEMU,
46 RTL8723A_TRANS_END
47};
48
49/*3Card Disable Array*/
50struct wlan_pwr_cfg
51rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
52 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
53 + RTL8723A_TRANS_END_STPS] = {
54 RTL8723A_TRANS_ACT_TO_CARDEMU,
55 RTL8723A_TRANS_CARDEMU_TO_CARDDIS,
56 RTL8723A_TRANS_END
57};
58
59/*3 Card Enable Array*/
60struct wlan_pwr_cfg rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
61 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
62 + RTL8723A_TRANS_END_STPS] = {
63 RTL8723A_TRANS_CARDDIS_TO_CARDEMU,
64 RTL8723A_TRANS_CARDEMU_TO_ACT,
65 RTL8723A_TRANS_END
66};
67
68/*3Suspend Array*/
69struct wlan_pwr_cfg rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
70 + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS
71 + RTL8723A_TRANS_END_STPS] = {
72 RTL8723A_TRANS_ACT_TO_CARDEMU,
73 RTL8723A_TRANS_CARDEMU_TO_SUS,
74 RTL8723A_TRANS_END
75};
76
77/*3 Resume Array*/
78struct wlan_pwr_cfg rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
79 + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS
80 + RTL8723A_TRANS_END_STPS] = {
81 RTL8723A_TRANS_SUS_TO_CARDEMU,
82 RTL8723A_TRANS_CARDEMU_TO_ACT,
83 RTL8723A_TRANS_END
84};
85
86/*3HWPDN Array*/
87struct wlan_pwr_cfg rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
88 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
89 + RTL8723A_TRANS_END_STPS] = {
90 RTL8723A_TRANS_ACT_TO_CARDEMU,
91 RTL8723A_TRANS_CARDEMU_TO_PDN,
92 RTL8723A_TRANS_END
93};
94
95/*3 Enter LPS */
96struct wlan_pwr_cfg rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STPS
97 + RTL8723A_TRANS_END_STPS] = {
98 /*FW behavior*/
99 RTL8723A_TRANS_ACT_TO_LPS,
100 RTL8723A_TRANS_END
101};
102
103/*3 Leave LPS */
104struct wlan_pwr_cfg rtl8723A_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STPS
105 + RTL8723A_TRANS_END_STPS] = {
106 /*FW behavior*/
107 RTL8723A_TRANS_LPS_TO_ACT,
108 RTL8723A_TRANS_END
109};
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h
new file mode 100644
index 000000000000..7a46f9fdf558
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h
@@ -0,0 +1,322 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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#ifndef __RTL8723E_PWRSEQ_H__
31#define __RTL8723E_PWRSEQ_H__
32
33#include "pwrseqcmd.h"
34/*
35 Check document WM-20110607-Paul-RTL8723A_Power_Architecture-R02.vsd
36 There are 6 HW Power States:
37 0: POFF--Power Off
38 1: PDN--Power Down
39 2: CARDEMU--Card Emulation
40 3: ACT--Active Mode
41 4: LPS--Low Power State
42 5: SUS--Suspend
43
44 The transision from different states are defined below
45 TRANS_CARDEMU_TO_ACT
46 TRANS_ACT_TO_CARDEMU
47 TRANS_CARDEMU_TO_SUS
48 TRANS_SUS_TO_CARDEMU
49 TRANS_CARDEMU_TO_PDN
50 TRANS_ACT_TO_LPS
51 TRANS_LPS_TO_ACT
52
53 TRANS_END
54*/
55
56#define RTL8723A_TRANS_CARDEMU_TO_ACT_STPS 10
57#define RTL8723A_TRANS_ACT_TO_CARDEMU_STPS 10
58#define RTL8723A_TRANS_CARDEMU_TO_SUS_STPS 10
59#define RTL8723A_TRANS_SUS_TO_CARDEMU_STPS 10
60#define RTL8723A_TRANS_CARDEMU_TO_PDN_STPS 10
61#define RTL8723A_TRANS_PDN_TO_CARDEMU_STPS 10
62#define RTL8723A_TRANS_ACT_TO_LPS_STPS 15
63#define RTL8723A_TRANS_LPS_TO_ACT_STPS 15
64#define RTL8723A_TRANS_END_STPS 1
65
66
67#define RTL8723A_TRANS_CARDEMU_TO_ACT \
68 /* format */ \
69 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \
70 * comments here*/ \
71 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
72 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), 0}, \
73 /* disable SW LPS 0x04[10]=0*/ \
74 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
75 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
76 /* wait till 0x04[17] = 1 power ready*/ \
77 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
78 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
79 /* release WLON reset 0x04[16]=1*/ \
80 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
81 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \
82 /* disable HWPDN 0x04[15]=0*/ \
83 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
84 PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0}, \
85 /* disable WL suspend*/ \
86 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
87 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
88 /* polling until return 0*/ \
89 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
90 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0}
91
92#define RTL8723A_TRANS_ACT_TO_CARDEMU \
93 /* format */ \
94 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \
95 * comments here*/ \
96 {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
97 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, \
98 /*0x1F[7:0] = 0 turn off RF*/ \
99 {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
100 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \
101 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
102 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
103 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
104 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}
105
106#define RTL8723A_TRANS_CARDEMU_TO_SUS \
107 /* format */ \
108 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \
109 * comments here*/ \
110 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
111 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), \
112 (BIT(4)|BIT(3))}, \
113 /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \
114 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK | \
115 PWR_INTF_SDIO_MSK, \
116 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)},\
117 /*0x04[12:11] = 2b'01 enable WL suspend*/ \
118 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
119 PWR_BASEADDR_MAC, \
120 PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4)}, \
121 /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \
122 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
123 PWR_BASEADDR_SDIO, \
124 PWR_CMD_WRITE, BIT(0), BIT(0)}, \
125 /*Set SDIO suspend local register*/ \
126 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
127 PWR_BASEADDR_SDIO, \
128 PWR_CMD_POLLING, BIT(1), 0} \
129 /*wait power state to suspend*/
130
131#define RTL8723A_TRANS_SUS_TO_CARDEMU \
132 /* format */ \
133 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
134 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
135 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \
136 /*Set SDIO suspend local register*/ \
137 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
138 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
139 /*wait power state to suspend*/ \
140 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
141 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0} \
142 /*0x04[12:11] = 2b'01enable WL suspend*/
143
144#define RTL8723A_TRANS_CARDEMU_TO_CARDDIS \
145 /* format */ \
146 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
147 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
148 PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
149 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)},\
150 /*0x04[12:11] = 2b'01 enable WL suspend*/ \
151 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
152 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), BIT(2)}, \
153 /*0x04[10] = 1, enable SW LPS*/ \
154 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
155 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
156 /*Set SDIO suspend local register*/ \
157 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
158 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0} \
159 /*wait power state to suspend*/
160
161#define RTL8723A_TRANS_CARDDIS_TO_CARDEMU \
162 /* format */ \
163 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
164 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
165 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \
166 /*Set SDIO suspend local register*/ \
167 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
168 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
169 /*wait power state to suspend*/ \
170 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
171 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, \
172 /*0x04[12:11] = 2b'00enable WL suspend*/ \
173 {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
174 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0} \
175 /*PCIe DMA start*/
176
177#define RTL8723A_TRANS_CARDEMU_TO_PDN \
178 /* format */ \
179 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
180 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
181 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
182 /* 0x04[16] = 0*/\
183 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
184 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)} \
185 /* 0x04[15] = 1*/
186
187#define RTL8723A_TRANS_PDN_TO_CARDEMU \
188 /* format */ \
189 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
190 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
191 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0} \
192 /* 0x04[15] = 0*/
193
194#define RTL8723A_TRANS_ACT_TO_LPS \
195 /* format */ \
196 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
197 {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
198 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \
199 /*PCIe DMA stop*/ \
200 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
201 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F}, \
202 /*Tx Pause*/ \
203 {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
204 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
205 /*Should be zero if no packet is transmitting*/ \
206 {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
207 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
208 /*Should be zero if no packet is transmitting*/ \
209 {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
210 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
211 /*Should be zero if no packet is transmitting*/ \
212 {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
213 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
214 /*Should be zero if no packet is transmitting*/ \
215 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
216 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
217 /*CCK and OFDM are disabled,and clock are gated*/ \
218 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
219 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US}, \
220 /*Delay 1us*/ \
221 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
222 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
223 /*Whole BB is reset*/ \
224 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
225 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3F}, \
226 /*Reset MAC TRX*/ \
227 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
228 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
229 /*check if removed later*/ \
230 {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
231 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)} \
232 /*Respond TxOK to scheduler*/
233
234#define RTL8723A_TRANS_LPS_TO_ACT \
235 /* format */ \
236 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
237 {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
238 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, \
239 /*SDIO RPWM*/ \
240 {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
241 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \
242 /*USB RPWM*/ \
243 {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
244 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \
245 /*PCIe RPWM*/ \
246 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
247 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, \
248 /*Delay*/ \
249 {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
250 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
251 /* 0x08[4] = 0 switch TSF to 40M*/ \
252 {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
253 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, \
254 /*Polling 0x109[7]=0 TSF in 40M*/ \
255 {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
256 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, \
257 /*. 0x29[7:6] = 2b'00 enable BB clock*/ \
258 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
259 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
260 /*. 0x101[1] = 1*/ \
261 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
262 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \
263 /* 0x100[7:0] = 0xFF enable WMAC TRX*/ \
264 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
265 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1)|BIT(0), \
266 BIT(1)|BIT(0)}, \
267 /* 0x02[1:0] = 2b'11 enable BB macro*/ \
268 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
269 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0} \
270 /*. 0x522 = 0*/
271
272#define RTL8723A_TRANS_END \
273 /* format */ \
274 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
275 {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
276 0, PWR_CMD_END, 0, 0}
277
278extern struct
279wlan_pwr_cfg rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STPS
280 + RTL8723A_TRANS_END_STPS];
281extern struct
282wlan_pwr_cfg rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
283 + RTL8723A_TRANS_END_STPS];
284extern struct
285wlan_pwr_cfg rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
286 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
287 + RTL8723A_TRANS_END_STPS];
288extern struct
289wlan_pwr_cfg rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
290 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
291 + RTL8723A_TRANS_END_STPS];
292extern struct
293wlan_pwr_cfg rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
294 + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS
295 + RTL8723A_TRANS_END_STPS];
296extern struct
297wlan_pwr_cfg rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
298 + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS
299 + RTL8723A_TRANS_END_STPS];
300extern struct
301wlan_pwr_cfg rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
302 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
303 + RTL8723A_TRANS_END_STPS];
304extern struct
305wlan_pwr_cfg rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STPS
306 + RTL8723A_TRANS_END_STPS];
307extern struct
308wlan_pwr_cfg rtl8723A_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STPS
309 + RTL8723A_TRANS_END_STPS];
310
311/* RTL8723 Power Configuration CMDs for PCIe interface */
312#define Rtl8723_NIC_PWR_ON_FLOW rtl8723A_power_on_flow
313#define Rtl8723_NIC_RF_OFF_FLOW rtl8723A_radio_off_flow
314#define Rtl8723_NIC_DISABLE_FLOW rtl8723A_card_disable_flow
315#define Rtl8723_NIC_ENABLE_FLOW rtl8723A_card_enable_flow
316#define Rtl8723_NIC_SUSPEND_FLOW rtl8723A_suspend_flow
317#define Rtl8723_NIC_RESUME_FLOW rtl8723A_resume_flow
318#define Rtl8723_NIC_PDN_FLOW rtl8723A_hwpdn_flow
319#define Rtl8723_NIC_LPS_ENTER_FLOW rtl8723A_enter_lps_flow
320#define Rtl8723_NIC_LPS_LEAVE_FLOW rtl8723A_leave_lps_flow
321
322#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c
new file mode 100644
index 000000000000..2044b5936b7f
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c
@@ -0,0 +1,129 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 "pwrseq.h"
31
32/* Description:
33 * This routine deals with the Power Configuration CMD
34 * parsing for RTL8723/RTL8188E Series IC.
35 * Assumption:
36 * We should follow specific format that was released from HW SD.
37 */
38bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
39 u8 faversion, u8 interface_type,
40 struct wlan_pwr_cfg pwrcfgcmd[])
41{
42 struct wlan_pwr_cfg cfg_cmd = {0};
43 bool polling_bit = false;
44 u32 ary_idx = 0;
45 u8 value = 0;
46 u32 offset = 0;
47 u32 polling_count = 0;
48 u32 max_polling_cnt = 5000;
49
50 do {
51 cfg_cmd = pwrcfgcmd[ary_idx];
52 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
53 "rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), famsk(%#x),"
54 "interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n",
55 GET_PWR_CFG_OFFSET(cfg_cmd),
56 GET_PWR_CFG_CUT_MASK(cfg_cmd),
57 GET_PWR_CFG_FAB_MASK(cfg_cmd),
58 GET_PWR_CFG_INTF_MASK(cfg_cmd),
59 GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd),
60 GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd));
61
62 if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) &&
63 (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) &&
64 (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) {
65 switch (GET_PWR_CFG_CMD(cfg_cmd)) {
66 case PWR_CMD_READ:
67 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
68 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n");
69 break;
70 case PWR_CMD_WRITE:
71 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
72 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n");
73 offset = GET_PWR_CFG_OFFSET(cfg_cmd);
74
75 /*Read the value from system register*/
76 value = rtl_read_byte(rtlpriv, offset);
77 value &= (~(GET_PWR_CFG_MASK(cfg_cmd)));
78 value |= (GET_PWR_CFG_VALUE(cfg_cmd) &
79 GET_PWR_CFG_MASK(cfg_cmd));
80
81 /*Write the value back to sytem register*/
82 rtl_write_byte(rtlpriv, offset, value);
83 break;
84 case PWR_CMD_POLLING:
85 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
86 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n");
87 polling_bit = false;
88 offset = GET_PWR_CFG_OFFSET(cfg_cmd);
89
90 do {
91 value = rtl_read_byte(rtlpriv, offset);
92
93 value &= GET_PWR_CFG_MASK(cfg_cmd);
94 if (value ==
95 (GET_PWR_CFG_VALUE(cfg_cmd)
96 & GET_PWR_CFG_MASK(cfg_cmd)))
97 polling_bit = true;
98 else
99 udelay(10);
100
101 if (polling_count++ > max_polling_cnt)
102 return false;
103 } while (!polling_bit);
104 break;
105 case PWR_CMD_DELAY:
106 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
107 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n");
108 if (GET_PWR_CFG_VALUE(cfg_cmd) ==
109 PWRSEQ_DELAY_US)
110 udelay(GET_PWR_CFG_OFFSET(cfg_cmd));
111 else
112 mdelay(GET_PWR_CFG_OFFSET(cfg_cmd));
113 break;
114 case PWR_CMD_END:
115 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
116 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n");
117 return true;
118 default:
119 RT_ASSERT(false,
120 "rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n");
121 break;
122 }
123
124 }
125 ary_idx++;
126 } while (1);
127
128 return true;
129}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h
new file mode 100644
index 000000000000..6e0f3ea37ec0
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h
@@ -0,0 +1,98 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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#ifndef __RTL8723E_PWRSEQCMD_H__
31#define __RTL8723E_PWRSEQCMD_H__
32
33#include "../wifi.h"
34/*---------------------------------------------
35 * 3 The value of cmd: 4 bits
36 *---------------------------------------------
37 */
38#define PWR_CMD_READ 0x00
39#define PWR_CMD_WRITE 0x01
40#define PWR_CMD_POLLING 0x02
41#define PWR_CMD_DELAY 0x03
42#define PWR_CMD_END 0x04
43
44/* define the base address of each block */
45#define PWR_BASEADDR_MAC 0x00
46#define PWR_BASEADDR_USB 0x01
47#define PWR_BASEADDR_PCIE 0x02
48#define PWR_BASEADDR_SDIO 0x03
49
50#define PWR_INTF_SDIO_MSK BIT(0)
51#define PWR_INTF_USB_MSK BIT(1)
52#define PWR_INTF_PCI_MSK BIT(2)
53#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
54
55#define PWR_FAB_TSMC_MSK BIT(0)
56#define PWR_FAB_UMC_MSK BIT(1)
57#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
58
59#define PWR_CUT_TESTCHIP_MSK BIT(0)
60#define PWR_CUT_A_MSK BIT(1)
61#define PWR_CUT_B_MSK BIT(2)
62#define PWR_CUT_C_MSK BIT(3)
63#define PWR_CUT_D_MSK BIT(4)
64#define PWR_CUT_E_MSK BIT(5)
65#define PWR_CUT_F_MSK BIT(6)
66#define PWR_CUT_G_MSK BIT(7)
67#define PWR_CUT_ALL_MSK 0xFF
68
69enum pwrseq_delay_unit {
70 PWRSEQ_DELAY_US,
71 PWRSEQ_DELAY_MS,
72};
73
74struct wlan_pwr_cfg {
75 u16 offset;
76 u8 cut_msk;
77 u8 fab_msk:4;
78 u8 interface_msk:4;
79 u8 base:4;
80 u8 cmd:4;
81 u8 msk;
82 u8 value;
83};
84
85#define GET_PWR_CFG_OFFSET(__PWR_CMD) (__PWR_CMD.offset)
86#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) (__PWR_CMD.cut_msk)
87#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) (__PWR_CMD.fab_msk)
88#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) (__PWR_CMD.interface_msk)
89#define GET_PWR_CFG_BASE(__PWR_CMD) (__PWR_CMD.base)
90#define GET_PWR_CFG_CMD(__PWR_CMD) (__PWR_CMD.cmd)
91#define GET_PWR_CFG_MASK(__PWR_CMD) (__PWR_CMD.msk)
92#define GET_PWR_CFG_VALUE(__PWR_CMD) (__PWR_CMD.value)
93
94bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
95 u8 fab_version, u8 interface_type,
96 struct wlan_pwr_cfg pwrcfgcmd[]);
97
98#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
new file mode 100644
index 000000000000..199da366c6da
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
@@ -0,0 +1,2097 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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#ifndef __RTL8723E_REG_H__
31#define __RTL8723E_REG_H__
32
33#define REG_SYS_ISO_CTRL 0x0000
34#define REG_SYS_FUNC_EN 0x0002
35#define REG_APS_FSMCO 0x0004
36#define REG_SYS_CLKR 0x0008
37#define REG_9346CR 0x000A
38#define REG_EE_VPD 0x000C
39#define REG_AFE_MISC 0x0010
40#define REG_SPS0_CTRL 0x0011
41#define REG_SPS_OCP_CFG 0x0018
42#define REG_RSV_CTRL 0x001C
43#define REG_RF_CTRL 0x001F
44#define REG_LDOA15_CTRL 0x0020
45#define REG_LDOV12D_CTRL 0x0021
46#define REG_LDOHCI12_CTRL 0x0022
47#define REG_LPLDO_CTRL 0x0023
48#define REG_AFE_XTAL_CTRL 0x0024
49#define REG_AFE_PLL_CTRL 0x0028
50#define REG_EFUSE_CTRL 0x0030
51#define REG_EFUSE_TEST 0x0034
52#define REG_PWR_DATA 0x0038
53#define REG_CAL_TIMER 0x003C
54#define REG_ACLK_MON 0x003E
55#define REG_GPIO_MUXCFG 0x0040
56#define REG_GPIO_IO_SEL 0x0042
57#define REG_MAC_PINMUX_CFG 0x0043
58#define REG_GPIO_PIN_CTRL 0x0044
59#define REG_GPIO_INTM 0x0048
60#define REG_LEDCFG0 0x004C
61#define REG_LEDCFG1 0x004D
62#define REG_LEDCFG2 0x004E
63#define REG_LEDCFG3 0x004F
64#define REG_FSIMR 0x0050
65#define REG_FSISR 0x0054
66#define REG_GPIO_PIN_CTRL_2 0x0060
67#define REG_GPIO_IO_SEL_2 0x0062
68#define REG_MULTI_FUNC_CTRL 0x0068
69
70#define REG_MCUFWDL 0x0080
71
72#define REG_HMEBOX_EXT_0 0x0088
73#define REG_HMEBOX_EXT_1 0x008A
74#define REG_HMEBOX_EXT_2 0x008C
75#define REG_HMEBOX_EXT_3 0x008E
76
77#define REG_BIST_SCAN 0x00D0
78#define REG_BIST_RPT 0x00D4
79#define REG_BIST_ROM_RPT 0x00D8
80#define REG_USB_SIE_INTF 0x00E0
81#define REG_PCIE_MIO_INTF 0x00E4
82#define REG_PCIE_MIO_INTD 0x00E8
83#define REG_SYS_CFG 0x00F0
84#define REG_GPIO_OUTSTS 0x00F4
85
86#define REG_CR 0x0100
87#define REG_PBP 0x0104
88#define REG_TRXDMA_CTRL 0x010C
89#define REG_TRXFF_BNDY 0x0114
90#define REG_TRXFF_STATUS 0x0118
91#define REG_RXFF_PTR 0x011C
92#define REG_HIMR 0x0120
93#define REG_HISR 0x0124
94#define REG_HIMRE 0x0128
95#define REG_HISRE 0x012C
96#define REG_CPWM 0x012F
97#define REG_FWIMR 0x0130
98#define REG_FWISR 0x0134
99#define REG_PKTBUF_DBG_CTRL 0x0140
100#define REG_PKTBUF_DBG_DATA_L 0x0144
101#define REG_PKTBUF_DBG_DATA_H 0x0148
102
103#define REG_TC0_CTRL 0x0150
104#define REG_TC1_CTRL 0x0154
105#define REG_TC2_CTRL 0x0158
106#define REG_TC3_CTRL 0x015C
107#define REG_TC4_CTRL 0x0160
108#define REG_TCUNIT_BASE 0x0164
109#define REG_MBIST_START 0x0174
110#define REG_MBIST_DONE 0x0178
111#define REG_MBIST_FAIL 0x017C
112#define REG_C2HEVT_MSG_NORMAL 0x01A0
113#define REG_C2HEVT_MSG_TEST 0x01B8
114#define REG_MCUTST_1 0x01c0
115#define REG_FMETHR 0x01C8
116#define REG_HMETFR 0x01CC
117#define REG_HMEBOX_0 0x01D0
118#define REG_HMEBOX_1 0x01D4
119#define REG_HMEBOX_2 0x01D8
120#define REG_HMEBOX_3 0x01DC
121
122#define REG_LLT_INIT 0x01E0
123#define REG_BB_ACCEESS_CTRL 0x01E8
124#define REG_BB_ACCESS_DATA 0x01EC
125
126#define REG_RQPN 0x0200
127#define REG_FIFOPAGE 0x0204
128#define REG_TDECTRL 0x0208
129#define REG_TXDMA_OFFSET_CHK 0x020C
130#define REG_TXDMA_STATUS 0x0210
131#define REG_RQPN_NPQ 0x0214
132
133#define REG_RXDMA_AGG_PG_TH 0x0280
134#define REG_RXPKT_NUM 0x0284
135#define REG_RXDMA_STATUS 0x0288
136
137#define REG_PCIE_CTRL_REG 0x0300
138#define REG_INT_MIG 0x0304
139#define REG_BCNQ_DESA 0x0308
140#define REG_HQ_DESA 0x0310
141#define REG_MGQ_DESA 0x0318
142#define REG_VOQ_DESA 0x0320
143#define REG_VIQ_DESA 0x0328
144#define REG_BEQ_DESA 0x0330
145#define REG_BKQ_DESA 0x0338
146#define REG_RX_DESA 0x0340
147#define REG_DBI 0x0348
148#define REG_MDIO 0x0354
149#define REG_DBG_SEL 0x0360
150#define REG_PCIE_HRPWM 0x0361
151#define REG_PCIE_HCPWM 0x0363
152#define REG_UART_CTRL 0x0364
153#define REG_UART_TX_DESA 0x0370
154#define REG_UART_RX_DESA 0x0378
155
156#define REG_HDAQ_DESA_NODEF 0x0000
157#define REG_CMDQ_DESA_NODEF 0x0000
158
159#define REG_VOQ_INFORMATION 0x0400
160#define REG_VIQ_INFORMATION 0x0404
161#define REG_BEQ_INFORMATION 0x0408
162#define REG_BKQ_INFORMATION 0x040C
163#define REG_MGQ_INFORMATION 0x0410
164#define REG_HGQ_INFORMATION 0x0414
165#define REG_BCNQ_INFORMATION 0x0418
166
167#define REG_CPU_MGQ_INFORMATION 0x041C
168#define REG_FWHW_TXQ_CTRL 0x0420
169#define REG_HWSEQ_CTRL 0x0423
170#define REG_TXPKTBUF_BCNQ_BDNY 0x0424
171#define REG_TXPKTBUF_MGQ_BDNY 0x0425
172#define REG_MULTI_BCNQ_EN 0x0426
173#define REG_MULTI_BCNQ_OFFSET 0x0427
174#define REG_SPEC_SIFS 0x0428
175#define REG_RL 0x042A
176#define REG_DARFRC 0x0430
177#define REG_RARFRC 0x0438
178#define REG_RRSR 0x0440
179#define REG_ARFR0 0x0444
180#define REG_ARFR1 0x0448
181#define REG_ARFR2 0x044C
182#define REG_ARFR3 0x0450
183#define REG_AGGLEN_LMT 0x0458
184#define REG_AMPDU_MIN_SPACE 0x045C
185#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D
186#define REG_FAST_EDCA_CTRL 0x0460
187#define REG_RD_RESP_PKT_TH 0x0463
188#define REG_INIRTS_RATE_SEL 0x0480
189#define REG_INIDATA_RATE_SEL 0x0484
190#define REG_POWER_STATUS 0x04A4
191#define REG_POWER_STAGE1 0x04B4
192#define REG_POWER_STAGE2 0x04B8
193#define REG_PKT_LIFE_TIME 0x04C0
194#define REG_STBC_SETTING 0x04C4
195#define REG_PROT_MODE_CTRL 0x04C8
196#define REG_BAR_MODE_CTRL 0x04CC
197#define REG_RA_TRY_RATE_AGG_LMT 0x04CF
198#define REG_NQOS_SEQ 0x04DC
199#define REG_QOS_SEQ 0x04DE
200#define REG_NEED_CPU_HANDLE 0x04E0
201#define REG_PKT_LOSE_RPT 0x04E1
202#define REG_PTCL_ERR_STATUS 0x04E2
203#define REG_DUMMY 0x04FC
204
205#define REG_EDCA_VO_PARAM 0x0500
206#define REG_EDCA_VI_PARAM 0x0504
207#define REG_EDCA_BE_PARAM 0x0508
208#define REG_EDCA_BK_PARAM 0x050C
209#define REG_BCNTCFG 0x0510
210#define REG_PIFS 0x0512
211#define REG_RDG_PIFS 0x0513
212#define REG_SIFS_CTX 0x0514
213#define REG_SIFS_TRX 0x0516
214#define REG_AGGR_BREAK_TIME 0x051A
215#define REG_SLOT 0x051B
216#define REG_TX_PTCL_CTRL 0x0520
217#define REG_TXPAUSE 0x0522
218#define REG_DIS_TXREQ_CLR 0x0523
219#define REG_RD_CTRL 0x0524
220#define REG_TBTT_PROHIBIT 0x0540
221#define REG_RD_NAV_NXT 0x0544
222#define REG_NAV_PROT_LEN 0x0546
223#define REG_BCN_CTRL 0x0550
224#define REG_USTIME_TSF 0x0551
225#define REG_MBID_NUM 0x0552
226#define REG_DUAL_TSF_RST 0x0553
227#define REG_BCN_INTERVAL 0x0554
228#define REG_MBSSID_BCN_SPACE 0x0554
229#define REG_DRVERLYINT 0x0558
230#define REG_BCNDMATIM 0x0559
231#define REG_ATIMWND 0x055A
232#define REG_BCN_MAX_ERR 0x055D
233#define REG_RXTSF_OFFSET_CCK 0x055E
234#define REG_RXTSF_OFFSET_OFDM 0x055F
235#define REG_TSFTR 0x0560
236#define REG_INIT_TSFTR 0x0564
237#define REG_PSTIMER 0x0580
238#define REG_TIMER0 0x0584
239#define REG_TIMER1 0x0588
240#define REG_ACMHWCTRL 0x05C0
241#define REG_ACMRSTCTRL 0x05C1
242#define REG_ACMAVG 0x05C2
243#define REG_VO_ADMTIME 0x05C4
244#define REG_VI_ADMTIME 0x05C6
245#define REG_BE_ADMTIME 0x05C8
246#define REG_EDCA_RANDOM_GEN 0x05CC
247#define REG_SCH_TXCMD 0x05D0
248
249#define REG_APSD_CTRL 0x0600
250#define REG_BWOPMODE 0x0603
251#define REG_TCR 0x0604
252#define REG_RCR 0x0608
253#define REG_RX_PKT_LIMIT 0x060C
254#define REG_RX_DLK_TIME 0x060D
255#define REG_RX_DRVINFO_SZ 0x060F
256
257#define REG_MACID 0x0610
258#define REG_BSSID 0x0618
259#define REG_MAR 0x0620
260#define REG_MBIDCAMCFG 0x0628
261
262#define REG_USTIME_EDCA 0x0638
263#define REG_MAC_SPEC_SIFS 0x063A
264#define REG_RESP_SIFS_CCK 0x063C
265#define REG_RESP_SIFS_OFDM 0x063E
266#define REG_ACKTO 0x0640
267#define REG_CTS2TO 0x0641
268#define REG_EIFS 0x0642
269
270#define REG_NAV_CTRL 0x0650
271#define REG_BACAMCMD 0x0654
272#define REG_BACAMCONTENT 0x0658
273#define REG_LBDLY 0x0660
274#define REG_FWDLY 0x0661
275#define REG_RXERR_RPT 0x0664
276#define REG_WMAC_TRXPTCL_CTL 0x0668
277
278#define REG_CAMCMD 0x0670
279#define REG_CAMWRITE 0x0674
280#define REG_CAMREAD 0x0678
281#define REG_CAMDBG 0x067C
282#define REG_SECCFG 0x0680
283
284#define REG_WOW_CTRL 0x0690
285#define REG_PSSTATUS 0x0691
286#define REG_PS_RX_INFO 0x0692
287#define REG_LPNAV_CTRL 0x0694
288#define REG_WKFMCAM_CMD 0x0698
289#define REG_WKFMCAM_RWD 0x069C
290#define REG_RXFLTMAP0 0x06A0
291#define REG_RXFLTMAP1 0x06A2
292#define REG_RXFLTMAP2 0x06A4
293#define REG_BCN_PSR_RPT 0x06A8
294#define REG_CALB32K_CTRL 0x06AC
295#define REG_PKT_MON_CTRL 0x06B4
296#define REG_BT_COEX_TABLE 0x06C0
297#define REG_WMAC_RESP_TXINFO 0x06D8
298
299#define REG_USB_INFO 0xFE17
300#define REG_USB_SPECIAL_OPTION 0xFE55
301#define REG_USB_DMA_AGG_TO 0xFE5B
302#define REG_USB_AGG_TO 0xFE5C
303#define REG_USB_AGG_TH 0xFE5D
304
305#define REG_TEST_USB_TXQS 0xFE48
306#define REG_TEST_SIE_VID 0xFE60
307#define REG_TEST_SIE_PID 0xFE62
308#define REG_TEST_SIE_OPTIONAL 0xFE64
309#define REG_TEST_SIE_CHIRP_K 0xFE65
310#define REG_TEST_SIE_PHY 0xFE66
311#define REG_TEST_SIE_MAC_ADDR 0xFE70
312#define REG_TEST_SIE_STRING 0xFE80
313
314#define REG_NORMAL_SIE_VID 0xFE60
315#define REG_NORMAL_SIE_PID 0xFE62
316#define REG_NORMAL_SIE_OPTIONAL 0xFE64
317#define REG_NORMAL_SIE_EP 0xFE65
318#define REG_NORMAL_SIE_PHY 0xFE68
319#define REG_NORMAL_SIE_MAC_ADDR 0xFE70
320#define REG_NORMAL_SIE_STRING 0xFE80
321
322#define CR9346 REG_9346CR
323#define MSR (REG_CR + 2)
324#define ISR REG_HISR
325#define TSFR REG_TSFTR
326
327#define MACIDR0 REG_MACID
328#define MACIDR4 (REG_MACID + 4)
329
330#define PBP REG_PBP
331
332#define IDR0 MACIDR0
333#define IDR4 MACIDR4
334
335#define UNUSED_REGISTER 0x1BF
336#define DCAM UNUSED_REGISTER
337#define PSR UNUSED_REGISTER
338#define BBADDR UNUSED_REGISTER
339#define PHYDATAR UNUSED_REGISTER
340
341#define INVALID_BBRF_VALUE 0x12345678
342
343#define MAX_MSS_DENSITY_2T 0x13
344#define MAX_MSS_DENSITY_1T 0x0A
345
346#define CMDEEPROM_EN BIT(5)
347#define CMDEEPROM_SEL BIT(4)
348#define CMD9346CR_9356SEL BIT(4)
349#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL)
350#define AUTOLOAD_EFUSE CMDEEPROM_EN
351
352#define GPIOSEL_GPIO 0
353#define GPIOSEL_ENBT BIT(5)
354
355#define GPIO_IN REG_GPIO_PIN_CTRL
356#define GPIO_OUT (REG_GPIO_PIN_CTRL+1)
357#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2)
358#define GPIO_MOD (REG_GPIO_PIN_CTRL+3)
359
360#define MSR_NOLINK 0x00
361#define MSR_ADHOC 0x01
362#define MSR_INFRA 0x02
363#define MSR_AP 0x03
364
365#define RRSR_RSC_OFFSET 21
366#define RRSR_SHORT_OFFSET 23
367#define RRSR_RSC_BW_40M 0x600000
368#define RRSR_RSC_UPSUBCHNL 0x400000
369#define RRSR_RSC_LOWSUBCHNL 0x200000
370#define RRSR_SHORT 0x800000
371#define RRSR_1M BIT(0)
372#define RRSR_2M BIT(1)
373#define RRSR_5_5M BIT(2)
374#define RRSR_11M BIT(3)
375#define RRSR_6M BIT(4)
376#define RRSR_9M BIT(5)
377#define RRSR_12M BIT(6)
378#define RRSR_18M BIT(7)
379#define RRSR_24M BIT(8)
380#define RRSR_36M BIT(9)
381#define RRSR_48M BIT(10)
382#define RRSR_54M BIT(11)
383#define RRSR_MCS0 BIT(12)
384#define RRSR_MCS1 BIT(13)
385#define RRSR_MCS2 BIT(14)
386#define RRSR_MCS3 BIT(15)
387#define RRSR_MCS4 BIT(16)
388#define RRSR_MCS5 BIT(17)
389#define RRSR_MCS6 BIT(18)
390#define RRSR_MCS7 BIT(19)
391#define BRSR_ACKSHORTPMB BIT(23)
392
393#define RATR_1M 0x00000001
394#define RATR_2M 0x00000002
395#define RATR_55M 0x00000004
396#define RATR_11M 0x00000008
397#define RATR_6M 0x00000010
398#define RATR_9M 0x00000020
399#define RATR_12M 0x00000040
400#define RATR_18M 0x00000080
401#define RATR_24M 0x00000100
402#define RATR_36M 0x00000200
403#define RATR_48M 0x00000400
404#define RATR_54M 0x00000800
405#define RATR_MCS0 0x00001000
406#define RATR_MCS1 0x00002000
407#define RATR_MCS2 0x00004000
408#define RATR_MCS3 0x00008000
409#define RATR_MCS4 0x00010000
410#define RATR_MCS5 0x00020000
411#define RATR_MCS6 0x00040000
412#define RATR_MCS7 0x00080000
413#define RATR_MCS8 0x00100000
414#define RATR_MCS9 0x00200000
415#define RATR_MCS10 0x00400000
416#define RATR_MCS11 0x00800000
417#define RATR_MCS12 0x01000000
418#define RATR_MCS13 0x02000000
419#define RATR_MCS14 0x04000000
420#define RATR_MCS15 0x08000000
421
422#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
423#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\
424 RATR_24M | RATR_36M | RATR_48M | RATR_54M)
425#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\
426 RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\
427 RATR_MCS6 | RATR_MCS7)
428#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\
429 RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\
430 RATR_MCS14 | RATR_MCS15)
431
432#define BW_OPMODE_20MHZ BIT(2)
433#define BW_OPMODE_5G BIT(1)
434#define BW_OPMODE_11J BIT(0)
435
436#define CAM_VALID BIT(15)
437#define CAM_NOTVALID 0x0000
438#define CAM_USEDK BIT(5)
439
440#define CAM_NONE 0x0
441#define CAM_WEP40 0x01
442#define CAM_TKIP 0x02
443#define CAM_AES 0x04
444#define CAM_WEP104 0x05
445
446#define TOTAL_CAM_ENTRY 32
447#define HALF_CAM_ENTRY 16
448
449#define CAM_WRITE BIT(16)
450#define CAM_READ 0x00000000
451#define CAM_POLLINIG BIT(31)
452
453#define SCR_USEDK 0x01
454#define SCR_TXSEC_ENABLE 0x02
455#define SCR_RXSEC_ENABLE 0x04
456
457#define WOW_PMEN BIT(0)
458#define WOW_WOMEN BIT(1)
459#define WOW_MAGIC BIT(2)
460#define WOW_UWF BIT(3)
461
462#define IMR8190_DISABLED 0x0
463#define IMR_BCNDMAINT6 BIT(31)
464#define IMR_BCNDMAINT5 BIT(30)
465#define IMR_BCNDMAINT4 BIT(29)
466#define IMR_BCNDMAINT3 BIT(28)
467#define IMR_BCNDMAINT2 BIT(27)
468#define IMR_BCNDMAINT1 BIT(26)
469#define IMR_BCNDOK8 BIT(25)
470#define IMR_BCNDOK7 BIT(24)
471#define IMR_BCNDOK6 BIT(23)
472#define IMR_BCNDOK5 BIT(22)
473#define IMR_BCNDOK4 BIT(21)
474#define IMR_BCNDOK3 BIT(20)
475#define IMR_BCNDOK2 BIT(19)
476#define IMR_BCNDOK1 BIT(18)
477#define IMR_TIMEOUT2 BIT(17)
478#define IMR_TIMEOUT1 BIT(16)
479#define IMR_TXFOVW BIT(15)
480#define IMR_PSTIMEOUT BIT(14)
481#define IMR_BCNINT BIT(13)
482#define IMR_RXFOVW BIT(12)
483#define IMR_RDU BIT(11)
484#define IMR_ATIMEND BIT(10)
485#define IMR_BDOK BIT(9)
486#define IMR_HIGHDOK BIT(8)
487#define IMR_TBDOK BIT(7)
488#define IMR_MGNTDOK BIT(6)
489#define IMR_TBDER BIT(5)
490#define IMR_BKDOK BIT(4)
491#define IMR_BEDOK BIT(3)
492#define IMR_VIDOK BIT(2)
493#define IMR_VODOK BIT(1)
494#define IMR_ROK BIT(0)
495
496#define IMR_TXERR BIT(11)
497#define IMR_RXERR BIT(10)
498#define IMR_CPWM BIT(8)
499#define IMR_OCPINT BIT(1)
500#define IMR_WLANOFF BIT(0)
501
502/* 8723E series PCIE Host IMR/ISR bit */
503/* IMR DW0 Bit 0-31 */
504#define PHIMR_TIMEOUT2 BIT(31)
505#define PHIMR_TIMEOUT1 BIT(30)
506#define PHIMR_PSTIMEOUT BIT(29)
507#define PHIMR_GTINT4 BIT(28)
508#define PHIMR_GTINT3 BIT(27)
509#define PHIMR_TXBCNERR BIT(26)
510#define PHIMR_TXBCNOK BIT(25)
511#define PHIMR_TSF_BIT32_TOGGLE BIT(24)
512#define PHIMR_BCNDMAINT3 BIT(23)
513#define PHIMR_BCNDMAINT2 BIT(22)
514#define PHIMR_BCNDMAINT1 BIT(21)
515#define PHIMR_BCNDMAINT0 BIT(20)
516#define PHIMR_BCNDOK3 BIT(19)
517#define PHIMR_BCNDOK2 BIT(18)
518#define PHIMR_BCNDOK1 BIT(17)
519#define PHIMR_BCNDOK0 BIT(16)
520#define PHIMR_HSISR_IND_ON BIT(15)
521#define PHIMR_BCNDMAINT_E BIT(14)
522#define PHIMR_ATIMEND_E BIT(13)
523#define PHIMR_ATIM_CTW_END BIT(12)
524#define PHIMR_HISRE_IND BIT(11)
525#define PHIMR_C2HCMD BIT(10)
526#define PHIMR_CPWM2 BIT(9)
527#define PHIMR_CPWM BIT(8)
528#define PHIMR_HIGHDOK BIT(7)
529#define PHIMR_MGNTDOK BIT(6)
530#define PHIMR_BKDOK BIT(5)
531#define PHIMR_BEDOK BIT(4)
532#define PHIMR_VIDOK BIT(3)
533#define PHIMR_VODOK BIT(2)
534#define PHIMR_RDU BIT(1)
535#define PHIMR_ROK BIT(0)
536
537/* PCIE Host Interrupt Status Extension bit */
538#define PHIMR_BCNDMAINT7 BIT(23)
539#define PHIMR_BCNDMAINT6 BIT(22)
540#define PHIMR_BCNDMAINT5 BIT(21)
541#define PHIMR_BCNDMAINT4 BIT(20)
542#define PHIMR_BCNDOK7 BIT(19)
543#define PHIMR_BCNDOK6 BIT(18)
544#define PHIMR_BCNDOK5 BIT(17)
545#define PHIMR_BCNDOK4 BIT(16)
546/* bit12-15: RSVD */
547#define PHIMR_TXERR BIT(11)
548#define PHIMR_RXERR BIT(10)
549#define PHIMR_TXFOVW BIT(9)
550#define PHIMR_RXFOVW BIT(8)
551/* bit2-7: RSV */
552#define PHIMR_OCPINT BIT(1)
553
554#define HWSET_MAX_SIZE 256
555#define EFUSE_MAX_SECTION 32
556#define EFUSE_REAL_CONTENT_LEN 512
557#define EFUSE_OOB_PROTECT_BYTES 15
558
559#define EEPROM_DEFAULT_TSSI 0x0
560#define EEPROM_DEFAULT_TXPOWERDIFF 0x0
561#define EEPROM_DEFAULT_CRYSTALCAP 0x5
562#define EEPROM_DEFAULT_BOARDTYPE 0x02
563#define EEPROM_DEFAULT_TXPOWER 0x1010
564#define EEPROM_DEFAULT_HT2T_TXPWR 0x10
565
566#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
567#define EEPROM_DEFAULT_THERMALMETER 0x12
568#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0
569#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5
570#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22
571#define EEPROM_DEFAULT_HT40_2SDIFF 0x0
572#define EEPROM_DEFAULT_HT20_DIFF 2
573#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
574#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0
575#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0
576
577
578#define EEPROM_DEFAULT_PID 0x1234
579#define EEPROM_DEFAULT_VID 0x5678
580#define EEPROM_DEFAULT_CUSTOMERID 0xAB
581#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD
582#define EEPROM_DEFAULT_VERSION 0
583
584#define EEPROM_CHANNEL_PLAN_FCC 0x0
585#define EEPROM_CHANNEL_PLAN_IC 0x1
586#define EEPROM_CHANNEL_PLAN_ETSI 0x2
587#define EEPROM_CHANNEL_PLAN_SPAIN 0x3
588#define EEPROM_CHANNEL_PLAN_FRANCE 0x4
589#define EEPROM_CHANNEL_PLAN_MKK 0x5
590#define EEPROM_CHANNEL_PLAN_MKK1 0x6
591#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7
592#define EEPROM_CHANNEL_PLAN_TELEC 0x8
593#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9
594#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA
595#define EEPROM_CHANNEL_PLAN_NCC 0xB
596#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
597
598#define EEPROM_CID_DEFAULT 0x0
599#define EEPROM_CID_TOSHIBA 0x4
600#define EEPROM_CID_CCX 0x10
601#define EEPROM_CID_QMI 0x0D
602#define EEPROM_CID_WHQL 0xFE
603
604#define RTL8192_EEPROM_ID 0x8129
605
606#define RTL8190_EEPROM_ID 0x8129
607#define EEPROM_HPON 0x02
608#define EEPROM_CLK 0x06
609#define EEPROM_TESTR 0x08
610
611#define EEPROM_VID 0x49
612#define EEPROM_DID 0x4B
613#define EEPROM_SVID 0x4D
614#define EEPROM_SMID 0x4F
615
616#define EEPROM_MAC_ADDR 0x67
617
618#define EEPROM_CCK_TX_PWR_INX 0x5A
619#define EEPROM_HT40_1S_TX_PWR_INX 0x60
620#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66
621#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69
622#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C
623#define EEPROM_HT40_MAX_PWR_OFFSET 0x25
624#define EEPROM_HT20_MAX_PWR_OFFSET 0x22
625
626#define EEPROM_THERMAL_METER 0x2a
627#define EEPROM_XTAL_K 0x78
628#define EEPROM_RF_OPT1 0x79
629#define EEPROM_RF_OPT2 0x7A
630#define EEPROM_RF_OPT3 0x7B
631#define EEPROM_RF_OPT4 0x7C
632#define EEPROM_CHANNEL_PLAN 0x28
633#define EEPROM_VERSION 0x30
634#define EEPROM_CUSTOMER_ID 0x31
635
636#define EEPROM_PWRDIFF 0x54
637
638#define EEPROM_TXPOWERCCK 0x10
639#define EEPROM_TXPOWERHT40_1S 0x16
640#define EEPROM_TXPOWERHT40_2SDIFF 0x66
641#define EEPROM_TXPOWERHT20DIFF 0x1C
642#define EEPROM_TXPOWER_OFDMDIFF 0x1F
643
644#define EEPROM_TXPWR_GROUP 0x22
645
646#define EEPROM_TSSI_A 0x29
647#define EEPROM_TSSI_B 0x77
648
649#define EEPROM_CHANNELPLAN 0x28
650
651#define RF_OPTION1 0x2B
652#define RF_OPTION2 0x2C
653#define RF_OPTION3 0x2D
654#define RF_OPTION4 0x2E
655
656#define STOPBECON BIT(6)
657#define STOPHIGHT BIT(5)
658#define STOPMGT BIT(4)
659#define STOPVO BIT(3)
660#define STOPVI BIT(2)
661#define STOPBE BIT(1)
662#define STOPBK BIT(0)
663
664#define RCR_APPFCS BIT(31)
665#define RCR_APP_MIC BIT(30)
666#define RCR_APP_ICV BIT(29)
667#define RCR_APP_PHYST_RXFF BIT(28)
668#define RCR_APP_BA_SSN BIT(27)
669#define RCR_ENMBID BIT(24)
670#define RCR_LSIGEN BIT(23)
671#define RCR_MFBEN BIT(22)
672#define RCR_HTC_LOC_CTRL BIT(14)
673#define RCR_AMF BIT(13)
674#define RCR_ACF BIT(12)
675#define RCR_ADF BIT(11)
676#define RCR_AICV BIT(9)
677#define RCR_ACRC32 BIT(8)
678#define RCR_CBSSID_BCN BIT(7)
679#define RCR_CBSSID_DATA BIT(6)
680#define RCR_CBSSID RCR_CBSSID_DATA
681#define RCR_APWRMGT BIT(5)
682#define RCR_ADD3 BIT(4)
683#define RCR_AB BIT(3)
684#define RCR_AM BIT(2)
685#define RCR_APM BIT(1)
686#define RCR_AAP BIT(0)
687#define RCR_MXDMA_OFFSET 8
688#define RCR_FIFO_OFFSET 13
689
690#define RSV_CTRL 0x001C
691#define RD_CTRL 0x0524
692
693#define REG_USB_INFO 0xFE17
694#define REG_USB_SPECIAL_OPTION 0xFE55
695#define REG_USB_DMA_AGG_TO 0xFE5B
696#define REG_USB_AGG_TO 0xFE5C
697#define REG_USB_AGG_TH 0xFE5D
698
699#define REG_USB_VID 0xFE60
700#define REG_USB_PID 0xFE62
701#define REG_USB_OPTIONAL 0xFE64
702#define REG_USB_CHIRP_K 0xFE65
703#define REG_USB_PHY 0xFE66
704#define REG_USB_MAC_ADDR 0xFE70
705#define REG_USB_HRPWM 0xFE58
706#define REG_USB_HCPWM 0xFE57
707
708#define SW18_FPWM BIT(3)
709
710#define ISO_MD2PP BIT(0)
711#define ISO_UA2USB BIT(1)
712#define ISO_UD2CORE BIT(2)
713#define ISO_PA2PCIE BIT(3)
714#define ISO_PD2CORE BIT(4)
715#define ISO_IP2MAC BIT(5)
716#define ISO_DIOP BIT(6)
717#define ISO_DIOE BIT(7)
718#define ISO_EB2CORE BIT(8)
719#define ISO_DIOR BIT(9)
720
721#define PWC_EV25V BIT(14)
722#define PWC_EV12V BIT(15)
723
724#define FEN_BBRSTB BIT(0)
725#define FEN_BB_GLB_RSTn BIT(1)
726#define FEN_USBA BIT(2)
727#define FEN_UPLL BIT(3)
728#define FEN_USBD BIT(4)
729#define FEN_DIO_PCIE BIT(5)
730#define FEN_PCIEA BIT(6)
731#define FEN_PPLL BIT(7)
732#define FEN_PCIED BIT(8)
733#define FEN_DIOE BIT(9)
734#define FEN_CPUEN BIT(10)
735#define FEN_DCORE BIT(11)
736#define FEN_ELDR BIT(12)
737#define FEN_DIO_RF BIT(13)
738#define FEN_HWPDN BIT(14)
739#define FEN_MREGEN BIT(15)
740
741#define PFM_LDALL BIT(0)
742#define PFM_ALDN BIT(1)
743#define PFM_LDKP BIT(2)
744#define PFM_WOWL BIT(3)
745#define EnPDN BIT(4)
746#define PDN_PL BIT(5)
747#define APFM_ONMAC BIT(8)
748#define APFM_OFF BIT(9)
749#define APFM_RSM BIT(10)
750#define AFSM_HSUS BIT(11)
751#define AFSM_PCIE BIT(12)
752#define APDM_MAC BIT(13)
753#define APDM_HOST BIT(14)
754#define APDM_HPDN BIT(15)
755#define RDY_MACON BIT(16)
756#define SUS_HOST BIT(17)
757#define ROP_ALD BIT(20)
758#define ROP_PWR BIT(21)
759#define ROP_SPS BIT(22)
760#define SOP_MRST BIT(25)
761#define SOP_FUSE BIT(26)
762#define SOP_ABG BIT(27)
763#define SOP_AMB BIT(28)
764#define SOP_RCK BIT(29)
765#define SOP_A8M BIT(30)
766#define XOP_BTCK BIT(31)
767
768#define ANAD16V_EN BIT(0)
769#define ANA8M BIT(1)
770#define MACSLP BIT(4)
771#define LOADER_CLK_EN BIT(5)
772#define _80M_SSC_DIS BIT(7)
773#define _80M_SSC_EN_HO BIT(8)
774#define PHY_SSC_RSTB BIT(9)
775#define SEC_CLK_EN BIT(10)
776#define MAC_CLK_EN BIT(11)
777#define SYS_CLK_EN BIT(12)
778#define RING_CLK_EN BIT(13)
779
780#define BOOT_FROM_EEPROM BIT(4)
781#define EEPROM_EN BIT(5)
782
783#define AFE_BGEN BIT(0)
784#define AFE_MBEN BIT(1)
785#define MAC_ID_EN BIT(7)
786
787#define WLOCK_ALL BIT(0)
788#define WLOCK_00 BIT(1)
789#define WLOCK_04 BIT(2)
790#define WLOCK_08 BIT(3)
791#define WLOCK_40 BIT(4)
792#define R_DIS_PRST_0 BIT(5)
793#define R_DIS_PRST_1 BIT(6)
794#define LOCK_ALL_EN BIT(7)
795
796#define RF_EN BIT(0)
797#define RF_RSTB BIT(1)
798#define RF_SDMRSTB BIT(2)
799
800#define LDA15_EN BIT(0)
801#define LDA15_STBY BIT(1)
802#define LDA15_OBUF BIT(2)
803#define LDA15_REG_VOS BIT(3)
804#define _LDA15_VOADJ(x) (((x) & 0x7) << 4)
805
806#define LDV12_EN BIT(0)
807#define LDV12_SDBY BIT(1)
808#define LPLDO_HSM BIT(2)
809#define LPLDO_LSM_DIS BIT(3)
810#define _LDV12_VADJ(x) (((x) & 0xF) << 4)
811
812#define XTAL_EN BIT(0)
813#define XTAL_BSEL BIT(1)
814#define _XTAL_BOSC(x) (((x) & 0x3) << 2)
815#define _XTAL_CADJ(x) (((x) & 0xF) << 4)
816#define XTAL_GATE_USB BIT(8)
817#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9)
818#define XTAL_GATE_AFE BIT(11)
819#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12)
820#define XTAL_RF_GATE BIT(14)
821#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15)
822#define XTAL_GATE_DIG BIT(17)
823#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18)
824#define XTAL_BT_GATE BIT(20)
825#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21)
826#define _XTAL_GPIO(x) (((x) & 0x7) << 23)
827
828#define CKDLY_AFE BIT(26)
829#define CKDLY_USB BIT(27)
830#define CKDLY_DIG BIT(28)
831#define CKDLY_BT BIT(29)
832
833#define APLL_EN BIT(0)
834#define APLL_320_EN BIT(1)
835#define APLL_FREF_SEL BIT(2)
836#define APLL_EDGE_SEL BIT(3)
837#define APLL_WDOGB BIT(4)
838#define APLL_LPFEN BIT(5)
839
840#define APLL_REF_CLK_13MHZ 0x1
841#define APLL_REF_CLK_19_2MHZ 0x2
842#define APLL_REF_CLK_20MHZ 0x3
843#define APLL_REF_CLK_25MHZ 0x4
844#define APLL_REF_CLK_26MHZ 0x5
845#define APLL_REF_CLK_38_4MHZ 0x6
846#define APLL_REF_CLK_40MHZ 0x7
847
848#define APLL_320EN BIT(14)
849#define APLL_80EN BIT(15)
850#define APLL_1MEN BIT(24)
851
852#define ALD_EN BIT(18)
853#define EF_PD BIT(19)
854#define EF_FLAG BIT(31)
855
856#define EF_TRPT BIT(7)
857#define LDOE25_EN BIT(31)
858
859#define RSM_EN BIT(0)
860#define Timer_EN BIT(4)
861
862#define TRSW0EN BIT(2)
863#define TRSW1EN BIT(3)
864#define EROM_EN BIT(4)
865#define EnBT BIT(5)
866#define EnUart BIT(8)
867#define Uart_910 BIT(9)
868#define EnPMAC BIT(10)
869#define SIC_SWRST BIT(11)
870#define EnSIC BIT(12)
871#define SIC_23 BIT(13)
872#define EnHDP BIT(14)
873#define SIC_LBK BIT(15)
874
875#define LED0PL BIT(4)
876#define LED1PL BIT(12)
877#define LED0DIS BIT(7)
878
879#define MCUFWDL_EN BIT(0)
880#define MCUFWDL_RDY BIT(1)
881#define FWDL_ChkSum_rpt BIT(2)
882#define MACINI_RDY BIT(3)
883#define BBINI_RDY BIT(4)
884#define RFINI_RDY BIT(5)
885#define WINTINI_RDY BIT(6)
886#define CPRST BIT(23)
887
888#define XCLK_VLD BIT(0)
889#define ACLK_VLD BIT(1)
890#define UCLK_VLD BIT(2)
891#define PCLK_VLD BIT(3)
892#define PCIRSTB BIT(4)
893#define V15_VLD BIT(5)
894#define TRP_B15V_EN BIT(7)
895#define SIC_IDLE BIT(8)
896#define BD_MAC2 BIT(9)
897#define BD_MAC1 BIT(10)
898#define IC_MACPHY_MODE BIT(11)
899#define BT_FUNC BIT(16)
900#define VENDOR_ID BIT(19)
901#define PAD_HWPD_IDN BIT(22)
902#define TRP_VAUX_EN BIT(23)
903#define TRP_BT_EN BIT(24)
904#define BD_PKG_SEL BIT(25)
905#define BD_HCI_SEL BIT(26)
906#define TYPE_ID BIT(27)
907
908#define CHIP_VER_RTL_MASK 0xF000
909#define CHIP_VER_RTL_SHIFT 12
910
911#define REG_LBMODE (REG_CR + 3)
912
913#define HCI_TXDMA_EN BIT(0)
914#define HCI_RXDMA_EN BIT(1)
915#define TXDMA_EN BIT(2)
916#define RXDMA_EN BIT(3)
917#define PROTOCOL_EN BIT(4)
918#define SCHEDULE_EN BIT(5)
919#define MACTXEN BIT(6)
920#define MACRXEN BIT(7)
921#define ENSWBCN BIT(8)
922#define ENSEC BIT(9)
923
924#define _NETTYPE(x) (((x) & 0x3) << 16)
925#define MASK_NETTYPE 0x30000
926#define NT_NO_LINK 0x0
927#define NT_LINK_AD_HOC 0x1
928#define NT_LINK_AP 0x2
929#define NT_AS_AP 0x3
930
931#define _LBMODE(x) (((x) & 0xF) << 24)
932#define MASK_LBMODE 0xF000000
933#define LOOPBACK_NORMAL 0x0
934#define LOOPBACK_IMMEDIATELY 0xB
935#define LOOPBACK_MAC_DELAY 0x3
936#define LOOPBACK_PHY 0x1
937#define LOOPBACK_DMA 0x7
938
939#define GET_RX_PAGE_SIZE(value) ((value) & 0xF)
940#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4)
941#define _PSRX_MASK 0xF
942#define _PSTX_MASK 0xF0
943#define _PSRX(x) (x)
944#define _PSTX(x) ((x) << 4)
945
946#define PBP_64 0x0
947#define PBP_128 0x1
948#define PBP_256 0x2
949#define PBP_512 0x3
950#define PBP_1024 0x4
951
952#define RXDMA_ARBBW_EN BIT(0)
953#define RXSHFT_EN BIT(1)
954#define RXDMA_AGG_EN BIT(2)
955#define QS_VO_QUEUE BIT(8)
956#define QS_VI_QUEUE BIT(9)
957#define QS_BE_QUEUE BIT(10)
958#define QS_BK_QUEUE BIT(11)
959#define QS_MANAGER_QUEUE BIT(12)
960#define QS_HIGH_QUEUE BIT(13)
961
962#define HQSEL_VOQ BIT(0)
963#define HQSEL_VIQ BIT(1)
964#define HQSEL_BEQ BIT(2)
965#define HQSEL_BKQ BIT(3)
966#define HQSEL_MGTQ BIT(4)
967#define HQSEL_HIQ BIT(5)
968
969#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14)
970#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12)
971#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10)
972#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8)
973#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6)
974#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4)
975
976#define QUEUE_LOW 1
977#define QUEUE_NORMAL 2
978#define QUEUE_HIGH 3
979
980#define _LLT_NO_ACTIVE 0x0
981#define _LLT_WRITE_ACCESS 0x1
982#define _LLT_READ_ACCESS 0x2
983
984#define _LLT_INIT_DATA(x) ((x) & 0xFF)
985#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8)
986#define _LLT_OP(x) (((x) & 0x3) << 30)
987#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3)
988
989#define BB_WRITE_READ_MASK (BIT(31) | BIT(30))
990#define BB_WRITE_EN BIT(30)
991#define BB_READ_EN BIT(31)
992
993#define _HPQ(x) ((x) & 0xFF)
994#define _LPQ(x) (((x) & 0xFF) << 8)
995#define _PUBQ(x) (((x) & 0xFF) << 16)
996#define _NPQ(x) ((x) & 0xFF)
997
998#define HPQ_PUBLIC_DIS BIT(24)
999#define LPQ_PUBLIC_DIS BIT(25)
1000#define LD_RQPN BIT(31)
1001
1002#define BCN_VALID BIT(16)
1003#define BCN_HEAD(x) (((x) & 0xFF) << 8)
1004#define BCN_HEAD_MASK 0xFF00
1005
1006#define BLK_DESC_NUM_SHIFT 4
1007#define BLK_DESC_NUM_MASK 0xF
1008
1009#define DROP_DATA_EN BIT(9)
1010
1011#define EN_AMPDU_RTY_NEW BIT(7)
1012
1013#define _INIRTSMCS_SEL(x) ((x) & 0x3F)
1014
1015#define _SPEC_SIFS_CCK(x) ((x) & 0xFF)
1016#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8)
1017
1018#define RATE_REG_BITMAP_ALL 0xFFFFF
1019
1020#define _RRSC_BITMAP(x) ((x) & 0xFFFFF)
1021
1022#define _RRSR_RSC(x) (((x) & 0x3) << 21)
1023#define RRSR_RSC_RESERVED 0x0
1024#define RRSR_RSC_UPPER_SUBCHANNEL 0x1
1025#define RRSR_RSC_LOWER_SUBCHANNEL 0x2
1026#define RRSR_RSC_DUPLICATE_MODE 0x3
1027
1028#define USE_SHORT_G1 BIT(20)
1029
1030#define _AGGLMT_MCS0(x) ((x) & 0xF)
1031#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4)
1032#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8)
1033#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12)
1034#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16)
1035#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20)
1036#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24)
1037#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28)
1038
1039#define RETRY_LIMIT_SHORT_SHIFT 8
1040#define RETRY_LIMIT_LONG_SHIFT 0
1041
1042#define _DARF_RC1(x) ((x) & 0x1F)
1043#define _DARF_RC2(x) (((x) & 0x1F) << 8)
1044#define _DARF_RC3(x) (((x) & 0x1F) << 16)
1045#define _DARF_RC4(x) (((x) & 0x1F) << 24)
1046#define _DARF_RC5(x) ((x) & 0x1F)
1047#define _DARF_RC6(x) (((x) & 0x1F) << 8)
1048#define _DARF_RC7(x) (((x) & 0x1F) << 16)
1049#define _DARF_RC8(x) (((x) & 0x1F) << 24)
1050
1051#define _RARF_RC1(x) ((x) & 0x1F)
1052#define _RARF_RC2(x) (((x) & 0x1F) << 8)
1053#define _RARF_RC3(x) (((x) & 0x1F) << 16)
1054#define _RARF_RC4(x) (((x) & 0x1F) << 24)
1055#define _RARF_RC5(x) ((x) & 0x1F)
1056#define _RARF_RC6(x) (((x) & 0x1F) << 8)
1057#define _RARF_RC7(x) (((x) & 0x1F) << 16)
1058#define _RARF_RC8(x) (((x) & 0x1F) << 24)
1059
1060#define AC_PARAM_TXOP_LIMIT_OFFSET 16
1061#define AC_PARAM_ECW_MAX_OFFSET 12
1062#define AC_PARAM_ECW_MIN_OFFSET 8
1063#define AC_PARAM_AIFS_OFFSET 0
1064
1065#define _AIFS(x) (x)
1066#define _ECW_MAX_MIN(x) ((x) << 8)
1067#define _TXOP_LIMIT(x) ((x) << 16)
1068
1069#define _BCNIFS(x) ((x) & 0xFF)
1070#define _BCNECW(x) ((((x) & 0xF)) << 8)
1071
1072#define _LRL(x) ((x) & 0x3F)
1073#define _SRL(x) (((x) & 0x3F) << 8)
1074
1075#define _SIFS_CCK_CTX(x) ((x) & 0xFF)
1076#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8);
1077
1078#define _SIFS_OFDM_CTX(x) ((x) & 0xFF)
1079#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8);
1080
1081#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8)
1082
1083#define DIS_EDCA_CNT_DWN BIT(11)
1084
1085#define EN_MBSSID BIT(1)
1086#define EN_TXBCN_RPT BIT(2)
1087#define EN_BCN_FUNCTION BIT(3)
1088
1089#define TSFTR_RST BIT(0)
1090#define TSFTR1_RST BIT(1)
1091
1092#define STOP_BCNQ BIT(6)
1093
1094#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4)
1095#define DIS_TSF_UDT0_TEST_CHIP BIT(5)
1096
1097#define AcmHw_HwEn BIT(0)
1098#define AcmHw_BeqEn BIT(1)
1099#define AcmHw_ViqEn BIT(2)
1100#define AcmHw_VoqEn BIT(3)
1101#define AcmHw_BeqStatus BIT(4)
1102#define AcmHw_ViqStatus BIT(5)
1103#define AcmHw_VoqStatus BIT(6)
1104
1105#define APSDOFF BIT(6)
1106#define APSDOFF_STATUS BIT(7)
1107
1108#define BW_20MHZ BIT(2)
1109
1110#define RATE_BITMAP_ALL 0xFFFFF
1111
1112#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1
1113
1114#define TSFRST BIT(0)
1115#define DIS_GCLK BIT(1)
1116#define PAD_SEL BIT(2)
1117#define PWR_ST BIT(6)
1118#define PWRBIT_OW_EN BIT(7)
1119#define ACRC BIT(8)
1120#define CFENDFORM BIT(9)
1121#define ICV BIT(10)
1122
1123#define AAP BIT(0)
1124#define APM BIT(1)
1125#define AM BIT(2)
1126#define AB BIT(3)
1127#define ADD3 BIT(4)
1128#define APWRMGT BIT(5)
1129#define CBSSID BIT(6)
1130#define CBSSID_DATA BIT(6)
1131#define CBSSID_BCN BIT(7)
1132#define ACRC32 BIT(8)
1133#define AICV BIT(9)
1134#define ADF BIT(11)
1135#define ACF BIT(12)
1136#define AMF BIT(13)
1137#define HTC_LOC_CTRL BIT(14)
1138#define UC_DATA_EN BIT(16)
1139#define BM_DATA_EN BIT(17)
1140#define MFBEN BIT(22)
1141#define LSIGEN BIT(23)
1142#define EnMBID BIT(24)
1143#define APP_BASSN BIT(27)
1144#define APP_PHYSTS BIT(28)
1145#define APP_ICV BIT(29)
1146#define APP_MIC BIT(30)
1147#define APP_FCS BIT(31)
1148
1149#define _MIN_SPACE(x) ((x) & 0x7)
1150#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3)
1151
1152#define RXERR_TYPE_OFDM_PPDU 0
1153#define RXERR_TYPE_OFDM_FALSE_ALARM 1
1154#define RXERR_TYPE_OFDM_MPDU_OK 2
1155#define RXERR_TYPE_OFDM_MPDU_FAIL 3
1156#define RXERR_TYPE_CCK_PPDU 4
1157#define RXERR_TYPE_CCK_FALSE_ALARM 5
1158#define RXERR_TYPE_CCK_MPDU_OK 6
1159#define RXERR_TYPE_CCK_MPDU_FAIL 7
1160#define RXERR_TYPE_HT_PPDU 8
1161#define RXERR_TYPE_HT_FALSE_ALARM 9
1162#define RXERR_TYPE_HT_MPDU_TOTAL 10
1163#define RXERR_TYPE_HT_MPDU_OK 11
1164#define RXERR_TYPE_HT_MPDU_FAIL 12
1165#define RXERR_TYPE_RX_FULL_DROP 15
1166
1167#define RXERR_COUNTER_MASK 0xFFFFF
1168#define RXERR_RPT_RST BIT(27)
1169#define _RXERR_RPT_SEL(type) ((type) << 28)
1170
1171#define SCR_TxUseDK BIT(0)
1172#define SCR_RxUseDK BIT(1)
1173#define SCR_TxEncEnable BIT(2)
1174#define SCR_RxDecEnable BIT(3)
1175#define SCR_SKByA2 BIT(4)
1176#define SCR_NoSKMC BIT(5)
1177#define SCR_TXBCUSEDK BIT(6)
1178#define SCR_RXBCUSEDK BIT(7)
1179
1180#define USB_IS_HIGH_SPEED 0
1181#define USB_IS_FULL_SPEED 1
1182#define USB_SPEED_MASK BIT(5)
1183
1184#define USB_NORMAL_SIE_EP_MASK 0xF
1185#define USB_NORMAL_SIE_EP_SHIFT 4
1186
1187#define USB_TEST_EP_MASK 0x30
1188#define USB_TEST_EP_SHIFT 4
1189
1190#define USB_AGG_EN BIT(3)
1191
1192#define MAC_ADDR_LEN 6
1193#define LAST_ENTRY_OF_TX_PKT_BUFFER 255
1194
1195#define POLLING_LLT_THRESHOLD 20
1196#define POLLING_READY_TIMEOUT_COUNT 1000
1197
1198#define MAX_MSS_DENSITY_2T 0x13
1199#define MAX_MSS_DENSITY_1T 0x0A
1200
1201#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
1202#define EPROM_CMD_CONFIG 0x3
1203#define EPROM_CMD_LOAD 1
1204
1205#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE
1206
1207#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2)
1208
1209#define RPMAC_RESET 0x100
1210#define RPMAC_TXSTART 0x104
1211#define RPMAC_TXLEGACYSIG 0x108
1212#define RPMAC_TXHTSIG1 0x10c
1213#define RPMAC_TXHTSIG2 0x110
1214#define RPMAC_PHYDEBUG 0x114
1215#define RPMAC_TXPACKETNUM 0x118
1216#define RPMAC_TXIDLE 0x11c
1217#define RPMAC_TXMACHEADER0 0x120
1218#define RPMAC_TXMACHEADER1 0x124
1219#define RPMAC_TXMACHEADER2 0x128
1220#define RPMAC_TXMACHEADER3 0x12c
1221#define RPMAC_TXMACHEADER4 0x130
1222#define RPMAC_TXMACHEADER5 0x134
1223#define RPMAC_TXDADATYPE 0x138
1224#define RPMAC_TXRANDOMSEED 0x13c
1225#define RPMAC_CCKPLCPPREAMBLE 0x140
1226#define RPMAC_CCKPLCPHEADER 0x144
1227#define RPMAC_CCKCRC16 0x148
1228#define RPMAC_OFDMRXCRC32OK 0x170
1229#define RPMAC_OFDMRXCRC32Er 0x174
1230#define RPMAC_OFDMRXPARITYER 0x178
1231#define RPMAC_OFDMRXCRC8ER 0x17c
1232#define RPMAC_CCKCRXRC16ER 0x180
1233#define RPMAC_CCKCRXRC32ER 0x184
1234#define RPMAC_CCKCRXRC32OK 0x188
1235#define RPMAC_TXSTATUS 0x18c
1236
1237#define RFPGA0_RFMOD 0x800
1238
1239#define RFPGA0_TXINFO 0x804
1240#define RFPGA0_PSDFUNCTION 0x808
1241
1242#define RFPGA0_TXGAINSTAGE 0x80c
1243
1244#define RFPGA0_RFTIMING1 0x810
1245#define RFPGA0_RFTIMING2 0x814
1246
1247#define RFPGA0_XA_HSSIPARAMETER1 0x820
1248#define RFPGA0_XA_HSSIPARAMETER2 0x824
1249#define RFPGA0_XB_HSSIPARAMETER1 0x828
1250#define RFPGA0_XB_HSSIPARAMETER2 0x82c
1251
1252#define RFPGA0_XA_LSSIPARAMETER 0x840
1253#define RFPGA0_XB_LSSIPARAMETER 0x844
1254
1255#define RFPGA0_RFWAKEUPPARAMETER 0x850
1256#define RFPGA0_RFSLEEPUPPARAMETER 0x854
1257
1258#define RFPGA0_XAB_SWITCHCONTROL 0x858
1259#define RFPGA0_XCD_SWITCHCONTROL 0x85c
1260
1261#define RFPGA0_XA_RFINTERFACEOE 0x860
1262#define RFPGA0_XB_RFINTERFACEOE 0x864
1263
1264#define RFPGA0_XAB_RFINTERFACESW 0x870
1265#define RFPGA0_XCD_RFINTERFACESW 0x874
1266
1267#define rFPGA0_XAB_RFPARAMETER 0x878
1268#define rFPGA0_XCD_RFPARAMETER 0x87c
1269
1270#define RFPGA0_ANALOGPARAMETER1 0x880
1271#define RFPGA0_ANALOGPARAMETER2 0x884
1272#define RFPGA0_ANALOGPARAMETER3 0x888
1273#define RFPGA0_ANALOGPARAMETER4 0x88c
1274
1275#define RFPGA0_XA_LSSIREADBACK 0x8a0
1276#define RFPGA0_XB_LSSIREADBACK 0x8a4
1277#define RFPGA0_XC_LSSIREADBACK 0x8a8
1278#define RFPGA0_XD_LSSIREADBACK 0x8ac
1279
1280#define RFPGA0_PSDREPORT 0x8b4
1281#define TRANSCEIVEA_HSPI_READBACK 0x8b8
1282#define TRANSCEIVEB_HSPI_READBACK 0x8bc
1283#define RFPGA0_XAB_RFINTERFACERB 0x8e0
1284#define RFPGA0_XCD_RFINTERFACERB 0x8e4
1285
1286#define RFPGA1_RFMOD 0x900
1287
1288#define RFPGA1_TXBLOCK 0x904
1289#define RFPGA1_DEBUGSELECT 0x908
1290#define RFPGA1_TXINFO 0x90c
1291
1292#define RCCK0_SYSTEM 0xa00
1293
1294#define RCCK0_AFESETTING 0xa04
1295#define RCCK0_CCA 0xa08
1296
1297#define RCCK0_RXAGC1 0xa0c
1298#define RCCK0_RXAGC2 0xa10
1299
1300#define RCCK0_RXHP 0xa14
1301
1302#define RCCK0_DSPPARAMETER1 0xa18
1303#define RCCK0_DSPPARAMETER2 0xa1c
1304
1305#define RCCK0_TXFILTER1 0xa20
1306#define RCCK0_TXFILTER2 0xa24
1307#define RCCK0_DEBUGPORT 0xa28
1308#define RCCK0_FALSEALARMREPORT 0xa2c
1309#define RCCK0_TRSSIREPORT 0xa50
1310#define RCCK0_RXREPORT 0xa54
1311#define RCCK0_FACOUNTERLOWER 0xa5c
1312#define RCCK0_FACOUNTERUPPER 0xa58
1313
1314#define ROFDM0_LSTF 0xc00
1315
1316#define ROFDM0_TRXPATHENABLE 0xc04
1317#define ROFDM0_TRMUXPAR 0xc08
1318#define ROFDM0_TRSWISOLATION 0xc0c
1319
1320#define ROFDM0_XARXAFE 0xc10
1321#define ROFDM0_XARXIQIMBALANCE 0xc14
1322#define ROFDM0_XBRXAFE 0xc18
1323#define ROFDM0_XBRXIQIMBALANCE 0xc1c
1324#define ROFDM0_XCRXAFE 0xc20
1325#define ROFDM0_XCRXIQIMBANLANCE 0xc24
1326#define ROFDM0_XDRXAFE 0xc28
1327#define ROFDM0_XDRXIQIMBALANCE 0xc2c
1328
1329#define ROFDM0_RXDETECTOR1 0xc30
1330#define ROFDM0_RXDETECTOR2 0xc34
1331#define ROFDM0_RXDETECTOR3 0xc38
1332#define ROFDM0_RXDETECTOR4 0xc3c
1333
1334#define ROFDM0_RXDSP 0xc40
1335#define ROFDM0_CFOANDDAGC 0xc44
1336#define ROFDM0_CCADROPTHRESHOLD 0xc48
1337#define ROFDM0_ECCATHRESHOLD 0xc4c
1338
1339#define ROFDM0_XAAGCCORE1 0xc50
1340#define ROFDM0_XAAGCCORE2 0xc54
1341#define ROFDM0_XBAGCCORE1 0xc58
1342#define ROFDM0_XBAGCCORE2 0xc5c
1343#define ROFDM0_XCAGCCORE1 0xc60
1344#define ROFDM0_XCAGCCORE2 0xc64
1345#define ROFDM0_XDAGCCORE1 0xc68
1346#define ROFDM0_XDAGCCORE2 0xc6c
1347
1348#define ROFDM0_AGCPARAMETER1 0xc70
1349#define ROFDM0_AGCPARAMETER2 0xc74
1350#define ROFDM0_AGCRSSITABLE 0xc78
1351#define ROFDM0_HTSTFAGC 0xc7c
1352
1353#define ROFDM0_XATXIQIMBALANCE 0xc80
1354#define ROFDM0_XATXAFE 0xc84
1355#define ROFDM0_XBTXIQIMBALANCE 0xc88
1356#define ROFDM0_XBTXAFE 0xc8c
1357#define ROFDM0_XCTXIQIMBALANCE 0xc90
1358#define ROFDM0_XCTXAFE 0xc94
1359#define ROFDM0_XDTXIQIMBALANCE 0xc98
1360#define ROFDM0_XDTXAFE 0xc9c
1361
1362#define ROFDM0_RXIQEXTANTA 0xca0
1363
1364#define ROFDM0_RXHPPARAMETER 0xce0
1365#define ROFDM0_TXPSEUDONOISEWGT 0xce4
1366#define ROFDM0_FRAMESYNC 0xcf0
1367#define ROFDM0_DFSREPORT 0xcf4
1368#define ROFDM0_TXCOEFF1 0xca4
1369#define ROFDM0_TXCOEFF2 0xca8
1370#define ROFDM0_TXCOEFF3 0xcac
1371#define ROFDM0_TXCOEFF4 0xcb0
1372#define ROFDM0_TXCOEFF5 0xcb4
1373#define ROFDM0_TXCOEFF6 0xcb8
1374
1375#define ROFDM1_LSTF 0xd00
1376#define ROFDM1_TRXPATHENABLE 0xd04
1377
1378#define ROFDM1_CF0 0xd08
1379#define ROFDM1_CSI1 0xd10
1380#define ROFDM1_SBD 0xd14
1381#define ROFDM1_CSI2 0xd18
1382#define ROFDM1_CFOTRACKING 0xd2c
1383#define ROFDM1_TRXMESAURE1 0xd34
1384#define ROFDM1_INTFDET 0xd3c
1385#define ROFDM1_PSEUDONOISESTATEAB 0xd50
1386#define ROFDM1_PSEUDONOISESTATECD 0xd54
1387#define ROFDM1_RXPSEUDONOISEWGT 0xd58
1388
1389#define ROFDM_PHYCOUNTER1 0xda0
1390#define ROFDM_PHYCOUNTER2 0xda4
1391#define ROFDM_PHYCOUNTER3 0xda8
1392
1393#define ROFDM_SHORTCFOAB 0xdac
1394#define ROFDM_SHORTCFOCD 0xdb0
1395#define ROFDM_LONGCFOAB 0xdb4
1396#define ROFDM_LONGCFOCD 0xdb8
1397#define ROFDM_TAILCF0AB 0xdbc
1398#define ROFDM_TAILCF0CD 0xdc0
1399#define ROFDM_PWMEASURE1 0xdc4
1400#define ROFDM_PWMEASURE2 0xdc8
1401#define ROFDM_BWREPORT 0xdcc
1402#define ROFDM_AGCREPORT 0xdd0
1403#define ROFDM_RXSNR 0xdd4
1404#define ROFDM_RXEVMCSI 0xdd8
1405#define ROFDM_SIGREPORT 0xddc
1406
1407#define RTXAGC_A_RATE18_06 0xe00
1408#define RTXAGC_A_RATE54_24 0xe04
1409#define RTXAGC_A_CCK1_MCS32 0xe08
1410#define RTXAGC_A_MCS03_MCS00 0xe10
1411#define RTXAGC_A_MCS07_MCS04 0xe14
1412#define RTXAGC_A_MCS11_MCS08 0xe18
1413#define RTXAGC_A_MCS15_MCS12 0xe1c
1414
1415#define RTXAGC_B_RATE18_06 0x830
1416#define RTXAGC_B_RATE54_24 0x834
1417#define RTXAGC_B_CCK1_55_MCS32 0x838
1418#define RTXAGC_B_MCS03_MCS00 0x83c
1419#define RTXAGC_B_MCS07_MCS04 0x848
1420#define RTXAGC_B_MCS11_MCS08 0x84c
1421#define RTXAGC_B_MCS15_MCS12 0x868
1422#define RTXAGC_B_CCK11_A_CCK2_11 0x86c
1423
1424#define RZEBRA1_HSSIENABLE 0x0
1425#define RZEBRA1_TRXENABLE1 0x1
1426#define RZEBRA1_TRXENABLE2 0x2
1427#define RZEBRA1_AGC 0x4
1428#define RZEBRA1_CHARGEPUMP 0x5
1429#define RZEBRA1_CHANNEL 0x7
1430
1431#define RZEBRA1_TXGAIN 0x8
1432#define RZEBRA1_TXLPF 0x9
1433#define RZEBRA1_RXLPF 0xb
1434#define RZEBRA1_RXHPFCORNER 0xc
1435
1436#define RGLOBALCTRL 0
1437#define RRTL8256_TXLPF 19
1438#define RRTL8256_RXLPF 11
1439#define RRTL8258_TXLPF 0x11
1440#define RRTL8258_RXLPF 0x13
1441#define RRTL8258_RSSILPF 0xa
1442
1443#define RF_AC 0x00
1444
1445#define RF_IQADJ_G1 0x01
1446#define RF_IQADJ_G2 0x02
1447#define RF_POW_TRSW 0x05
1448
1449#define RF_GAIN_RX 0x06
1450#define RF_GAIN_TX 0x07
1451
1452#define RF_TXM_IDAC 0x08
1453#define RF_BS_IQGEN 0x0F
1454
1455#define RF_MODE1 0x10
1456#define RF_MODE2 0x11
1457
1458#define RF_RX_AGC_HP 0x12
1459#define RF_TX_AGC 0x13
1460#define RF_BIAS 0x14
1461#define RF_IPA 0x15
1462#define RF_POW_ABILITY 0x17
1463#define RF_MODE_AG 0x18
1464#define RRFCHANNEL 0x18
1465#define RF_CHNLBW 0x18
1466#define RF_TOP 0x19
1467
1468#define RF_RX_G1 0x1A
1469#define RF_RX_G2 0x1B
1470
1471#define RF_RX_BB2 0x1C
1472#define RF_RX_BB1 0x1D
1473
1474#define RF_RCK1 0x1E
1475#define RF_RCK2 0x1F
1476
1477#define RF_TX_G1 0x20
1478#define RF_TX_G2 0x21
1479#define RF_TX_G3 0x22
1480
1481#define RF_TX_BB1 0x23
1482#define RF_T_METER 0x24
1483
1484#define RF_SYN_G1 0x25
1485#define RF_SYN_G2 0x26
1486#define RF_SYN_G3 0x27
1487#define RF_SYN_G4 0x28
1488#define RF_SYN_G5 0x29
1489#define RF_SYN_G6 0x2A
1490#define RF_SYN_G7 0x2B
1491#define RF_SYN_G8 0x2C
1492
1493#define RF_RCK_OS 0x30
1494#define RF_TXPA_G1 0x31
1495#define RF_TXPA_G2 0x32
1496#define RF_TXPA_G3 0x33
1497
1498#define BBBRESETB 0x100
1499#define BGLOBALRESETB 0x200
1500#define BOFDMTXSTART 0x4
1501#define BCCKTXSTART 0x8
1502#define BCRC32DEBUG 0x100
1503#define BPMACLOOPBACK 0x10
1504#define BTXLSIG 0xffffff
1505#define BOFDMTXRATE 0xf
1506#define BOFDMTXRESERVED 0x10
1507#define BOFDMTXLENGTH 0x1ffe0
1508#define BOFDMTXPARITY 0x20000
1509#define BTXHTSIG1 0xffffff
1510#define BTXHTMCSRATE 0x7f
1511#define BTXHTBW 0x80
1512#define BTXHTLENGTH 0xffff00
1513#define BTXHTSIG2 0xffffff
1514#define BTXHTSMOOTHING 0x1
1515#define BTXHTSOUNDING 0x2
1516#define BTXHTRESERVED 0x4
1517#define BTXHTAGGREATION 0x8
1518#define BTXHTSTBC 0x30
1519#define BTXHTADVANCECODING 0x40
1520#define BTXHTSHORTGI 0x80
1521#define BTXHTNUMBERHT_LTF 0x300
1522#define BTXHTCRC8 0x3fc00
1523#define BCOUNTERRESET 0x10000
1524#define BNUMOFOFDMTX 0xffff
1525#define BNUMOFCCKTX 0xffff0000
1526#define BTXIDLEINTERVAL 0xffff
1527#define BOFDMSERVICE 0xffff0000
1528#define BTXMACHEADER 0xffffffff
1529#define BTXDATAINIT 0xff
1530#define BTXHTMODE 0x100
1531#define BTXDATATYPE 0x30000
1532#define BTXRANDOMSEED 0xffffffff
1533#define BCCKTXPREAMBLE 0x1
1534#define BCCKTXSFD 0xffff0000
1535#define BCCKTXSIG 0xff
1536#define BCCKTXSERVICE 0xff00
1537#define BCCKLENGTHEXT 0x8000
1538#define BCCKTXLENGHT 0xffff0000
1539#define BCCKTXCRC16 0xffff
1540#define BCCKTXSTATUS 0x1
1541#define BOFDMTXSTATUS 0x2
1542#define IS_BB_REG_OFFSET_92S(_Offset) \
1543 ((_Offset >= 0x800) && (_Offset <= 0xfff))
1544
1545#define BRFMOD 0x1
1546#define BJAPANMODE 0x2
1547#define BCCKTXSC 0x30
1548#define BCCKEN 0x1000000
1549#define BOFDMEN 0x2000000
1550
1551#define BOFDMRXADCPHASE 0x10000
1552#define BOFDMTXDACPHASE 0x40000
1553#define BXATXAGC 0x3f
1554
1555#define BXBTXAGC 0xf00
1556#define BXCTXAGC 0xf000
1557#define BXDTXAGC 0xf0000
1558
1559#define BPASTART 0xf0000000
1560#define BTRSTART 0x00f00000
1561#define BRFSTART 0x0000f000
1562#define BBBSTART 0x000000f0
1563#define BBBCCKSTART 0x0000000f
1564#define BPAEND 0xf
1565#define BTREND 0x0f000000
1566#define BRFEND 0x000f0000
1567#define BCCAMASK 0x000000f0
1568#define BR2RCCAMASK 0x00000f00
1569#define BHSSI_R2TDELAY 0xf8000000
1570#define BHSSI_T2RDELAY 0xf80000
1571#define BCONTXHSSI 0x400
1572#define BIGFROMCCK 0x200
1573#define BAGCADDRESS 0x3f
1574#define BRXHPTX 0x7000
1575#define BRXHP2RX 0x38000
1576#define BRXHPCCKINI 0xc0000
1577#define BAGCTXCODE 0xc00000
1578#define BAGCRXCODE 0x300000
1579
1580#define B3WIREDATALENGTH 0x800
1581#define B3WIREADDREAALENGTH 0x400
1582
1583#define B3WIRERFPOWERDOWN 0x1
1584#define B5GPAPEPOLARITY 0x40000000
1585#define B2GPAPEPOLARITY 0x80000000
1586#define BRFSW_TXDEFAULTANT 0x3
1587#define BRFSW_TXOPTIONANT 0x30
1588#define BRFSW_RXDEFAULTANT 0x300
1589#define BRFSW_RXOPTIONANT 0x3000
1590#define BRFSI_3WIREDATA 0x1
1591#define BRFSI_3WIRECLOCK 0x2
1592#define BRFSI_3WIRELOAD 0x4
1593#define BRFSI_3WIRERW 0x8
1594#define BRFSI_3WIRE 0xf
1595
1596#define BRFSI_RFENV 0x10
1597
1598#define BRFSI_TRSW 0x20
1599#define BRFSI_TRSWB 0x40
1600#define BRFSI_ANTSW 0x100
1601#define BRFSI_ANTSWB 0x200
1602#define BRFSI_PAPE 0x400
1603#define BRFSI_PAPE5G 0x800
1604#define BBANDSELECT 0x1
1605#define BHTSIG2_GI 0x80
1606#define BHTSIG2_SMOOTHING 0x01
1607#define BHTSIG2_SOUNDING 0x02
1608#define BHTSIG2_AGGREATON 0x08
1609#define BHTSIG2_STBC 0x30
1610#define BHTSIG2_ADVCODING 0x40
1611#define BHTSIG2_NUMOFHTLTF 0x300
1612#define BHTSIG2_CRC8 0x3fc
1613#define BHTSIG1_MCS 0x7f
1614#define BHTSIG1_BANDWIDTH 0x80
1615#define BHTSIG1_HTLENGTH 0xffff
1616#define BLSIG_RATE 0xf
1617#define BLSIG_RESERVED 0x10
1618#define BLSIG_LENGTH 0x1fffe
1619#define BLSIG_PARITY 0x20
1620#define BCCKRXPHASE 0x4
1621
1622#define BLSSIREADADDRESS 0x7f800000
1623#define BLSSIREADEDGE 0x80000000
1624
1625#define BLSSIREADBACKDATA 0xfffff
1626
1627#define BLSSIREADOKFLAG 0x1000
1628#define BCCKSAMPLERATE 0x8
1629#define BREGULATOR0STANDBY 0x1
1630#define BREGULATORPLLSTANDBY 0x2
1631#define BREGULATOR1STANDBY 0x4
1632#define BPLLPOWERUP 0x8
1633#define BDPLLPOWERUP 0x10
1634#define BDA10POWERUP 0x20
1635#define BAD7POWERUP 0x200
1636#define BDA6POWERUP 0x2000
1637#define BXTALPOWERUP 0x4000
1638#define B40MDCLKPOWERUP 0x8000
1639#define BDA6DEBUGMODE 0x20000
1640#define BDA6SWING 0x380000
1641
1642#define BADCLKPHASE 0x4000000
1643#define B80MCLKDELAY 0x18000000
1644#define BAFEWATCHDOGENABLE 0x20000000
1645
1646#define BXTALCAP01 0xc0000000
1647#define BXTALCAP23 0x3
1648#define BXTALCAP92X 0x0f000000
1649#define BXTALCAP 0x0f000000
1650
1651#define BINTDIFCLKENABLE 0x400
1652#define BEXTSIGCLKENABLE 0x800
1653#define BBANDGAP_MBIAS_POWERUP 0x10000
1654#define BAD11SH_GAIN 0xc0000
1655#define BAD11NPUT_RANGE 0x700000
1656#define BAD110P_CURRENT 0x3800000
1657#define BLPATH_LOOPBACK 0x4000000
1658#define BQPATH_LOOPBACK 0x8000000
1659#define BAFE_LOOPBACK 0x10000000
1660#define BDA10_SWING 0x7e0
1661#define BDA10_REVERSE 0x800
1662#define BDA_CLK_SOURCE 0x1000
1663#define BDA7INPUT_RANGE 0x6000
1664#define BDA7_GAIN 0x38000
1665#define BDA7OUTPUT_CM_MODE 0x40000
1666#define BDA7INPUT_CM_MODE 0x380000
1667#define BDA7CURRENT 0xc00000
1668#define BREGULATOR_ADJUST 0x7000000
1669#define BAD11POWERUP_ATTX 0x1
1670#define BDA10PS_ATTX 0x10
1671#define BAD11POWERUP_ATRX 0x100
1672#define BDA10PS_ATRX 0x1000
1673#define BCCKRX_AGC_FORMAT 0x200
1674#define BPSDFFT_SAMPLE_POINT 0xc000
1675#define BPSD_AVERAGE_NUM 0x3000
1676#define BIQPATH_CONTROL 0xc00
1677#define BPSD_FREQ 0x3ff
1678#define BPSD_ANTENNA_PATH 0x30
1679#define BPSD_IQ_SWITCH 0x40
1680#define BPSD_RX_TRIGGER 0x400000
1681#define BPSD_TX_TRIGGER 0x80000000
1682#define BPSD_SINE_TONE_SCALE 0x7f000000
1683#define BPSD_REPORT 0xffff
1684
1685#define BOFDM_TXSC 0x30000000
1686#define BCCK_TXON 0x1
1687#define BOFDM_TXON 0x2
1688#define BDEBUG_PAGE 0xfff
1689#define BDEBUG_ITEM 0xff
1690#define BANTL 0x10
1691#define BANT_NONHT 0x100
1692#define BANT_HT1 0x1000
1693#define BANT_HT2 0x10000
1694#define BANT_HT1S1 0x100000
1695#define BANT_NONHTS1 0x1000000
1696
1697#define BCCK_BBMODE 0x3
1698#define BCCK_TXPOWERSAVING 0x80
1699#define BCCK_RXPOWERSAVING 0x40
1700
1701#define BCCK_SIDEBAND 0x10
1702
1703#define BCCK_SCRAMBLE 0x8
1704#define BCCK_ANTDIVERSITY 0x8000
1705#define BCCK_CARRIER_RECOVERY 0x4000
1706#define BCCK_TXRATE 0x3000
1707#define BCCK_DCCANCEL 0x0800
1708#define BCCK_ISICANCEL 0x0400
1709#define BCCK_MATCH_FILTER 0x0200
1710#define BCCK_EQUALIZER 0x0100
1711#define BCCK_PREAMBLE_DETECT 0x800000
1712#define BCCK_FAST_FALSECCAi 0x400000
1713#define BCCK_CH_ESTSTARTi 0x300000
1714#define BCCK_CCA_COUNTi 0x080000
1715#define BCCK_CS_LIM 0x070000
1716#define BCCK_BIST_MODEi 0x80000000
1717#define BCCK_CCAMASK 0x40000000
1718#define BCCK_TX_DAC_PHASE 0x4
1719#define BCCK_RX_ADC_PHASE 0x20000000
1720#define BCCKR_CP_MODE 0x0100
1721#define BCCK_TXDC_OFFSET 0xf0
1722#define BCCK_RXDC_OFFSET 0xf
1723#define BCCK_CCA_MODE 0xc000
1724#define BCCK_FALSECS_LIM 0x3f00
1725#define BCCK_CS_RATIO 0xc00000
1726#define BCCK_CORGBIT_SEL 0x300000
1727#define BCCK_PD_LIM 0x0f0000
1728#define BCCK_NEWCCA 0x80000000
1729#define BCCK_RXHP_OF_IG 0x8000
1730#define BCCK_RXIG 0x7f00
1731#define BCCK_LNA_POLARITY 0x800000
1732#define BCCK_RX1ST_BAIN 0x7f0000
1733#define BCCK_RF_EXTEND 0x20000000
1734#define BCCK_RXAGC_SATLEVEL 0x1f000000
1735#define BCCK_RXAGC_SATCOUNT 0xe0
1736#define bCCKRxRFSettle 0x1f
1737#define BCCK_FIXED_RXAGC 0x8000
1738#define BCCK_ANTENNA_POLARITY 0x2000
1739#define BCCK_TXFILTER_TYPE 0x0c00
1740#define BCCK_RXAGC_REPORTTYPE 0x0300
1741#define BCCK_RXDAGC_EN 0x80000000
1742#define BCCK_RXDAGC_PERIOD 0x20000000
1743#define BCCK_RXDAGC_SATLEVEL 0x1f000000
1744#define BCCK_TIMING_RECOVERY 0x800000
1745#define BCCK_TXC0 0x3f0000
1746#define BCCK_TXC1 0x3f000000
1747#define BCCK_TXC2 0x3f
1748#define BCCK_TXC3 0x3f00
1749#define BCCK_TXC4 0x3f0000
1750#define BCCK_TXC5 0x3f000000
1751#define BCCK_TXC6 0x3f
1752#define BCCK_TXC7 0x3f00
1753#define BCCK_DEBUGPORT 0xff0000
1754#define BCCK_DAC_DEBUG 0x0f000000
1755#define BCCK_FALSEALARM_ENABLE 0x8000
1756#define BCCK_FALSEALARM_READ 0x4000
1757#define BCCK_TRSSI 0x7f
1758#define BCCK_RXAGC_REPORT 0xfe
1759#define BCCK_RXREPORT_ANTSEL 0x80000000
1760#define BCCK_RXREPORT_MFOFF 0x40000000
1761#define BCCK_RXREPORT_SQLOSS 0x20000000
1762#define BCCK_RXREPORT_PKTLOSS 0x10000000
1763#define BCCK_RXREPORT_LOCKEDBIT 0x08000000
1764#define BCCK_RXREPORT_RATEERROR 0x04000000
1765#define BCCK_RXREPORT_RXRATE 0x03000000
1766#define BCCK_RXFA_COUNTER_LOWER 0xff
1767#define BCCK_RXFA_COUNTER_UPPER 0xff000000
1768#define BCCK_RXHPAGC_START 0xe000
1769#define BCCK_RXHPAGC_FINAL 0x1c00
1770#define BCCK_RXFALSEALARM_ENABLE 0x8000
1771#define BCCK_FACOUNTER_FREEZE 0x4000
1772#define BCCK_TXPATH_SEL 0x10000000
1773#define BCCK_DEFAULT_RXPATH 0xc000000
1774#define BCCK_OPTION_RXPATH 0x3000000
1775
1776#define BNUM_OFSTF 0x3
1777#define BSHIFT_L 0xc0
1778#define BGI_TH 0xc
1779#define BRXPATH_A 0x1
1780#define BRXPATH_B 0x2
1781#define BRXPATH_C 0x4
1782#define BRXPATH_D 0x8
1783#define BTXPATH_A 0x1
1784#define BTXPATH_B 0x2
1785#define BTXPATH_C 0x4
1786#define BTXPATH_D 0x8
1787#define BTRSSI_FREQ 0x200
1788#define BADC_BACKOFF 0x3000
1789#define BDFIR_BACKOFF 0xc000
1790#define BTRSSI_LATCH_PHASE 0x10000
1791#define BRX_LDC_OFFSET 0xff
1792#define BRX_QDC_OFFSET 0xff00
1793#define BRX_DFIR_MODE 0x1800000
1794#define BRX_DCNF_TYPE 0xe000000
1795#define BRXIQIMB_A 0x3ff
1796#define BRXIQIMB_B 0xfc00
1797#define BRXIQIMB_C 0x3f0000
1798#define BRXIQIMB_D 0xffc00000
1799#define BDC_DC_NOTCH 0x60000
1800#define BRXNB_NOTCH 0x1f000000
1801#define BPD_TH 0xf
1802#define BPD_TH_OPT2 0xc000
1803#define BPWED_TH 0x700
1804#define BIFMF_WIN_L 0x800
1805#define BPD_OPTION 0x1000
1806#define BMF_WIN_L 0xe000
1807#define BBW_SEARCH_L 0x30000
1808#define BWIN_ENH_L 0xc0000
1809#define BBW_TH 0x700000
1810#define BED_TH2 0x3800000
1811#define BBW_OPTION 0x4000000
1812#define BRADIO_TH 0x18000000
1813#define BWINDOW_L 0xe0000000
1814#define BSBD_OPTION 0x1
1815#define BFRAME_TH 0x1c
1816#define BFS_OPTION 0x60
1817#define BDC_SLOPE_CHECK 0x80
1818#define BFGUARD_COUNTER_DC_L 0xe00
1819#define BFRAME_WEIGHT_SHORT 0x7000
1820#define BSUB_TUNE 0xe00000
1821#define BFRAME_DC_LENGTH 0xe000000
1822#define BSBD_START_OFFSET 0x30000000
1823#define BFRAME_TH_2 0x7
1824#define BFRAME_GI2_TH 0x38
1825#define BGI2_SYNC_EN 0x40
1826#define BSARCH_SHORT_EARLY 0x300
1827#define BSARCH_SHORT_LATE 0xc00
1828#define BSARCH_GI2_LATE 0x70000
1829#define BCFOANTSUM 0x1
1830#define BCFOACC 0x2
1831#define BCFOSTARTOFFSET 0xc
1832#define BCFOLOOPBACK 0x70
1833#define BCFOSUMWEIGHT 0x80
1834#define BDAGCENABLE 0x10000
1835#define BTXIQIMB_A 0x3ff
1836#define BTXIQIMB_b 0xfc00
1837#define BTXIQIMB_C 0x3f0000
1838#define BTXIQIMB_D 0xffc00000
1839#define BTXIDCOFFSET 0xff
1840#define BTXIQDCOFFSET 0xff00
1841#define BTXDFIRMODE 0x10000
1842#define BTXPESUDO_NOISEON 0x4000000
1843#define BTXPESUDO_NOISE_A 0xff
1844#define BTXPESUDO_NOISE_B 0xff00
1845#define BTXPESUDO_NOISE_C 0xff0000
1846#define BTXPESUDO_NOISE_D 0xff000000
1847#define BCCA_DROPOPTION 0x20000
1848#define BCCA_DROPTHRES 0xfff00000
1849#define BEDCCA_H 0xf
1850#define BEDCCA_L 0xf0
1851#define BLAMBDA_ED 0x300
1852#define BRX_INITIALGAIN 0x7f
1853#define BRX_ANTDIV_EN 0x80
1854#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00
1855#define BRX_HIGHPOWER_FLOW 0x8000
1856#define BRX_AGC_FREEZE_THRES 0xc0000
1857#define BRX_FREEZESTEP_AGC1 0x300000
1858#define BRX_FREEZESTEP_AGC2 0xc00000
1859#define BRX_FREEZESTEP_AGC3 0x3000000
1860#define BRX_FREEZESTEP_AGC0 0xc000000
1861#define BRXRSSI_CMP_EN 0x10000000
1862#define BRXQUICK_AGCEN 0x20000000
1863#define BRXAGC_FREEZE_THRES_MODE 0x40000000
1864#define BRX_OVERFLOW_CHECKTYPE 0x80000000
1865#define BRX_AGCSHIFT 0x7f
1866#define BTRSW_TRI_ONLY 0x80
1867#define BPOWER_THRES 0x300
1868#define BRXAGC_EN 0x1
1869#define BRXAGC_TOGETHER_EN 0x2
1870#define BRXAGC_MIN 0x4
1871#define BRXHP_INI 0x7
1872#define BRXHP_TRLNA 0x70
1873#define BRXHP_RSSI 0x700
1874#define BRXHP_BBP1 0x7000
1875#define BRXHP_BBP2 0x70000
1876#define BRXHP_BBP3 0x700000
1877#define BRSSI_H 0x7f0000
1878#define BRSSI_GEN 0x7f000000
1879#define BRXSETTLE_TRSW 0x7
1880#define BRXSETTLE_LNA 0x38
1881#define BRXSETTLE_RSSI 0x1c0
1882#define BRXSETTLE_BBP 0xe00
1883#define BRXSETTLE_RXHP 0x7000
1884#define BRXSETTLE_ANTSW_RSSI 0x38000
1885#define BRXSETTLE_ANTSW 0xc0000
1886#define BRXPROCESS_TIME_DAGC 0x300000
1887#define BRXSETTLE_HSSI 0x400000
1888#define BRXPROCESS_TIME_BBPPW 0x800000
1889#define BRXANTENNA_POWER_SHIFT 0x3000000
1890#define BRSSI_TABLE_SELECT 0xc000000
1891#define BRXHP_FINAL 0x7000000
1892#define BRXHPSETTLE_BBP 0x7
1893#define BRXHTSETTLE_HSSI 0x8
1894#define BRXHTSETTLE_RXHP 0x70
1895#define BRXHTSETTLE_BBPPW 0x80
1896#define BRXHTSETTLE_IDLE 0x300
1897#define BRXHTSETTLE_RESERVED 0x1c00
1898#define BRXHT_RXHP_EN 0x8000
1899#define BRXAGC_FREEZE_THRES 0x30000
1900#define BRXAGC_TOGETHEREN 0x40000
1901#define BRXHTAGC_MIN 0x80000
1902#define BRXHTAGC_EN 0x100000
1903#define BRXHTDAGC_EN 0x200000
1904#define BRXHT_RXHP_BBP 0x1c00000
1905#define BRXHT_RXHP_FINAL 0xe0000000
1906#define BRXPW_RADIO_TH 0x3
1907#define BRXPW_RADIO_EN 0x4
1908#define BRXMF_HOLD 0x3800
1909#define BRXPD_DELAY_TH1 0x38
1910#define BRXPD_DELAY_TH2 0x1c0
1911#define BRXPD_DC_COUNT_MAX 0x600
1912#define BRXPD_DELAY_TH 0x8000
1913#define BRXPROCESS_DELAY 0xf0000
1914#define BRXSEARCHRANGE_GI2_EARLY 0x700000
1915#define BRXFRAME_FUARD_COUNTER_L 0x3800000
1916#define BRXSGI_GUARD_L 0xc000000
1917#define BRXSGI_SEARCH_L 0x30000000
1918#define BRXSGI_TH 0xc0000000
1919#define BDFSCNT0 0xff
1920#define BDFSCNT1 0xff00
1921#define BDFSFLAG 0xf0000
1922#define BMF_WEIGHT_SUM 0x300000
1923#define BMINIDX_TH 0x7f000000
1924#define BDAFORMAT 0x40000
1925#define BTXCH_EMU_ENABLE 0x01000000
1926#define BTRSW_ISOLATION_A 0x7f
1927#define BTRSW_ISOLATION_B 0x7f00
1928#define BTRSW_ISOLATION_C 0x7f0000
1929#define BTRSW_ISOLATION_D 0x7f000000
1930#define BEXT_LNA_GAIN 0x7c00
1931
1932#define BSTBC_EN 0x4
1933#define BANTENNA_MAPPING 0x10
1934#define BNSS 0x20
1935#define BCFO_ANTSUM_ID 0x200
1936#define BPHY_COUNTER_RESET 0x8000000
1937#define BCFO_REPORT_GET 0x4000000
1938#define BOFDM_CONTINUE_TX 0x10000000
1939#define BOFDM_SINGLE_CARRIER 0x20000000
1940#define BOFDM_SINGLE_TONE 0x40000000
1941#define BHT_DETECT 0x100
1942#define BCFOEN 0x10000
1943#define BCFOVALUE 0xfff00000
1944#define BSIGTONE_RE 0x3f
1945#define BSIGTONE_IM 0x7f00
1946#define BCOUNTER_CCA 0xffff
1947#define BCOUNTER_PARITYFAIL 0xffff0000
1948#define BCOUNTER_RATEILLEGAL 0xffff
1949#define BCOUNTER_CRC8FAIL 0xffff0000
1950#define BCOUNTER_MCSNOSUPPORT 0xffff
1951#define BCOUNTER_FASTSYNC 0xffff
1952#define BSHORTCFO 0xfff
1953#define BSHORTCFOT_LENGTH 12
1954#define BSHORTCFOF_LENGTH 11
1955#define BLONGCFO 0x7ff
1956#define BLONGCFOT_LENGTH 11
1957#define BLONGCFOF_LENGTH 11
1958#define BTAILCFO 0x1fff
1959#define BTAILCFOT_LENGTH 13
1960#define BTAILCFOF_LENGTH 12
1961#define BNOISE_EN_PWDB 0xffff
1962#define BCC_POWER_DB 0xffff0000
1963#define BMOISE_PWDB 0xffff
1964#define BPOWERMEAST_LENGTH 10
1965#define BPOWERMEASF_LENGTH 3
1966#define BRX_HT_BW 0x1
1967#define BRXSC 0x6
1968#define BRX_HT 0x8
1969#define BNB_INTF_DET_ON 0x1
1970#define BINTF_WIN_LEN_CFG 0x30
1971#define BNB_INTF_TH_CFG 0x1c0
1972#define BRFGAIN 0x3f
1973#define BTABLESEL 0x40
1974#define BTRSW 0x80
1975#define BRXSNR_A 0xff
1976#define BRXSNR_B 0xff00
1977#define BRXSNR_C 0xff0000
1978#define BRXSNR_D 0xff000000
1979#define BSNR_EVMT_LENGTH 8
1980#define BSNR_EVMF_LENGTH 1
1981#define BCSI1ST 0xff
1982#define BCSI2ND 0xff00
1983#define BRXEVM1ST 0xff0000
1984#define BRXEVM2ND 0xff000000
1985#define BSIGEVM 0xff
1986#define BPWDB 0xff00
1987#define BSGIEN 0x10000
1988
1989#define BSFACTOR_QMA1 0xf
1990#define BSFACTOR_QMA2 0xf0
1991#define BSFACTOR_QMA3 0xf00
1992#define BSFACTOR_QMA4 0xf000
1993#define BSFACTOR_QMA5 0xf0000
1994#define BSFACTOR_QMA6 0xf0000
1995#define BSFACTOR_QMA7 0xf00000
1996#define BSFACTOR_QMA8 0xf000000
1997#define BSFACTOR_QMA9 0xf0000000
1998#define BCSI_SCHEME 0x100000
1999
2000#define BNOISE_LVL_TOP_SET 0x3
2001#define BCHSMOOTH 0x4
2002#define BCHSMOOTH_CFG1 0x38
2003#define BCHSMOOTH_CFG2 0x1c0
2004#define BCHSMOOTH_CFG3 0xe00
2005#define BCHSMOOTH_CFG4 0x7000
2006#define BMRCMODE 0x800000
2007#define BTHEVMCFG 0x7000000
2008
2009#define BLOOP_FIT_TYPE 0x1
2010#define BUPD_CFO 0x40
2011#define BUPD_CFO_OFFDATA 0x80
2012#define BADV_UPD_CFO 0x100
2013#define BADV_TIME_CTRL 0x800
2014#define BUPD_CLKO 0x1000
2015#define BFC 0x6000
2016#define BTRACKING_MODE 0x8000
2017#define BPHCMP_ENABLE 0x10000
2018#define BUPD_CLKO_LTF 0x20000
2019#define BCOM_CH_CFO 0x40000
2020#define BCSI_ESTI_MODE 0x80000
2021#define BADV_UPD_EQZ 0x100000
2022#define BUCHCFG 0x7000000
2023#define BUPDEQZ 0x8000000
2024
2025#define BRX_PESUDO_NOISE_ON 0x20000000
2026#define BRX_PESUDO_NOISE_A 0xff
2027#define BRX_PESUDO_NOISE_B 0xff00
2028#define BRX_PESUDO_NOISE_C 0xff0000
2029#define BRX_PESUDO_NOISE_D 0xff000000
2030#define BRX_PESUDO_NOISESTATE_A 0xffff
2031#define BRX_PESUDO_NOISESTATE_B 0xffff0000
2032#define BRX_PESUDO_NOISESTATE_C 0xffff
2033#define BRX_PESUDO_NOISESTATE_D 0xffff0000
2034
2035#define BZEBRA1_HSSIENABLE 0x8
2036#define BZEBRA1_TRXCONTROL 0xc00
2037#define BZEBRA1_TRXGAINSETTING 0x07f
2038#define BZEBRA1_RXCOUNTER 0xc00
2039#define BZEBRA1_TXCHANGEPUMP 0x38
2040#define BZEBRA1_RXCHANGEPUMP 0x7
2041#define BZEBRA1_CHANNEL_NUM 0xf80
2042#define BZEBRA1_TXLPFBW 0x400
2043#define BZEBRA1_RXLPFBW 0x600
2044
2045#define BRTL8256REG_MODE_CTRL1 0x100
2046#define BRTL8256REG_MODE_CTRL0 0x40
2047#define BRTL8256REG_TXLPFBW 0x18
2048#define BRTL8256REG_RXLPFBW 0x600
2049
2050#define BRTL8258_TXLPFBW 0xc
2051#define BRTL8258_RXLPFBW 0xc00
2052#define BRTL8258_RSSILPFBW 0xc0
2053
2054#define BBYTE0 0x1
2055#define BBYTE1 0x2
2056#define BBYTE2 0x4
2057#define BBYTE3 0x8
2058#define BWORD0 0x3
2059#define BWORD1 0xc
2060#define BWORD 0xf
2061
2062#define MASKBYTE0 0xff
2063#define MASKBYTE1 0xff00
2064#define MASKBYTE2 0xff0000
2065#define MASKBYTE3 0xff000000
2066#define MASKHWORD 0xffff0000
2067#define MASKLWORD 0x0000ffff
2068#define MASKDWORD 0xffffffff
2069#define MASK12BITS 0xfff
2070#define MASKH4BITS 0xf0000000
2071#define MASKOFDM_D 0xffc00000
2072#define MASKCCK 0x3f3f3f3f
2073
2074#define MASK4BITS 0x0f
2075#define MASK20BITS 0xfffff
2076#define RFREG_OFFSET_MASK 0xfffff
2077
2078#define BENABLE 0x1
2079#define BDISABLE 0x0
2080
2081#define LEFT_ANTENNA 0x0
2082#define RIGHT_ANTENNA 0x1
2083
2084#define TCHECK_TXSTATUS 500
2085#define TUPDATE_RXCOUNTER 100
2086
2087/* 2 EFUSE_TEST (For RTL8723 partially) */
2088#define EFUSE_SEL(x) (((x) & 0x3) << 8)
2089#define EFUSE_SEL_MASK 0x300
2090#define EFUSE_WIFI_SEL_0 0x0
2091
2092/* Enable GPIO[9] as WiFi HW PDn source*/
2093#define WL_HWPDN_EN BIT(0)
2094/* WiFi HW PDn polarity control*/
2095#define WL_HWPDN_SL BIT(1)
2096
2097#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c
new file mode 100644
index 000000000000..50dd2fb2c93d
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c
@@ -0,0 +1,505 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 "reg.h"
32#include "def.h"
33#include "phy.h"
34#include "rf.h"
35#include "dm.h"
36
37void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
38{
39 struct rtl_priv *rtlpriv = rtl_priv(hw);
40 struct rtl_phy *rtlphy = &(rtlpriv->phy);
41
42 switch (bandwidth) {
43 case HT_CHANNEL_WIDTH_20:
44 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
45 0xfffff3ff) | 0x0400);
46 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
47 rtlphy->rfreg_chnlval[0]);
48 break;
49 case HT_CHANNEL_WIDTH_20_40:
50 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
51 0xfffff3ff));
52 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
53 rtlphy->rfreg_chnlval[0]);
54 break;
55 default:
56 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
57 "unknown bandwidth: %#X\n", bandwidth);
58 break;
59 }
60}
61
62void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
63 u8 *ppowerlevel)
64{
65 struct rtl_priv *rtlpriv = rtl_priv(hw);
66 struct rtl_phy *rtlphy = &(rtlpriv->phy);
67 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
68 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
69 u32 tx_agc[2] = {0, 0}, tmpval;
70 bool turbo_scanoff = false;
71 u8 idx1, idx2;
72 u8 *ptr;
73
74 if (rtlefuse->eeprom_regulatory != 0)
75 turbo_scanoff = true;
76
77 if (mac->act_scanning == true) {
78 tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
79 tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
80
81 if (turbo_scanoff) {
82 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
83 tx_agc[idx1] = ppowerlevel[idx1] |
84 (ppowerlevel[idx1] << 8) |
85 (ppowerlevel[idx1] << 16) |
86 (ppowerlevel[idx1] << 24);
87 }
88 }
89 } else {
90 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
91 tx_agc[idx1] = ppowerlevel[idx1] |
92 (ppowerlevel[idx1] << 8) |
93 (ppowerlevel[idx1] << 16) |
94 (ppowerlevel[idx1] << 24);
95 }
96
97 if (rtlefuse->eeprom_regulatory == 0) {
98 tmpval = (rtlphy->mcs_offset[0][6]) +
99 (rtlphy->mcs_offset[0][7] << 8);
100 tx_agc[RF90_PATH_A] += tmpval;
101
102 tmpval = (rtlphy->mcs_offset[0][14]) +
103 (rtlphy->mcs_offset[0][15] << 24);
104 tx_agc[RF90_PATH_B] += tmpval;
105 }
106 }
107
108 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
109 ptr = (u8 *) (&(tx_agc[idx1]));
110 for (idx2 = 0; idx2 < 4; idx2++) {
111 if (*ptr > RF6052_MAX_TX_PWR)
112 *ptr = RF6052_MAX_TX_PWR;
113 ptr++;
114 }
115 }
116
117 tmpval = tx_agc[RF90_PATH_A] & 0xff;
118 rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
119
120 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
121 "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
122 RTXAGC_A_CCK1_MCS32);
123
124 tmpval = tx_agc[RF90_PATH_A] >> 8;
125
126 tmpval = tmpval & 0xff00ffff;
127
128 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
129
130 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
131 "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
132 RTXAGC_B_CCK11_A_CCK2_11);
133
134 tmpval = tx_agc[RF90_PATH_B] >> 24;
135 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
136
137 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
138 "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
139 RTXAGC_B_CCK11_A_CCK2_11);
140
141 tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
142 rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
143
144 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
145 "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
146 RTXAGC_B_CCK1_55_MCS32);
147}
148
149static void rtl8723ae_phy_get_power_base(struct ieee80211_hw *hw,
150 u8 *ppowerlevel, u8 channel,
151 u32 *ofdmbase, u32 *mcsbase)
152{
153 struct rtl_priv *rtlpriv = rtl_priv(hw);
154 struct rtl_phy *rtlphy = &(rtlpriv->phy);
155 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
156 u32 powerBase0, powerBase1;
157 u8 legacy_pwrdiff, ht20_pwrdiff;
158 u8 i, powerlevel[2];
159
160 for (i = 0; i < 2; i++) {
161 powerlevel[i] = ppowerlevel[i];
162 legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
163 powerBase0 = powerlevel[i] + legacy_pwrdiff;
164
165 powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
166 (powerBase0 << 8) | powerBase0;
167 *(ofdmbase + i) = powerBase0;
168 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
169 " [OFDM power base index rf(%c) = 0x%x]\n",
170 ((i == 0) ? 'A' : 'B'), *(ofdmbase + i));
171 }
172
173 for (i = 0; i < 2; i++) {
174 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
175 ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
176 powerlevel[i] += ht20_pwrdiff;
177 }
178 powerBase1 = powerlevel[i];
179 powerBase1 = (powerBase1 << 24) |
180 (powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
181
182 *(mcsbase + i) = powerBase1;
183
184 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
185 " [MCS power base index rf(%c) = 0x%x]\n",
186 ((i == 0) ? 'A' : 'B'), *(mcsbase + i));
187 }
188}
189
190static void rtl8723ae_get_txpwr_val_by_reg(struct ieee80211_hw *hw,
191 u8 channel, u8 index,
192 u32 *powerBase0,
193 u32 *powerBase1,
194 u32 *p_outwriteval)
195{
196 struct rtl_priv *rtlpriv = rtl_priv(hw);
197 struct rtl_phy *rtlphy = &(rtlpriv->phy);
198 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
199 u8 i, chnlgroup = 0, pwr_diff_limit[4];
200 u32 writeVal, customer_limit, rf;
201
202 for (rf = 0; rf < 2; rf++) {
203 switch (rtlefuse->eeprom_regulatory) {
204 case 0:
205 chnlgroup = 0;
206
207 writeVal = rtlphy->mcs_offset[chnlgroup]
208 [index + (rf ? 8 : 0)] +
209 ((index < 2) ? powerBase0[rf] :
210 powerBase1[rf]);
211
212 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
213 "RTK better performance, "
214 "writeVal(%c) = 0x%x\n",
215 ((rf == 0) ? 'A' : 'B'), writeVal);
216 break;
217 case 1:
218 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
219 writeVal = ((index < 2) ? powerBase0[rf] :
220 powerBase1[rf]);
221
222 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
223 "Realtek regulatory, 40MHz, "
224 "writeVal(%c) = 0x%x\n",
225 ((rf == 0) ? 'A' : 'B'), writeVal);
226 } else {
227 if (rtlphy->pwrgroup_cnt == 1)
228 chnlgroup = 0;
229 if (rtlphy->pwrgroup_cnt >= 3) {
230 if (channel <= 3)
231 chnlgroup = 0;
232 else if (channel >= 4 && channel <= 9)
233 chnlgroup = 1;
234 else if (channel > 9)
235 chnlgroup = 2;
236 if (rtlphy->current_chan_bw ==
237 HT_CHANNEL_WIDTH_20)
238 chnlgroup++;
239 else
240 chnlgroup += 4;
241 }
242
243 writeVal = rtlphy->mcs_offset[chnlgroup]
244 [index + (rf ? 8 : 0)] + ((index < 2) ?
245 powerBase0[rf] :
246 powerBase1[rf]);
247
248 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
249 "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n",
250 ((rf == 0) ? 'A' : 'B'), writeVal);
251 }
252 break;
253 case 2:
254 writeVal =
255 ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
256
257 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
258 "Better regulatory, writeVal(%c) = 0x%x\n",
259 ((rf == 0) ? 'A' : 'B'), writeVal);
260 break;
261 case 3:
262 chnlgroup = 0;
263
264 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
265 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
266 "customer's limit, 40MHz rf(%c) = 0x%x\n",
267 ((rf == 0) ? 'A' : 'B'),
268 rtlefuse->pwrgroup_ht40[rf][channel-1]);
269 } else {
270 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
271 "customer's limit, 20MHz rf(%c) = 0x%x\n",
272 ((rf == 0) ? 'A' : 'B'),
273 rtlefuse->pwrgroup_ht20[rf][channel-1]);
274 }
275 for (i = 0; i < 4; i++) {
276 pwr_diff_limit[i] =
277 (u8) ((rtlphy->mcs_offset
278 [chnlgroup][index + (rf ? 8 : 0)] &
279 (0x7f << (i * 8))) >> (i * 8));
280
281 if (rtlphy->current_chan_bw ==
282 HT_CHANNEL_WIDTH_20_40) {
283 if (pwr_diff_limit[i] >
284 rtlefuse->
285 pwrgroup_ht40[rf][channel - 1])
286 pwr_diff_limit[i] =
287 rtlefuse->pwrgroup_ht40[rf]
288 [channel - 1];
289 } else {
290 if (pwr_diff_limit[i] >
291 rtlefuse->
292 pwrgroup_ht20[rf][channel - 1])
293 pwr_diff_limit[i] =
294 rtlefuse->pwrgroup_ht20[rf]
295 [channel - 1];
296 }
297 }
298
299 customer_limit = (pwr_diff_limit[3] << 24) |
300 (pwr_diff_limit[2] << 16) |
301 (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
302
303 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
304 "Customer's limit rf(%c) = 0x%x\n",
305 ((rf == 0) ? 'A' : 'B'), customer_limit);
306
307 writeVal = customer_limit +
308 ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
309
310 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
311 "Customer, writeVal rf(%c)= 0x%x\n",
312 ((rf == 0) ? 'A' : 'B'), writeVal);
313 break;
314 default:
315 chnlgroup = 0;
316 writeVal = rtlphy->mcs_offset[chnlgroup][index +
317 (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] :
318 powerBase1[rf]);
319
320 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
321 "RTK better performance, writeVal rf(%c) = 0x%x\n",
322 ((rf == 0) ? 'A' : 'B'), writeVal);
323 break;
324 }
325
326 if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
327 writeVal = writeVal - 0x06060606;
328 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
329 TXHIGHPWRLEVEL_BT2)
330 writeVal = writeVal - 0x0c0c0c0c;
331 *(p_outwriteval + rf) = writeVal;
332 }
333}
334
335static void _rtl8723ae_write_ofdm_power_reg(struct ieee80211_hw *hw,
336 u8 index, u32 *pValue)
337{
338 struct rtl_priv *rtlpriv = rtl_priv(hw);
339 struct rtl_phy *rtlphy = &(rtlpriv->phy);
340
341 u16 regoffset_a[6] = {
342 RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
343 RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
344 RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
345 };
346 u16 regoffset_b[6] = {
347 RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
348 RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
349 RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
350 };
351 u8 i, rf, pwr_val[4];
352 u32 writeVal;
353 u16 regoffset;
354
355 for (rf = 0; rf < 2; rf++) {
356 writeVal = pValue[rf];
357 for (i = 0; i < 4; i++) {
358 pwr_val[i] = (u8) ((writeVal & (0x7f <<
359 (i * 8))) >> (i * 8));
360
361 if (pwr_val[i] > RF6052_MAX_TX_PWR)
362 pwr_val[i] = RF6052_MAX_TX_PWR;
363 }
364 writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
365 (pwr_val[1] << 8) | pwr_val[0];
366
367 if (rf == 0)
368 regoffset = regoffset_a[index];
369 else
370 regoffset = regoffset_b[index];
371 rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
372
373 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
374 "Set 0x%x = %08x\n", regoffset, writeVal);
375
376 if (((get_rf_type(rtlphy) == RF_2T2R) &&
377 (regoffset == RTXAGC_A_MCS15_MCS12 ||
378 regoffset == RTXAGC_B_MCS15_MCS12)) ||
379 ((get_rf_type(rtlphy) != RF_2T2R) &&
380 (regoffset == RTXAGC_A_MCS07_MCS04 ||
381 regoffset == RTXAGC_B_MCS07_MCS04))) {
382
383 writeVal = pwr_val[3];
384 if (regoffset == RTXAGC_A_MCS15_MCS12 ||
385 regoffset == RTXAGC_A_MCS07_MCS04)
386 regoffset = 0xc90;
387 if (regoffset == RTXAGC_B_MCS15_MCS12 ||
388 regoffset == RTXAGC_B_MCS07_MCS04)
389 regoffset = 0xc98;
390
391 for (i = 0; i < 3; i++) {
392 writeVal = (writeVal > 6) ? (writeVal - 6) : 0;
393 rtl_write_byte(rtlpriv, (u32) (regoffset + i),
394 (u8) writeVal);
395 }
396 }
397 }
398}
399
400void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
401 u8 *ppowerlevel, u8 channel)
402{
403 u32 writeVal[2], powerBase0[2], powerBase1[2];
404 u8 index;
405
406 rtl8723ae_phy_get_power_base(hw, ppowerlevel,
407 channel, &powerBase0[0], &powerBase1[0]);
408
409 for (index = 0; index < 6; index++) {
410 rtl8723ae_get_txpwr_val_by_reg(hw, channel, index,
411 &powerBase0[0],
412 &powerBase1[0],
413 &writeVal[0]);
414
415 _rtl8723ae_write_ofdm_power_reg(hw, index, &writeVal[0]);
416 }
417}
418
419static bool _rtl8723ae_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
420{
421 struct rtl_priv *rtlpriv = rtl_priv(hw);
422 struct rtl_phy *rtlphy = &(rtlpriv->phy);
423 u32 u4_regvalue = 0;
424 u8 rfpath;
425 bool rtstatus = true;
426 struct bb_reg_def *pphyreg;
427
428 for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
429
430 pphyreg = &rtlphy->phyreg_def[rfpath];
431
432 switch (rfpath) {
433 case RF90_PATH_A:
434 case RF90_PATH_C:
435 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
436 BRFSI_RFENV);
437 break;
438 case RF90_PATH_B:
439 case RF90_PATH_D:
440 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
441 BRFSI_RFENV << 16);
442 break;
443 }
444
445 rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
446 udelay(1);
447
448 rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
449 udelay(1);
450
451 rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
452 B3WIREADDREAALENGTH, 0x0);
453 udelay(1);
454
455 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
456 udelay(1);
457
458 switch (rfpath) {
459 case RF90_PATH_A:
460 rtstatus = rtl8723ae_phy_config_rf_with_headerfile(hw,
461 (enum radio_path)rfpath);
462 break;
463 case RF90_PATH_B:
464 rtstatus = rtl8723ae_phy_config_rf_with_headerfile(hw,
465 (enum radio_path)rfpath);
466 break;
467 case RF90_PATH_C:
468 break;
469 case RF90_PATH_D:
470 break;
471 }
472 switch (rfpath) {
473 case RF90_PATH_A:
474 case RF90_PATH_C:
475 rtl_set_bbreg(hw, pphyreg->rfintfs,
476 BRFSI_RFENV, u4_regvalue);
477 break;
478 case RF90_PATH_B:
479 case RF90_PATH_D:
480 rtl_set_bbreg(hw, pphyreg->rfintfs,
481 BRFSI_RFENV << 16, u4_regvalue);
482 break;
483 }
484 if (rtstatus != true) {
485 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
486 "Radio[%d] Fail!!", rfpath);
487 return false;
488 }
489 }
490 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
491 return rtstatus;
492}
493
494bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw)
495{
496 struct rtl_priv *rtlpriv = rtl_priv(hw);
497 struct rtl_phy *rtlphy = &(rtlpriv->phy);
498
499 if (rtlphy->rf_type == RF_1T1R)
500 rtlphy->num_total_rfpath = 1;
501 else
502 rtlphy->num_total_rfpath = 2;
503
504 return _rtl8723ae_phy_rf6052_config_parafile(hw);
505}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h
new file mode 100644
index 000000000000..d0f9dd79abea
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h
@@ -0,0 +1,43 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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#ifndef __RTL8723E_RF_H__
31#define __RTL8723E_RF_H__
32
33#define RF6052_MAX_TX_PWR 0x3F
34
35extern void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
36 u8 bandwidth);
37extern void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
38 u8 *ppowerlevel);
39extern void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
40 u8 *ppowerlevel, u8 channel);
41extern bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw);
42
43#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
new file mode 100644
index 000000000000..0afdc240f2fd
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
@@ -0,0 +1,387 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 <linux/vmalloc.h>
32#include <linux/module.h>
33
34#include "../core.h"
35#include "../pci.h"
36#include "reg.h"
37#include "def.h"
38#include "phy.h"
39#include "dm.h"
40#include "hw.h"
41#include "sw.h"
42#include "trx.h"
43#include "led.h"
44#include "table.h"
45#include "hal_btc.h"
46
47static void rtl8723ae_init_aspm_vars(struct ieee80211_hw *hw)
48{
49 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
50
51 /*close ASPM for AMD defaultly */
52 rtlpci->const_amdpci_aspm = 0;
53
54 /* ASPM PS mode.
55 * 0 - Disable ASPM,
56 * 1 - Enable ASPM without Clock Req,
57 * 2 - Enable ASPM with Clock Req,
58 * 3 - Alwyas Enable ASPM with Clock Req,
59 * 4 - Always Enable ASPM without Clock Req.
60 * set defult to RTL8192CE:3 RTL8192E:2
61 */
62 rtlpci->const_pci_aspm = 3;
63
64 /*Setting for PCI-E device */
65 rtlpci->const_devicepci_aspm_setting = 0x03;
66
67 /*Setting for PCI-E bridge */
68 rtlpci->const_hostpci_aspm_setting = 0x02;
69
70 /* In Hw/Sw Radio Off situation.
71 * 0 - Default,
72 * 1 - From ASPM setting without low Mac Pwr,
73 * 2 - From ASPM setting with low Mac Pwr,
74 * 3 - Bus D3
75 * set default to RTL8192CE:0 RTL8192SE:2
76 */
77 rtlpci->const_hwsw_rfoff_d3 = 0;
78
79 /* This setting works for those device with
80 * backdoor ASPM setting such as EPHY setting.
81 * 0 - Not support ASPM,
82 * 1 - Support ASPM,
83 * 2 - According to chipset.
84 */
85 rtlpci->const_support_pciaspm = 1;
86}
87
88int rtl8723ae_init_sw_vars(struct ieee80211_hw *hw)
89{
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
91 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
92 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
93 int err;
94
95 rtl8723ae_bt_reg_init(hw);
96 rtlpriv->dm.dm_initialgain_enable = 1;
97 rtlpriv->dm.dm_flag = 0;
98 rtlpriv->dm.disable_framebursting = 0;
99 rtlpriv->dm.thermalvalue = 0;
100 rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
101
102 /* compatible 5G band 88ce just 2.4G band & smsp */
103 rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
104 rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
105 rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
106
107 rtlpci->receive_config = (RCR_APPFCS |
108 RCR_APP_MIC |
109 RCR_APP_ICV |
110 RCR_APP_PHYST_RXFF |
111 RCR_HTC_LOC_CTRL |
112 RCR_AMF |
113 RCR_ACF |
114 RCR_ADF |
115 RCR_AICV |
116 RCR_AB |
117 RCR_AM |
118 RCR_APM |
119 0);
120
121 rtlpci->irq_mask[0] =
122 (u32) (PHIMR_ROK |
123 PHIMR_RDU |
124 PHIMR_VODOK |
125 PHIMR_VIDOK |
126 PHIMR_BEDOK |
127 PHIMR_BKDOK |
128 PHIMR_MGNTDOK |
129 PHIMR_HIGHDOK |
130 PHIMR_C2HCMD |
131 PHIMR_HISRE_IND |
132 PHIMR_TSF_BIT32_TOGGLE |
133 PHIMR_TXBCNOK |
134 PHIMR_PSTIMEOUT |
135 0);
136
137 rtlpci->irq_mask[1] = (u32)(PHIMR_RXFOVW | 0);
138
139 /* for debug level */
140 rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
141 /* for LPS & IPS */
142 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
143 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
144 rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
145 rtlpriv->psc.reg_fwctrl_lps = 3;
146 rtlpriv->psc.reg_max_lps_awakeintvl = 5;
147 /* for ASPM, you can close aspm through
148 * set const_support_pciaspm = 0
149 */
150 rtl8723ae_init_aspm_vars(hw);
151
152 if (rtlpriv->psc.reg_fwctrl_lps == 1)
153 rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
154 else if (rtlpriv->psc.reg_fwctrl_lps == 2)
155 rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
156 else if (rtlpriv->psc.reg_fwctrl_lps == 3)
157 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
158
159 /* for firmware buf */
160 rtlpriv->rtlhal.pfirmware = vmalloc(0x6000);
161 if (!rtlpriv->rtlhal.pfirmware) {
162 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
163 "Can't alloc buffer for fw.\n");
164 return 1;
165 }
166
167 if (IS_VENDOR_8723_A_CUT(rtlhal->version))
168 rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw.bin";
169 else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
170 rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw_B.bin";
171
172 rtlpriv->max_fw_size = 0x6000;
173 pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
174 err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
175 rtlpriv->io.dev, GFP_KERNEL, hw,
176 rtl_fw_cb);
177 if (err) {
178 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
179 "Failed to request firmware!\n");
180 return 1;
181 }
182 return 0;
183}
184
185void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw)
186{
187 struct rtl_priv *rtlpriv = rtl_priv(hw);
188
189 if (rtlpriv->rtlhal.pfirmware) {
190 vfree(rtlpriv->rtlhal.pfirmware);
191 rtlpriv->rtlhal.pfirmware = NULL;
192 }
193}
194
195static struct rtl_hal_ops rtl8723ae_hal_ops = {
196 .init_sw_vars = rtl8723ae_init_sw_vars,
197 .deinit_sw_vars = rtl8723ae_deinit_sw_vars,
198 .read_eeprom_info = rtl8723ae_read_eeprom_info,
199 .interrupt_recognized = rtl8723ae_interrupt_recognized,
200 .hw_init = rtl8723ae_hw_init,
201 .hw_disable = rtl8723ae_card_disable,
202 .hw_suspend = rtl8723ae_suspend,
203 .hw_resume = rtl8723ae_resume,
204 .enable_interrupt = rtl8723ae_enable_interrupt,
205 .disable_interrupt = rtl8723ae_disable_interrupt,
206 .set_network_type = rtl8723ae_set_network_type,
207 .set_chk_bssid = rtl8723ae_set_check_bssid,
208 .set_qos = rtl8723ae_set_qos,
209 .set_bcn_reg = rtl8723ae_set_beacon_related_registers,
210 .set_bcn_intv = rtl8723ae_set_beacon_interval,
211 .update_interrupt_mask = rtl8723ae_update_interrupt_mask,
212 .get_hw_reg = rtl8723ae_get_hw_reg,
213 .set_hw_reg = rtl8723ae_set_hw_reg,
214 .update_rate_tbl = rtl8723ae_update_hal_rate_tbl,
215 .fill_tx_desc = rtl8723ae_tx_fill_desc,
216 .fill_tx_cmddesc = rtl8723ae_tx_fill_cmddesc,
217 .query_rx_desc = rtl8723ae_rx_query_desc,
218 .set_channel_access = rtl8723ae_update_channel_access_setting,
219 .radio_onoff_checking = rtl8723ae_gpio_radio_on_off_checking,
220 .set_bw_mode = rtl8723ae_phy_set_bw_mode,
221 .switch_channel = rtl8723ae_phy_sw_chnl,
222 .dm_watchdog = rtl8723ae_dm_watchdog,
223 .scan_operation_backup = rtl8723ae_phy_scan_operation_backup,
224 .set_rf_power_state = rtl8723ae_phy_set_rf_power_state,
225 .led_control = rtl8723ae_led_control,
226 .set_desc = rtl8723ae_set_desc,
227 .get_desc = rtl8723ae_get_desc,
228 .tx_polling = rtl8723ae_tx_polling,
229 .enable_hw_sec = rtl8723ae_enable_hw_security_config,
230 .set_key = rtl8723ae_set_key,
231 .init_sw_leds = rtl8723ae_init_sw_leds,
232 .allow_all_destaddr = rtl8723ae_allow_all_destaddr,
233 .get_bbreg = rtl8723ae_phy_query_bb_reg,
234 .set_bbreg = rtl8723ae_phy_set_bb_reg,
235 .get_rfreg = rtl8723ae_phy_query_rf_reg,
236 .set_rfreg = rtl8723ae_phy_set_rf_reg,
237 .c2h_command_handle = rtl_8723e_c2h_command_handle,
238 .bt_wifi_media_status_notify = rtl_8723e_bt_wifi_media_status_notify,
239 .bt_coex_off_before_lps = rtl8723ae_bt_coex_off_before_lps,
240};
241
242static struct rtl_mod_params rtl8723ae_mod_params = {
243 .sw_crypto = false,
244 .inactiveps = true,
245 .swctrl_lps = false,
246 .fwctrl_lps = true,
247 .debug = DBG_EMERG,
248};
249
250static struct rtl_hal_cfg rtl8723ae_hal_cfg = {
251 .bar_id = 2,
252 .write_readback = true,
253 .name = "rtl8723ae_pci",
254 .fw_name = "rtlwifi/rtl8723aefw.bin",
255 .ops = &rtl8723ae_hal_ops,
256 .mod_params = &rtl8723ae_mod_params,
257 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
258 .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
259 .maps[SYS_CLK] = REG_SYS_CLKR,
260 .maps[MAC_RCR_AM] = AM,
261 .maps[MAC_RCR_AB] = AB,
262 .maps[MAC_RCR_ACRC32] = ACRC32,
263 .maps[MAC_RCR_ACF] = ACF,
264 .maps[MAC_RCR_AAP] = AAP,
265 .maps[EFUSE_TEST] = REG_EFUSE_TEST,
266 .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
267 .maps[EFUSE_CLK] = 0,
268 .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
269 .maps[EFUSE_PWC_EV12V] = PWC_EV12V,
270 .maps[EFUSE_FEN_ELDR] = FEN_ELDR,
271 .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
272 .maps[EFUSE_ANA8M] = ANA8M,
273 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
274 .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
275 .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
276 .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
277
278 .maps[RWCAM] = REG_CAMCMD,
279 .maps[WCAMI] = REG_CAMWRITE,
280 .maps[RCAMO] = REG_CAMREAD,
281 .maps[CAMDBG] = REG_CAMDBG,
282 .maps[SECR] = REG_SECCFG,
283 .maps[SEC_CAM_NONE] = CAM_NONE,
284 .maps[SEC_CAM_WEP40] = CAM_WEP40,
285 .maps[SEC_CAM_TKIP] = CAM_TKIP,
286 .maps[SEC_CAM_AES] = CAM_AES,
287 .maps[SEC_CAM_WEP104] = CAM_WEP104,
288
289 .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
290 .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
291 .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
292 .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
293 .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
294 .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
295 .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
296 .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
297 .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
298 .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
299 .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
300 .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
301 .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
302 .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
303 .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
304 .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
305
306 .maps[RTL_IMR_TXFOVW] = PHIMR_TXFOVW,
307 .maps[RTL_IMR_PSTIMEOUT] = PHIMR_PSTIMEOUT,
308 .maps[RTL_IMR_BcnInt] = PHIMR_BCNDMAINT0,
309 .maps[RTL_IMR_RXFOVW] = PHIMR_RXFOVW,
310 .maps[RTL_IMR_RDU] = PHIMR_RDU,
311 .maps[RTL_IMR_ATIMEND] = PHIMR_ATIMEND_E,
312 .maps[RTL_IMR_BDOK] = PHIMR_BCNDOK0,
313 .maps[RTL_IMR_MGNTDOK] = PHIMR_MGNTDOK,
314 .maps[RTL_IMR_TBDER] = PHIMR_TXBCNERR,
315 .maps[RTL_IMR_HIGHDOK] = PHIMR_HIGHDOK,
316 .maps[RTL_IMR_TBDOK] = PHIMR_TXBCNOK,
317 .maps[RTL_IMR_BKDOK] = PHIMR_BKDOK,
318 .maps[RTL_IMR_BEDOK] = PHIMR_BEDOK,
319 .maps[RTL_IMR_VIDOK] = PHIMR_VIDOK,
320 .maps[RTL_IMR_VODOK] = PHIMR_VODOK,
321 .maps[RTL_IMR_ROK] = PHIMR_ROK,
322 .maps[RTL_IBSS_INT_MASKS] = (PHIMR_BCNDMAINT0 |
323 PHIMR_TXBCNOK | PHIMR_TXBCNERR),
324 .maps[RTL_IMR_C2HCMD] = PHIMR_C2HCMD,
325
326
327 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M,
328 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M,
329 .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M,
330 .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M,
331 .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M,
332 .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M,
333 .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M,
334 .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M,
335 .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M,
336 .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M,
337 .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M,
338 .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M,
339
340 .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7,
341 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
342};
343
344static struct pci_device_id rtl8723ae_pci_ids[] __devinitdata = {
345 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8723, rtl8723ae_hal_cfg)},
346 {},
347};
348
349MODULE_DEVICE_TABLE(pci, rtl8723ae_pci_ids);
350
351MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
352MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
353MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
354MODULE_LICENSE("GPL");
355MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless");
356MODULE_FIRMWARE("rtlwifi/rtl8723aefw.bin");
357MODULE_FIRMWARE("rtlwifi/rtl8723aefw_B.bin");
358
359module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444);
360module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444);
361module_param_named(ips, rtl8723ae_mod_params.inactiveps, bool, 0444);
362module_param_named(swlps, rtl8723ae_mod_params.swctrl_lps, bool, 0444);
363module_param_named(fwlps, rtl8723ae_mod_params.fwctrl_lps, bool, 0444);
364MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
365MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
366MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
367MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
368MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
369
370static const struct dev_pm_ops rtlwifi_pm_ops = {
371 .suspend = rtl_pci_suspend,
372 .resume = rtl_pci_resume,
373 .freeze = rtl_pci_suspend,
374 .thaw = rtl_pci_resume,
375 .poweroff = rtl_pci_suspend,
376 .restore = rtl_pci_resume,
377};
378
379static struct pci_driver rtl8723ae_driver = {
380 .name = KBUILD_MODNAME,
381 .id_table = rtl8723ae_pci_ids,
382 .probe = rtl_pci_probe,
383 .remove = rtl_pci_disconnect,
384 .driver.pm = &rtlwifi_pm_ops,
385};
386
387module_pci_driver(rtl8723ae_driver);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h
new file mode 100644
index 000000000000..fc4fde5e3eb5
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h
@@ -0,0 +1,37 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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#ifndef __RTL8723E_SW_H__
31#define __RTL8723E_SW_H__
32
33int rtl8723ae_init_sw_vars(struct ieee80211_hw *hw);
34void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw);
35void rtl8723ae_init_var_map(struct ieee80211_hw *hw);
36
37#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/table.c b/drivers/net/wireless/rtlwifi/rtl8723ae/table.c
new file mode 100644
index 000000000000..9b0b50cc4ade
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/table.c
@@ -0,0 +1,738 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 * Created on 2010/ 5/18, 1:41
27 *
28 * Larry Finger <Larry.Finger@lwfinger.net>
29 *
30 *****************************************************************************/
31
32#include "table.h"
33
34u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH] = {
35 0x800, 0x80040000,
36 0x804, 0x00000003,
37 0x808, 0x0000fc00,
38 0x80c, 0x0000000a,
39 0x810, 0x10005388,
40 0x814, 0x020c3d10,
41 0x818, 0x02200385,
42 0x81c, 0x00000000,
43 0x820, 0x01000100,
44 0x824, 0x00390004,
45 0x828, 0x00000000,
46 0x82c, 0x00000000,
47 0x830, 0x00000000,
48 0x834, 0x00000000,
49 0x838, 0x00000000,
50 0x83c, 0x00000000,
51 0x840, 0x00010000,
52 0x844, 0x00000000,
53 0x848, 0x00000000,
54 0x84c, 0x00000000,
55 0x850, 0x00000000,
56 0x854, 0x00000000,
57 0x858, 0x569a569a,
58 0x85c, 0x001b25a4,
59 0x860, 0x66f60110,
60 0x864, 0x061f0130,
61 0x868, 0x00000000,
62 0x86c, 0x32323200,
63 0x870, 0x07000760,
64 0x874, 0x22004000,
65 0x878, 0x00000808,
66 0x87c, 0x00000000,
67 0x880, 0xc0083070,
68 0x884, 0x000004d5,
69 0x888, 0x00000000,
70 0x88c, 0xccc000c0,
71 0x890, 0x00000800,
72 0x894, 0xfffffffe,
73 0x898, 0x40302010,
74 0x89c, 0x00706050,
75 0x900, 0x00000000,
76 0x904, 0x00000023,
77 0x908, 0x00000000,
78 0x90c, 0x81121111,
79 0xa00, 0x00d047c8,
80 0xa04, 0x80ff000c,
81 0xa08, 0x8c838300,
82 0xa0c, 0x2e68120f,
83 0xa10, 0x9500bb78,
84 0xa14, 0x11144028,
85 0xa18, 0x00881117,
86 0xa1c, 0x89140f00,
87 0xa20, 0x1a1b0000,
88 0xa24, 0x090e1317,
89 0xa28, 0x00000204,
90 0xa2c, 0x00d30000,
91 0xa70, 0x101fbf00,
92 0xa74, 0x00000007,
93 0xa78, 0x00000900,
94 0xc00, 0x48071d40,
95 0xc04, 0x03a05611,
96 0xc08, 0x000000e4,
97 0xc0c, 0x6c6c6c6c,
98 0xc10, 0x08800000,
99 0xc14, 0x40000100,
100 0xc18, 0x08800000,
101 0xc1c, 0x40000100,
102 0xc20, 0x00000000,
103 0xc24, 0x00000000,
104 0xc28, 0x00000000,
105 0xc2c, 0x00000000,
106 0xc30, 0x69e9ac44,
107 0xc34, 0x469652cf,
108 0xc38, 0x49795994,
109 0xc3c, 0x0a97971c,
110 0xc40, 0x1f7c403f,
111 0xc44, 0x000100b7,
112 0xc48, 0xec020107,
113 0xc4c, 0x007f037f,
114 0xc50, 0x69543420,
115 0xc54, 0x43bc0094,
116 0xc58, 0x69543420,
117 0xc5c, 0x433c0094,
118 0xc60, 0x00000000,
119 0xc64, 0x7116848b,
120 0xc68, 0x47c00bff,
121 0xc6c, 0x00000036,
122 0xc70, 0x2c7f000d,
123 0xc74, 0x018610db,
124 0xc78, 0x0000001f,
125 0xc7c, 0x00b91612,
126 0xc80, 0x40000100,
127 0xc84, 0x20f60000,
128 0xc88, 0x40000100,
129 0xc8c, 0x20200000,
130 0xc90, 0x00121820,
131 0xc94, 0x00000000,
132 0xc98, 0x00121820,
133 0xc9c, 0x00007f7f,
134 0xca0, 0x00000000,
135 0xca4, 0x00000080,
136 0xca8, 0x00000000,
137 0xcac, 0x00000000,
138 0xcb0, 0x00000000,
139 0xcb4, 0x00000000,
140 0xcb8, 0x00000000,
141 0xcbc, 0x28000000,
142 0xcc0, 0x00000000,
143 0xcc4, 0x00000000,
144 0xcc8, 0x00000000,
145 0xccc, 0x00000000,
146 0xcd0, 0x00000000,
147 0xcd4, 0x00000000,
148 0xcd8, 0x64b22427,
149 0xcdc, 0x00766932,
150 0xce0, 0x00222222,
151 0xce4, 0x00000000,
152 0xce8, 0x37644302,
153 0xcec, 0x2f97d40c,
154 0xd00, 0x00080740,
155 0xd04, 0x00020401,
156 0xd08, 0x0000907f,
157 0xd0c, 0x20010201,
158 0xd10, 0xa0633333,
159 0xd14, 0x3333bc43,
160 0xd18, 0x7a8f5b6b,
161 0xd2c, 0xcc979975,
162 0xd30, 0x00000000,
163 0xd34, 0x80608000,
164 0xd38, 0x00000000,
165 0xd3c, 0x00027293,
166 0xd40, 0x00000000,
167 0xd44, 0x00000000,
168 0xd48, 0x00000000,
169 0xd4c, 0x00000000,
170 0xd50, 0x6437140a,
171 0xd54, 0x00000000,
172 0xd58, 0x00000000,
173 0xd5c, 0x30032064,
174 0xd60, 0x4653de68,
175 0xd64, 0x04518a3c,
176 0xd68, 0x00002101,
177 0xd6c, 0x2a201c16,
178 0xd70, 0x1812362e,
179 0xd74, 0x322c2220,
180 0xd78, 0x000e3c24,
181 0xe00, 0x2a2a2a2a,
182 0xe04, 0x2a2a2a2a,
183 0xe08, 0x03902a2a,
184 0xe10, 0x2a2a2a2a,
185 0xe14, 0x2a2a2a2a,
186 0xe18, 0x2a2a2a2a,
187 0xe1c, 0x2a2a2a2a,
188 0xe28, 0x00000000,
189 0xe30, 0x1000dc1f,
190 0xe34, 0x10008c1f,
191 0xe38, 0x02140102,
192 0xe3c, 0x681604c2,
193 0xe40, 0x01007c00,
194 0xe44, 0x01004800,
195 0xe48, 0xfb000000,
196 0xe4c, 0x000028d1,
197 0xe50, 0x1000dc1f,
198 0xe54, 0x10008c1f,
199 0xe58, 0x02140102,
200 0xe5c, 0x28160d05,
201 0xe60, 0x00000008,
202 0xe68, 0x001b25a4,
203 0xe6c, 0x631b25a0,
204 0xe70, 0x631b25a0,
205 0xe74, 0x081b25a0,
206 0xe78, 0x081b25a0,
207 0xe7c, 0x081b25a0,
208 0xe80, 0x081b25a0,
209 0xe84, 0x631b25a0,
210 0xe88, 0x081b25a0,
211 0xe8c, 0x631b25a0,
212 0xed0, 0x631b25a0,
213 0xed4, 0x631b25a0,
214 0xed8, 0x631b25a0,
215 0xedc, 0x001b25a0,
216 0xee0, 0x001b25a0,
217 0xeec, 0x6b1b25a0,
218 0xf14, 0x00000003,
219 0xf4c, 0x00000000,
220 0xf00, 0x00000300,
221};
222
223u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH] = {
224 0xe00, 0xffffffff, 0x0a0c0c0c,
225 0xe04, 0xffffffff, 0x02040608,
226 0xe08, 0x0000ff00, 0x00000000,
227 0x86c, 0xffffff00, 0x00000000,
228 0xe10, 0xffffffff, 0x0a0c0d0e,
229 0xe14, 0xffffffff, 0x02040608,
230 0xe18, 0xffffffff, 0x0a0c0d0e,
231 0xe1c, 0xffffffff, 0x02040608,
232 0x830, 0xffffffff, 0x0a0c0c0c,
233 0x834, 0xffffffff, 0x02040608,
234 0x838, 0xffffff00, 0x00000000,
235 0x86c, 0x000000ff, 0x00000000,
236 0x83c, 0xffffffff, 0x0a0c0d0e,
237 0x848, 0xffffffff, 0x02040608,
238 0x84c, 0xffffffff, 0x0a0c0d0e,
239 0x868, 0xffffffff, 0x02040608,
240 0xe00, 0xffffffff, 0x00000000,
241 0xe04, 0xffffffff, 0x00000000,
242 0xe08, 0x0000ff00, 0x00000000,
243 0x86c, 0xffffff00, 0x00000000,
244 0xe10, 0xffffffff, 0x00000000,
245 0xe14, 0xffffffff, 0x00000000,
246 0xe18, 0xffffffff, 0x00000000,
247 0xe1c, 0xffffffff, 0x00000000,
248 0x830, 0xffffffff, 0x00000000,
249 0x834, 0xffffffff, 0x00000000,
250 0x838, 0xffffff00, 0x00000000,
251 0x86c, 0x000000ff, 0x00000000,
252 0x83c, 0xffffffff, 0x00000000,
253 0x848, 0xffffffff, 0x00000000,
254 0x84c, 0xffffffff, 0x00000000,
255 0x868, 0xffffffff, 0x00000000,
256 0xe00, 0xffffffff, 0x04040404,
257 0xe04, 0xffffffff, 0x00020204,
258 0xe08, 0x0000ff00, 0x00000000,
259 0x86c, 0xffffff00, 0x00000000,
260 0xe10, 0xffffffff, 0x06060606,
261 0xe14, 0xffffffff, 0x00020406,
262 0xe18, 0xffffffff, 0x00000000,
263 0xe1c, 0xffffffff, 0x00000000,
264 0x830, 0xffffffff, 0x04040404,
265 0x834, 0xffffffff, 0x00020204,
266 0x838, 0xffffff00, 0x00000000,
267 0x86c, 0x000000ff, 0x00000000,
268 0x83c, 0xffffffff, 0x06060606,
269 0x848, 0xffffffff, 0x00020406,
270 0x84c, 0xffffffff, 0x00000000,
271 0x868, 0xffffffff, 0x00000000,
272 0xe00, 0xffffffff, 0x00000000,
273 0xe04, 0xffffffff, 0x00000000,
274 0xe08, 0x0000ff00, 0x00000000,
275 0x86c, 0xffffff00, 0x00000000,
276 0xe10, 0xffffffff, 0x00000000,
277 0xe14, 0xffffffff, 0x00000000,
278 0xe18, 0xffffffff, 0x00000000,
279 0xe1c, 0xffffffff, 0x00000000,
280 0x830, 0xffffffff, 0x00000000,
281 0x834, 0xffffffff, 0x00000000,
282 0x838, 0xffffff00, 0x00000000,
283 0x86c, 0x000000ff, 0x00000000,
284 0x83c, 0xffffffff, 0x00000000,
285 0x848, 0xffffffff, 0x00000000,
286 0x84c, 0xffffffff, 0x00000000,
287 0x868, 0xffffffff, 0x00000000,
288 0xe00, 0xffffffff, 0x00000000,
289 0xe04, 0xffffffff, 0x00000000,
290 0xe08, 0x0000ff00, 0x00000000,
291 0x86c, 0xffffff00, 0x00000000,
292 0xe10, 0xffffffff, 0x00000000,
293 0xe14, 0xffffffff, 0x00000000,
294 0xe18, 0xffffffff, 0x00000000,
295 0xe1c, 0xffffffff, 0x00000000,
296 0x830, 0xffffffff, 0x00000000,
297 0x834, 0xffffffff, 0x00000000,
298 0x838, 0xffffff00, 0x00000000,
299 0x86c, 0x000000ff, 0x00000000,
300 0x83c, 0xffffffff, 0x00000000,
301 0x848, 0xffffffff, 0x00000000,
302 0x84c, 0xffffffff, 0x00000000,
303 0x868, 0xffffffff, 0x00000000,
304 0xe00, 0xffffffff, 0x04040404,
305 0xe04, 0xffffffff, 0x00020204,
306 0xe08, 0x0000ff00, 0x00000000,
307 0x86c, 0xffffff00, 0x00000000,
308 0xe10, 0xffffffff, 0x00000000,
309 0xe14, 0xffffffff, 0x00000000,
310 0xe18, 0xffffffff, 0x00000000,
311 0xe1c, 0xffffffff, 0x00000000,
312 0x830, 0xffffffff, 0x04040404,
313 0x834, 0xffffffff, 0x00020204,
314 0x838, 0xffffff00, 0x00000000,
315 0x86c, 0x000000ff, 0x00000000,
316 0x83c, 0xffffffff, 0x00000000,
317 0x848, 0xffffffff, 0x00000000,
318 0x84c, 0xffffffff, 0x00000000,
319 0x868, 0xffffffff, 0x00000000,
320 0xe00, 0xffffffff, 0x00000000,
321 0xe04, 0xffffffff, 0x00000000,
322 0xe08, 0x0000ff00, 0x00000000,
323 0x86c, 0xffffff00, 0x00000000,
324 0xe10, 0xffffffff, 0x00000000,
325 0xe14, 0xffffffff, 0x00000000,
326 0xe18, 0xffffffff, 0x00000000,
327 0xe1c, 0xffffffff, 0x00000000,
328 0x830, 0xffffffff, 0x00000000,
329 0x834, 0xffffffff, 0x00000000,
330 0x838, 0xffffff00, 0x00000000,
331 0x86c, 0x000000ff, 0x00000000,
332 0x83c, 0xffffffff, 0x00000000,
333 0x848, 0xffffffff, 0x00000000,
334 0x84c, 0xffffffff, 0x00000000,
335 0x868, 0xffffffff, 0x00000000,
336};
337
338u32 RTL8723E_RADIOA_1TARRAY[Rtl8723ERADIOA_1TARRAYLENGTH] = {
339 0x000, 0x00030159,
340 0x001, 0x00031284,
341 0x002, 0x00098000,
342 0x003, 0x00018c63,
343 0x004, 0x000210e7,
344 0x009, 0x0002044f,
345 0x00a, 0x0001a3f1,
346 0x00b, 0x00014787,
347 0x00c, 0x000896fe,
348 0x00d, 0x0000e02c,
349 0x00e, 0x00039ce7,
350 0x00f, 0x00000451,
351 0x019, 0x00000000,
352 0x01a, 0x00030355,
353 0x01b, 0x00060a00,
354 0x01c, 0x000fc378,
355 0x01d, 0x000a1250,
356 0x01e, 0x0004445f,
357 0x01f, 0x00080001,
358 0x020, 0x0000b614,
359 0x021, 0x0006c000,
360 0x022, 0x00000000,
361 0x023, 0x00001558,
362 0x024, 0x00000060,
363 0x025, 0x00000483,
364 0x026, 0x0004f000,
365 0x027, 0x000ec7d9,
366 0x028, 0x00057730,
367 0x029, 0x00004783,
368 0x02a, 0x00000001,
369 0x02b, 0x00021334,
370 0x02a, 0x00000000,
371 0x02b, 0x00000054,
372 0x02a, 0x00000001,
373 0x02b, 0x00000808,
374 0x02b, 0x00053333,
375 0x02c, 0x0000000c,
376 0x02a, 0x00000002,
377 0x02b, 0x00000808,
378 0x02b, 0x0005b333,
379 0x02c, 0x0000000d,
380 0x02a, 0x00000003,
381 0x02b, 0x00000808,
382 0x02b, 0x00063333,
383 0x02c, 0x0000000d,
384 0x02a, 0x00000004,
385 0x02b, 0x00000808,
386 0x02b, 0x0006b333,
387 0x02c, 0x0000000d,
388 0x02a, 0x00000005,
389 0x02b, 0x00000808,
390 0x02b, 0x00073333,
391 0x02c, 0x0000000d,
392 0x02a, 0x00000006,
393 0x02b, 0x00000709,
394 0x02b, 0x0005b333,
395 0x02c, 0x0000000d,
396 0x02a, 0x00000007,
397 0x02b, 0x00000709,
398 0x02b, 0x00063333,
399 0x02c, 0x0000000d,
400 0x02a, 0x00000008,
401 0x02b, 0x0000060a,
402 0x02b, 0x0004b333,
403 0x02c, 0x0000000d,
404 0x02a, 0x00000009,
405 0x02b, 0x0000060a,
406 0x02b, 0x00053333,
407 0x02c, 0x0000000d,
408 0x02a, 0x0000000a,
409 0x02b, 0x0000060a,
410 0x02b, 0x0005b333,
411 0x02c, 0x0000000d,
412 0x02a, 0x0000000b,
413 0x02b, 0x0000060a,
414 0x02b, 0x00063333,
415 0x02c, 0x0000000d,
416 0x02a, 0x0000000c,
417 0x02b, 0x0000060a,
418 0x02b, 0x0006b333,
419 0x02c, 0x0000000d,
420 0x02a, 0x0000000d,
421 0x02b, 0x0000060a,
422 0x02b, 0x00073333,
423 0x02c, 0x0000000d,
424 0x02a, 0x0000000e,
425 0x02b, 0x0000050b,
426 0x02b, 0x00066666,
427 0x02c, 0x0000001a,
428 0x02a, 0x000e0000,
429 0x010, 0x0004000f,
430 0x011, 0x000e31fc,
431 0x010, 0x0006000f,
432 0x011, 0x000ff9f8,
433 0x010, 0x0002000f,
434 0x011, 0x000203f9,
435 0x010, 0x0003000f,
436 0x011, 0x000ff500,
437 0x010, 0x00000000,
438 0x011, 0x00000000,
439 0x010, 0x0008000f,
440 0x011, 0x0003f100,
441 0x010, 0x0009000f,
442 0x011, 0x00023100,
443 0x012, 0x00032000,
444 0x012, 0x00071000,
445 0x012, 0x000b0000,
446 0x012, 0x000fc000,
447 0x013, 0x000287b3,
448 0x013, 0x000244b7,
449 0x013, 0x000204ab,
450 0x013, 0x0001c49f,
451 0x013, 0x00018493,
452 0x013, 0x0001429b,
453 0x013, 0x00010299,
454 0x013, 0x0000c29c,
455 0x013, 0x000081a0,
456 0x013, 0x000040ac,
457 0x013, 0x00000020,
458 0x014, 0x0001944c,
459 0x014, 0x00059444,
460 0x014, 0x0009944c,
461 0x014, 0x000d9444,
462 0x015, 0x0000f424,
463 0x015, 0x0004f407,
464 0x015, 0x0008f424,
465 0x015, 0x000cf424,
466 0x016, 0x00000339,
467 0x016, 0x00040339,
468 0x016, 0x00080339,
469 0x016, 0x000c0336,
470 0x000, 0x00010159,
471 0x018, 0x0000f401,
472 0x0fe, 0x00000000,
473 0x0fe, 0x00000000,
474 0x01f, 0x00080003,
475 0x0fe, 0x00000000,
476 0x0fe, 0x00000000,
477 0x01e, 0x00044457,
478 0x01f, 0x00080000,
479 0x000, 0x00030159,
480};
481
482
483u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH] = {
484 0x0,
485};
486
487
488u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH] = {
489 0x420, 0x00000080,
490 0x423, 0x00000000,
491 0x430, 0x00000000,
492 0x431, 0x00000000,
493 0x432, 0x00000000,
494 0x433, 0x00000001,
495 0x434, 0x00000004,
496 0x435, 0x00000005,
497 0x436, 0x00000006,
498 0x437, 0x00000007,
499 0x438, 0x00000000,
500 0x439, 0x00000000,
501 0x43a, 0x00000000,
502 0x43b, 0x00000001,
503 0x43c, 0x00000004,
504 0x43d, 0x00000005,
505 0x43e, 0x00000006,
506 0x43f, 0x00000007,
507 0x440, 0x0000005d,
508 0x441, 0x00000001,
509 0x442, 0x00000000,
510 0x444, 0x00000015,
511 0x445, 0x000000f0,
512 0x446, 0x0000000f,
513 0x447, 0x00000000,
514 0x458, 0x00000041,
515 0x459, 0x000000a8,
516 0x45a, 0x00000072,
517 0x45b, 0x000000b9,
518 0x460, 0x00000066,
519 0x461, 0x00000066,
520 0x462, 0x00000008,
521 0x463, 0x00000003,
522 0x4c8, 0x000000ff,
523 0x4c9, 0x00000008,
524 0x4cc, 0x000000ff,
525 0x4cd, 0x000000ff,
526 0x4ce, 0x00000001,
527 0x500, 0x00000026,
528 0x501, 0x000000a2,
529 0x502, 0x0000002f,
530 0x503, 0x00000000,
531 0x504, 0x00000028,
532 0x505, 0x000000a3,
533 0x506, 0x0000005e,
534 0x507, 0x00000000,
535 0x508, 0x0000002b,
536 0x509, 0x000000a4,
537 0x50a, 0x0000005e,
538 0x50b, 0x00000000,
539 0x50c, 0x0000004f,
540 0x50d, 0x000000a4,
541 0x50e, 0x00000000,
542 0x50f, 0x00000000,
543 0x512, 0x0000001c,
544 0x514, 0x0000000a,
545 0x515, 0x00000010,
546 0x516, 0x0000000a,
547 0x517, 0x00000010,
548 0x51a, 0x00000016,
549 0x524, 0x0000000f,
550 0x525, 0x0000004f,
551 0x546, 0x00000040,
552 0x547, 0x00000000,
553 0x550, 0x00000010,
554 0x551, 0x00000010,
555 0x559, 0x00000002,
556 0x55a, 0x00000002,
557 0x55d, 0x000000ff,
558 0x605, 0x00000030,
559 0x608, 0x0000000e,
560 0x609, 0x0000002a,
561 0x652, 0x00000020,
562 0x63c, 0x0000000a,
563 0x63d, 0x0000000e,
564 0x63e, 0x0000000a,
565 0x63f, 0x0000000e,
566 0x66e, 0x00000005,
567 0x700, 0x00000021,
568 0x701, 0x00000043,
569 0x702, 0x00000065,
570 0x703, 0x00000087,
571 0x708, 0x00000021,
572 0x709, 0x00000043,
573 0x70a, 0x00000065,
574 0x70b, 0x00000087,
575};
576
577u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH] = {
578 0xc78, 0x7b000001,
579 0xc78, 0x7b010001,
580 0xc78, 0x7b020001,
581 0xc78, 0x7b030001,
582 0xc78, 0x7b040001,
583 0xc78, 0x7b050001,
584 0xc78, 0x7a060001,
585 0xc78, 0x79070001,
586 0xc78, 0x78080001,
587 0xc78, 0x77090001,
588 0xc78, 0x760a0001,
589 0xc78, 0x750b0001,
590 0xc78, 0x740c0001,
591 0xc78, 0x730d0001,
592 0xc78, 0x720e0001,
593 0xc78, 0x710f0001,
594 0xc78, 0x70100001,
595 0xc78, 0x6f110001,
596 0xc78, 0x6e120001,
597 0xc78, 0x6d130001,
598 0xc78, 0x6c140001,
599 0xc78, 0x6b150001,
600 0xc78, 0x6a160001,
601 0xc78, 0x69170001,
602 0xc78, 0x68180001,
603 0xc78, 0x67190001,
604 0xc78, 0x661a0001,
605 0xc78, 0x651b0001,
606 0xc78, 0x641c0001,
607 0xc78, 0x631d0001,
608 0xc78, 0x621e0001,
609 0xc78, 0x611f0001,
610 0xc78, 0x60200001,
611 0xc78, 0x49210001,
612 0xc78, 0x48220001,
613 0xc78, 0x47230001,
614 0xc78, 0x46240001,
615 0xc78, 0x45250001,
616 0xc78, 0x44260001,
617 0xc78, 0x43270001,
618 0xc78, 0x42280001,
619 0xc78, 0x41290001,
620 0xc78, 0x402a0001,
621 0xc78, 0x262b0001,
622 0xc78, 0x252c0001,
623 0xc78, 0x242d0001,
624 0xc78, 0x232e0001,
625 0xc78, 0x222f0001,
626 0xc78, 0x21300001,
627 0xc78, 0x20310001,
628 0xc78, 0x06320001,
629 0xc78, 0x05330001,
630 0xc78, 0x04340001,
631 0xc78, 0x03350001,
632 0xc78, 0x02360001,
633 0xc78, 0x01370001,
634 0xc78, 0x00380001,
635 0xc78, 0x00390001,
636 0xc78, 0x003a0001,
637 0xc78, 0x003b0001,
638 0xc78, 0x003c0001,
639 0xc78, 0x003d0001,
640 0xc78, 0x003e0001,
641 0xc78, 0x003f0001,
642 0xc78, 0x7b400001,
643 0xc78, 0x7b410001,
644 0xc78, 0x7b420001,
645 0xc78, 0x7b430001,
646 0xc78, 0x7b440001,
647 0xc78, 0x7b450001,
648 0xc78, 0x7a460001,
649 0xc78, 0x79470001,
650 0xc78, 0x78480001,
651 0xc78, 0x77490001,
652 0xc78, 0x764a0001,
653 0xc78, 0x754b0001,
654 0xc78, 0x744c0001,
655 0xc78, 0x734d0001,
656 0xc78, 0x724e0001,
657 0xc78, 0x714f0001,
658 0xc78, 0x70500001,
659 0xc78, 0x6f510001,
660 0xc78, 0x6e520001,
661 0xc78, 0x6d530001,
662 0xc78, 0x6c540001,
663 0xc78, 0x6b550001,
664 0xc78, 0x6a560001,
665 0xc78, 0x69570001,
666 0xc78, 0x68580001,
667 0xc78, 0x67590001,
668 0xc78, 0x665a0001,
669 0xc78, 0x655b0001,
670 0xc78, 0x645c0001,
671 0xc78, 0x635d0001,
672 0xc78, 0x625e0001,
673 0xc78, 0x615f0001,
674 0xc78, 0x60600001,
675 0xc78, 0x49610001,
676 0xc78, 0x48620001,
677 0xc78, 0x47630001,
678 0xc78, 0x46640001,
679 0xc78, 0x45650001,
680 0xc78, 0x44660001,
681 0xc78, 0x43670001,
682 0xc78, 0x42680001,
683 0xc78, 0x41690001,
684 0xc78, 0x406a0001,
685 0xc78, 0x266b0001,
686 0xc78, 0x256c0001,
687 0xc78, 0x246d0001,
688 0xc78, 0x236e0001,
689 0xc78, 0x226f0001,
690 0xc78, 0x21700001,
691 0xc78, 0x20710001,
692 0xc78, 0x06720001,
693 0xc78, 0x05730001,
694 0xc78, 0x04740001,
695 0xc78, 0x03750001,
696 0xc78, 0x02760001,
697 0xc78, 0x01770001,
698 0xc78, 0x00780001,
699 0xc78, 0x00790001,
700 0xc78, 0x007a0001,
701 0xc78, 0x007b0001,
702 0xc78, 0x007c0001,
703 0xc78, 0x007d0001,
704 0xc78, 0x007e0001,
705 0xc78, 0x007f0001,
706 0xc78, 0x3800001e,
707 0xc78, 0x3801001e,
708 0xc78, 0x3802001e,
709 0xc78, 0x3803001e,
710 0xc78, 0x3804001e,
711 0xc78, 0x3805001e,
712 0xc78, 0x3806001e,
713 0xc78, 0x3807001e,
714 0xc78, 0x3808001e,
715 0xc78, 0x3c09001e,
716 0xc78, 0x3e0a001e,
717 0xc78, 0x400b001e,
718 0xc78, 0x440c001e,
719 0xc78, 0x480d001e,
720 0xc78, 0x4c0e001e,
721 0xc78, 0x500f001e,
722 0xc78, 0x5210001e,
723 0xc78, 0x5611001e,
724 0xc78, 0x5a12001e,
725 0xc78, 0x5e13001e,
726 0xc78, 0x6014001e,
727 0xc78, 0x6015001e,
728 0xc78, 0x6016001e,
729 0xc78, 0x6217001e,
730 0xc78, 0x6218001e,
731 0xc78, 0x6219001e,
732 0xc78, 0x621a001e,
733 0xc78, 0x621b001e,
734 0xc78, 0x621c001e,
735 0xc78, 0x621d001e,
736 0xc78, 0x621e001e,
737 0xc78, 0x621f001e,
738};
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/table.h b/drivers/net/wireless/rtlwifi/rtl8723ae/table.h
new file mode 100644
index 000000000000..f5ce71375c20
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/table.h
@@ -0,0 +1,50 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 * Created on 2010/ 5/18, 1:41
27 *
28 * Larry Finger <Larry.Finger@lwfinger.net>
29 *
30 *****************************************************************************/
31
32#ifndef __RTL8723E_TABLE__H_
33#define __RTL8723E_TABLE__H_
34
35#include <linux/types.h>
36
37#define RTL8723E_PHY_REG_1TARRAY_LENGTH 372
38extern u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH];
39#define RTL8723E_PHY_REG_ARRAY_PGLENGTH 336
40extern u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH];
41#define Rtl8723ERADIOA_1TARRAYLENGTH 282
42extern u32 RTL8723E_RADIOA_1TARRAY[Rtl8723ERADIOA_1TARRAYLENGTH];
43#define RTL8723E_RADIOB_1TARRAYLENGTH 1
44extern u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH];
45#define RTL8723E_MACARRAYLENGTH 172
46extern u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH];
47#define RTL8723E_AGCTAB_1TARRAYLENGTH 320
48extern u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH];
49
50#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
new file mode 100644
index 000000000000..9719d541e380
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
@@ -0,0 +1,670 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 "../stats.h"
34#include "reg.h"
35#include "def.h"
36#include "phy.h"
37#include "trx.h"
38#include "led.h"
39
40static u8 _rtl8723ae_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
41{
42 __le16 fc = rtl_get_fc(skb);
43
44 if (unlikely(ieee80211_is_beacon(fc)))
45 return QSLT_BEACON;
46 if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
47 return QSLT_MGNT;
48
49 return skb->priority;
50}
51
52static void _rtl8723ae_query_rxphystatus(struct ieee80211_hw *hw,
53 struct rtl_stats *pstatus, u8 *pdesc,
54 struct rx_fwinfo_8723e *p_drvinfo,
55 bool bpacket_match_bssid,
56 bool bpacket_toself, bool packet_beacon)
57{
58 struct rtl_priv *rtlpriv = rtl_priv(hw);
59 struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
60 struct phy_sts_cck_8723e_t *cck_buf;
61 s8 rx_pwr_all, rx_pwr[4];
62 u8 rf_rx_num = 0, evm, pwdb_all;
63 u8 i, max_spatial_stream;
64 u32 rssi, total_rssi = 0;
65 bool is_cck = pstatus->is_cck;
66
67 /* Record it for next packet processing */
68 pstatus->packet_matchbssid = bpacket_match_bssid;
69 pstatus->packet_toself = bpacket_toself;
70 pstatus->packet_beacon = packet_beacon;
71 pstatus->rx_mimo_sig_qual[0] = -1;
72 pstatus->rx_mimo_sig_qual[1] = -1;
73
74 if (is_cck) {
75 u8 report, cck_highpwr;
76
77 /* CCK Driver info Structure is not the same as OFDM packet. */
78 cck_buf = (struct phy_sts_cck_8723e_t *)p_drvinfo;
79
80 /* (1)Hardware does not provide RSSI for CCK
81 * (2)PWDB, Average PWDB cacluated by
82 * hardware (for rate adaptive)
83 */
84 if (ppsc->rfpwr_state == ERFON)
85 cck_highpwr = (u8) rtl_get_bbreg(hw,
86 RFPGA0_XA_HSSIPARAMETER2,
87 BIT(9));
88 else
89 cck_highpwr = false;
90
91 if (!cck_highpwr) {
92 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
93 report = cck_buf->cck_agc_rpt & 0xc0;
94 report = report >> 6;
95 switch (report) {
96 case 0x3:
97 rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
98 break;
99 case 0x2:
100 rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
101 break;
102 case 0x1:
103 rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
104 break;
105 case 0x0:
106 rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
107 break;
108 }
109 } else {
110 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
111 report = p_drvinfo->cfosho[0] & 0x60;
112 report = report >> 5;
113 switch (report) {
114 case 0x3:
115 rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
116 break;
117 case 0x2:
118 rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
119 break;
120 case 0x1:
121 rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
122 break;
123 case 0x0:
124 rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
125 break;
126 }
127 }
128
129 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
130 /* CCK gain is smaller than OFDM/MCS gain,
131 * so we add gain diff. From experience, the val is 6
132 */
133 pwdb_all += 6;
134 if (pwdb_all > 100)
135 pwdb_all = 100;
136 /* modify the offset to make the same
137 * gain index with OFDM.
138 */
139 if (pwdb_all > 34 && pwdb_all <= 42)
140 pwdb_all -= 2;
141 else if (pwdb_all > 26 && pwdb_all <= 34)
142 pwdb_all -= 6;
143 else if (pwdb_all > 14 && pwdb_all <= 26)
144 pwdb_all -= 8;
145 else if (pwdb_all > 4 && pwdb_all <= 14)
146 pwdb_all -= 4;
147
148 pstatus->rx_pwdb_all = pwdb_all;
149 pstatus->recvsignalpower = rx_pwr_all;
150
151 /* (3) Get Signal Quality (EVM) */
152 if (bpacket_match_bssid) {
153 u8 sq;
154
155 if (pstatus->rx_pwdb_all > 40) {
156 sq = 100;
157 } else {
158 sq = cck_buf->sq_rpt;
159 if (sq > 64)
160 sq = 0;
161 else if (sq < 20)
162 sq = 100;
163 else
164 sq = ((64 - sq) * 100) / 44;
165 }
166
167 pstatus->signalquality = sq;
168 pstatus->rx_mimo_sig_qual[0] = sq;
169 pstatus->rx_mimo_sig_qual[1] = -1;
170 }
171 } else {
172 rtlpriv->dm.rfpath_rxenable[0] =
173 rtlpriv->dm.rfpath_rxenable[1] = true;
174
175 /* (1)Get RSSI for HT rate */
176 for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
177
178 /* we will judge RF RX path now. */
179 if (rtlpriv->dm.rfpath_rxenable[i])
180 rf_rx_num++;
181
182 rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f)*2) - 110;
183
184 /* Translate DBM to percentage. */
185 rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
186 total_rssi += rssi;
187
188 /* Get Rx snr value in DB */
189 rtlpriv->stats.rx_snr_db[i] = (p_drvinfo->rxsnr[i] / 2);
190
191 /* Record Signal Strength for next packet */
192 if (bpacket_match_bssid)
193 pstatus->rx_mimo_signalstrength[i] = (u8) rssi;
194 }
195
196 /* (2)PWDB, Average PWDB cacluated by
197 * hardware (for rate adaptive)
198 */
199 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
200
201 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
202 pstatus->rx_pwdb_all = pwdb_all;
203 pstatus->rxpower = rx_pwr_all;
204 pstatus->recvsignalpower = rx_pwr_all;
205
206 /* (3)EVM of HT rate */
207 if (pstatus->is_ht && pstatus->rate >= DESC92_RATEMCS8 &&
208 pstatus->rate <= DESC92_RATEMCS15)
209 max_spatial_stream = 2;
210 else
211 max_spatial_stream = 1;
212
213 for (i = 0; i < max_spatial_stream; i++) {
214 evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
215
216 if (bpacket_match_bssid) {
217 /* Fill value in RFD, Get the first
218 * spatial stream only
219 */
220 if (i == 0)
221 pstatus->signalquality = (evm & 0xff);
222 pstatus->rx_mimo_sig_qual[i] = (evm & 0xff);
223 }
224 }
225 }
226
227 /* UI BSS List signal strength(in percentage),
228 * make it good looking, from 0~100.
229 */
230 if (is_cck)
231 pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
232 pwdb_all));
233 else if (rf_rx_num != 0)
234 pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
235 total_rssi /= rf_rx_num));
236}
237
238static void _rtl8723ae_translate_rx_signal_stuff(struct ieee80211_hw *hw,
239 struct sk_buff *skb, struct rtl_stats *pstatus,
240 u8 *pdesc, struct rx_fwinfo_8723e *p_drvinfo)
241{
242 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
243 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
244 struct ieee80211_hdr *hdr;
245 u8 *tmp_buf;
246 u8 *praddr;
247 u8 *psaddr;
248 __le16 fc;
249 u16 type;
250 bool packet_matchbssid, packet_toself, packet_beacon;
251
252 tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift;
253
254 hdr = (struct ieee80211_hdr *)tmp_buf;
255 fc = hdr->frame_control;
256 type = WLAN_FC_GET_TYPE(fc);
257 praddr = hdr->addr1;
258 psaddr = ieee80211_get_SA(hdr);
259
260 packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
261 (!compare_ether_addr(mac->bssid,
262 (le16_to_cpu(fc) & IEEE80211_FCTL_TODS) ?
263 hdr->addr1 : (le16_to_cpu(fc) &
264 IEEE80211_FCTL_FROMDS) ?
265 hdr->addr2 : hdr->addr3)) && (!pstatus->hwerror) &&
266 (!pstatus->crc) && (!pstatus->icv));
267
268 packet_toself = packet_matchbssid &&
269 (!compare_ether_addr(praddr, rtlefuse->dev_addr));
270
271 if (ieee80211_is_beacon(fc))
272 packet_beacon = true;
273
274 _rtl8723ae_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo,
275 packet_matchbssid, packet_toself,
276 packet_beacon);
277
278 rtl_process_phyinfo(hw, tmp_buf, pstatus);
279}
280
281bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,
282 struct rtl_stats *status,
283 struct ieee80211_rx_status *rx_status,
284 u8 *pdesc, struct sk_buff *skb)
285{
286 struct rx_fwinfo_8723e *p_drvinfo;
287 struct ieee80211_hdr *hdr;
288 u32 phystatus = GET_RX_DESC_PHYST(pdesc);
289
290 status->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
291 status->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
292 RX_DRV_INFO_SIZE_UNIT;
293 status->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
294 status->icv = (u16) GET_RX_DESC_ICV(pdesc);
295 status->crc = (u16) GET_RX_DESC_CRC32(pdesc);
296 status->hwerror = (status->crc | status->icv);
297 status->decrypted = !GET_RX_DESC_SWDEC(pdesc);
298 status->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
299 status->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
300 status->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
301 status->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
302 && (GET_RX_DESC_FAGGR(pdesc) == 1));
303 status->timestamp_low = GET_RX_DESC_TSFL(pdesc);
304 status->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
305 status->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
306
307 status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate);
308
309 rx_status->freq = hw->conf.channel->center_freq;
310 rx_status->band = hw->conf.channel->band;
311
312 hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size
313 + status->rx_bufshift);
314
315 if (status->crc)
316 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
317
318 if (status->rx_is40Mhzpacket)
319 rx_status->flag |= RX_FLAG_40MHZ;
320
321 if (status->is_ht)
322 rx_status->flag |= RX_FLAG_HT;
323
324 rx_status->flag |= RX_FLAG_MACTIME_MPDU;
325
326 /* hw will set status->decrypted true, if it finds the
327 * frame is open data frame or mgmt frame.
328 * Thus hw will not decrypt a robust managment frame
329 * for IEEE80211w but still set status->decrypted
330 * true, so here we should set it back to undecrypted
331 * for IEEE80211w frame, and mac80211 sw will help
332 * to decrypt it
333 */
334 if (status->decrypted) {
335 if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
336 (ieee80211_has_protected(hdr->frame_control)))
337 rx_status->flag &= ~RX_FLAG_DECRYPTED;
338 else
339 rx_status->flag |= RX_FLAG_DECRYPTED;
340 }
341
342 /* rate_idx: index of data rate into band's
343 * supported rates or MCS index if HT rates
344 * are use (RX_FLAG_HT)
345 */
346 rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht,
347 status->rate, false);
348
349 rx_status->mactime = status->timestamp_low;
350 if (phystatus == true) {
351 p_drvinfo = (struct rx_fwinfo_8723e *)(skb->data +
352 status->rx_bufshift);
353
354 _rtl8723ae_translate_rx_signal_stuff(hw,
355 skb, status, pdesc, p_drvinfo);
356 }
357
358 /*rx_status->qual = status->signal; */
359 rx_status->signal = status->recvsignalpower + 10;
360 /*rx_status->noise = -status->noise; */
361
362 return true;
363}
364
365void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,
366 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
367 struct ieee80211_tx_info *info,
368 struct ieee80211_sta *sta,
369 struct sk_buff *skb, u8 hw_queue,
370 struct rtl_tcb_desc *ptcdesc)
371{
372 struct rtl_priv *rtlpriv = rtl_priv(hw);
373 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
374 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
375 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
376 bool defaultadapter = true;
377 u8 *pdesc = (u8 *) pdesc_tx;
378 u16 seq_number;
379 __le16 fc = hdr->frame_control;
380 u8 fw_qsel = _rtl8723ae_map_hwqueue_to_fwqueue(skb, hw_queue);
381 bool firstseg = ((hdr->seq_ctrl &
382 cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
383 bool lastseg = ((hdr->frame_control &
384 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
385 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
386 skb->data, skb->len,
387 PCI_DMA_TODEVICE);
388 u8 bw_40 = 0;
389
390 if (mac->opmode == NL80211_IFTYPE_STATION) {
391 bw_40 = mac->bw_40;
392 } else if (mac->opmode == NL80211_IFTYPE_AP ||
393 mac->opmode == NL80211_IFTYPE_ADHOC) {
394 if (sta)
395 bw_40 = sta->ht_cap.cap &
396 IEEE80211_HT_CAP_SUP_WIDTH_20_40;
397 }
398
399 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
400
401 rtl_get_tcb_desc(hw, info, sta, skb, ptcdesc);
402
403 CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8723e));
404
405 if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
406 firstseg = true;
407 lastseg = true;
408 }
409
410 if (firstseg) {
411 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
412
413 SET_TX_DESC_TX_RATE(pdesc, ptcdesc->hw_rate);
414
415 if (ptcdesc->use_shortgi || ptcdesc->use_shortpreamble)
416 SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
417
418 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
419 SET_TX_DESC_AGG_BREAK(pdesc, 1);
420 SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
421 }
422 SET_TX_DESC_SEQ(pdesc, seq_number);
423
424 SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcdesc->rts_enable &&
425 !ptcdesc->
426 cts_enable) ? 1 : 0));
427 SET_TX_DESC_HW_RTS_ENABLE(pdesc,
428 ((ptcdesc->rts_enable
429 || ptcdesc->cts_enable) ? 1 : 0));
430 SET_TX_DESC_CTS2SELF(pdesc, ((ptcdesc->cts_enable) ? 1 : 0));
431 SET_TX_DESC_RTS_STBC(pdesc, ((ptcdesc->rts_stbc) ? 1 : 0));
432
433 SET_TX_DESC_RTS_RATE(pdesc, ptcdesc->rts_rate);
434 SET_TX_DESC_RTS_BW(pdesc, 0);
435 SET_TX_DESC_RTS_SC(pdesc, ptcdesc->rts_sc);
436 SET_TX_DESC_RTS_SHORT(pdesc,
437 ((ptcdesc->rts_rate <= DESC92_RATE54M) ?
438 (ptcdesc->rts_use_shortpreamble ? 1 : 0)
439 : (ptcdesc->rts_use_shortgi ? 1 : 0)));
440
441 if (bw_40) {
442 if (ptcdesc->packet_bw) {
443 SET_TX_DESC_DATA_BW(pdesc, 1);
444 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
445 } else {
446 SET_TX_DESC_DATA_BW(pdesc, 0);
447 SET_TX_DESC_TX_SUB_CARRIER(pdesc,
448 mac->cur_40_prime_sc);
449 }
450 } else {
451 SET_TX_DESC_DATA_BW(pdesc, 0);
452 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
453 }
454
455 SET_TX_DESC_LINIP(pdesc, 0);
456 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
457
458 if (sta) {
459 u8 ampdu_density = sta->ht_cap.ampdu_density;
460 SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
461 }
462
463 if (info->control.hw_key) {
464 struct ieee80211_key_conf *keyconf =
465 info->control.hw_key;
466
467 switch (keyconf->cipher) {
468 case WLAN_CIPHER_SUITE_WEP40:
469 case WLAN_CIPHER_SUITE_WEP104:
470 case WLAN_CIPHER_SUITE_TKIP:
471 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
472 break;
473 case WLAN_CIPHER_SUITE_CCMP:
474 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
475 break;
476 default:
477 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
478 break;
479 }
480 }
481
482 SET_TX_DESC_PKT_ID(pdesc, 0);
483 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
484
485 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
486 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
487 SET_TX_DESC_DISABLE_FB(pdesc, 0);
488 SET_TX_DESC_USE_RATE(pdesc, ptcdesc->use_driver_rate ? 1 : 0);
489
490 if (ieee80211_is_data_qos(fc)) {
491 if (mac->rdg_en) {
492 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
493 "Enable RDG function.\n");
494 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
495 SET_TX_DESC_HTC(pdesc, 1);
496 }
497 }
498 }
499
500 SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
501 SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
502
503 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
504
505 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
506
507 if (rtlpriv->dm.useramask) {
508 SET_TX_DESC_RATE_ID(pdesc, ptcdesc->ratr_index);
509 SET_TX_DESC_MACID(pdesc, ptcdesc->mac_id);
510 } else {
511 SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcdesc->ratr_index);
512 SET_TX_DESC_MACID(pdesc, ptcdesc->ratr_index);
513 }
514
515 if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
516 SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1);
517
518 if (!defaultadapter)
519 SET_TX_DESC_HWSEQ_SEL_8723(pdesc, 1);
520 }
521
522 SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
523
524 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
525 is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
526 SET_TX_DESC_BMC(pdesc, 1);
527 }
528
529 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
530}
531
532void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw,
533 u8 *pdesc, bool firstseg,
534 bool lastseg, struct sk_buff *skb)
535{
536 struct rtl_priv *rtlpriv = rtl_priv(hw);
537 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
538 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
539 u8 fw_queue = QSLT_BEACON;
540 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
541 skb->data, skb->len,
542 PCI_DMA_TODEVICE);
543 __le16 fc = hdr->frame_control;
544
545 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
546
547 if (firstseg)
548 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
549
550 SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
551
552 SET_TX_DESC_SEQ(pdesc, 0);
553
554 SET_TX_DESC_LINIP(pdesc, 0);
555
556 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
557
558 SET_TX_DESC_FIRST_SEG(pdesc, 1);
559 SET_TX_DESC_LAST_SEG(pdesc, 1);
560
561 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
562
563 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
564
565 SET_TX_DESC_RATE_ID(pdesc, 7);
566 SET_TX_DESC_MACID(pdesc, 0);
567
568 SET_TX_DESC_OWN(pdesc, 1);
569
570 SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
571
572 SET_TX_DESC_FIRST_SEG(pdesc, 1);
573 SET_TX_DESC_LAST_SEG(pdesc, 1);
574
575 SET_TX_DESC_OFFSET(pdesc, 0x20);
576
577 SET_TX_DESC_USE_RATE(pdesc, 1);
578
579 if (!ieee80211_is_data_qos(fc)) {
580 SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1);
581 /* SET_TX_DESC_HWSEQ_EN(pdesc, 1); */
582 /* SET_TX_DESC_PKT_ID(pdesc, 8); */
583 }
584
585 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
586 "H2C Tx Cmd Content\n",
587 pdesc, TX_DESC_SIZE);
588}
589
590void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
591{
592 if (istx == true) {
593 switch (desc_name) {
594 case HW_DESC_OWN:
595 SET_TX_DESC_OWN(pdesc, 1);
596 break;
597 case HW_DESC_TX_NEXTDESC_ADDR:
598 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
599 break;
600 default:
601 RT_ASSERT(false, "ERR txdesc :%d not process\n",
602 desc_name);
603 break;
604 }
605 } else {
606 switch (desc_name) {
607 case HW_DESC_RXOWN:
608 SET_RX_DESC_OWN(pdesc, 1);
609 break;
610 case HW_DESC_RXBUFF_ADDR:
611 SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
612 break;
613 case HW_DESC_RXPKT_LEN:
614 SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
615 break;
616 case HW_DESC_RXERO:
617 SET_RX_DESC_EOR(pdesc, 1);
618 break;
619 default:
620 RT_ASSERT(false, "ERR rxdesc :%d not process\n",
621 desc_name);
622 break;
623 }
624 }
625}
626
627u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name)
628{
629 u32 ret = 0;
630
631 if (istx == true) {
632 switch (desc_name) {
633 case HW_DESC_OWN:
634 ret = GET_TX_DESC_OWN(pdesc);
635 break;
636 case HW_DESC_TXBUFF_ADDR:
637 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc);
638 break;
639 default:
640 RT_ASSERT(false, "ERR txdesc :%d not process\n",
641 desc_name);
642 break;
643 }
644 } else {
645 switch (desc_name) {
646 case HW_DESC_OWN:
647 ret = GET_RX_DESC_OWN(pdesc);
648 break;
649 case HW_DESC_RXPKT_LEN:
650 ret = GET_RX_DESC_PKT_LEN(pdesc);
651 break;
652 default:
653 RT_ASSERT(false, "ERR rxdesc :%d not process\n",
654 desc_name);
655 break;
656 }
657 }
658 return ret;
659}
660
661void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
662{
663 struct rtl_priv *rtlpriv = rtl_priv(hw);
664 if (hw_queue == BEACON_QUEUE) {
665 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
666 } else {
667 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
668 BIT(0) << (hw_queue));
669 }
670}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h
new file mode 100644
index 000000000000..ad05b54bc0f1
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h
@@ -0,0 +1,725 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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#ifndef __RTL8723E_TRX_H__
31#define __RTL8723E_TRX_H__
32
33#define TX_DESC_SIZE 64
34#define TX_DESC_AGGR_SUBFRAME_SIZE 32
35
36#define RX_DESC_SIZE 32
37#define RX_DRV_INFO_SIZE_UNIT 8
38
39#define TX_DESC_NEXT_DESC_OFFSET 40
40#define USB_HWDESC_HEADER_LEN 32
41#define CRCLENGTH 4
42
43#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
44 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
45#define SET_TX_DESC_OFFSET(__pdesc, __val) \
46 SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
47#define SET_TX_DESC_BMC(__pdesc, __val) \
48 SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
49#define SET_TX_DESC_HTC(__pdesc, __val) \
50 SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
51#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
52 SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
53#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
54 SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
55#define SET_TX_DESC_LINIP(__pdesc, __val) \
56 SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
57#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
58 SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
59#define SET_TX_DESC_GF(__pdesc, __val) \
60 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
61#define SET_TX_DESC_OWN(__pdesc, __val) \
62 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
63
64#define GET_TX_DESC_PKT_SIZE(__pdesc) \
65 LE_BITS_TO_4BYTE(__pdesc, 0, 16)
66#define GET_TX_DESC_OFFSET(__pdesc) \
67 LE_BITS_TO_4BYTE(__pdesc, 16, 8)
68#define GET_TX_DESC_BMC(__pdesc) \
69 LE_BITS_TO_4BYTE(__pdesc, 24, 1)
70#define GET_TX_DESC_HTC(__pdesc) \
71 LE_BITS_TO_4BYTE(__pdesc, 25, 1)
72#define GET_TX_DESC_LAST_SEG(__pdesc) \
73 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
74#define GET_TX_DESC_FIRST_SEG(__pdesc) \
75 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
76#define GET_TX_DESC_LINIP(__pdesc) \
77 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
78#define GET_TX_DESC_NO_ACM(__pdesc) \
79 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
80#define GET_TX_DESC_GF(__pdesc) \
81 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
82#define GET_TX_DESC_OWN(__pdesc) \
83 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
84
85#define SET_TX_DESC_MACID(__pdesc, __val) \
86 SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val)
87#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
88 SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val)
89#define SET_TX_DESC_BK(__pdesc, __val) \
90 SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val)
91#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
92 SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val)
93#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
94 SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
95#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
96 SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
97#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
98 SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
99#define SET_TX_DESC_PIFS(__pdesc, __val) \
100 SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
101#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
102 SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val)
103#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
104 SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val)
105#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
106 SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
107#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
108 SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
109#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
110 SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val)
111
112#define GET_TX_DESC_MACID(__pdesc) \
113 LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
114#define GET_TX_DESC_AGG_ENABLE(__pdesc) \
115 LE_BITS_TO_4BYTE(__pdesc+4, 5, 1)
116#define GET_TX_DESC_AGG_BREAK(__pdesc) \
117 LE_BITS_TO_4BYTE(__pdesc+4, 6, 1)
118#define GET_TX_DESC_RDG_ENABLE(__pdesc) \
119 LE_BITS_TO_4BYTE(__pdesc+4, 7, 1)
120#define GET_TX_DESC_QUEUE_SEL(__pdesc) \
121 LE_BITS_TO_4BYTE(__pdesc+4, 8, 5)
122#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \
123 LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
124#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \
125 LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
126#define GET_TX_DESC_PIFS(__pdesc) \
127 LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
128#define GET_TX_DESC_RATE_ID(__pdesc) \
129 LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
130#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \
131 LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
132#define GET_TX_DESC_EN_DESC_ID(__pdesc) \
133 LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
134#define GET_TX_DESC_SEC_TYPE(__pdesc) \
135 LE_BITS_TO_4BYTE(__pdesc+4, 22, 2)
136#define GET_TX_DESC_PKT_OFFSET(__pdesc) \
137 LE_BITS_TO_4BYTE(__pdesc+4, 24, 8)
138
139#define SET_TX_DESC_RTS_RC(__pdesc, __val) \
140 SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val)
141#define SET_TX_DESC_DATA_RC(__pdesc, __val) \
142 SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val)
143#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
144 SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
145#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
146 SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
147#define SET_TX_DESC_RAW(__pdesc, __val) \
148 SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
149#define SET_TX_DESC_CCX(__pdesc, __val) \
150 SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
151#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
152 SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
153#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
154 SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val)
155#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
156 SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val)
157#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \
158 SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val)
159#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \
160 SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val)
161#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \
162 SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val)
163
164#define GET_TX_DESC_RTS_RC(__pdesc) \
165 LE_BITS_TO_4BYTE(__pdesc+8, 0, 6)
166#define GET_TX_DESC_DATA_RC(__pdesc) \
167 LE_BITS_TO_4BYTE(__pdesc+8, 6, 6)
168#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \
169 LE_BITS_TO_4BYTE(__pdesc+8, 14, 2)
170#define GET_TX_DESC_MORE_FRAG(__pdesc) \
171 LE_BITS_TO_4BYTE(__pdesc+8, 17, 1)
172#define GET_TX_DESC_RAW(__pdesc) \
173 LE_BITS_TO_4BYTE(__pdesc+8, 18, 1)
174#define GET_TX_DESC_CCX(__pdesc) \
175 LE_BITS_TO_4BYTE(__pdesc+8, 19, 1)
176#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \
177 LE_BITS_TO_4BYTE(__pdesc+8, 20, 3)
178#define GET_TX_DESC_ANTSEL_A(__pdesc) \
179 LE_BITS_TO_4BYTE(__pdesc+8, 24, 1)
180#define GET_TX_DESC_ANTSEL_B(__pdesc) \
181 LE_BITS_TO_4BYTE(__pdesc+8, 25, 1)
182#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \
183 LE_BITS_TO_4BYTE(__pdesc+8, 26, 2)
184#define GET_TX_DESC_TX_ANTL(__pdesc) \
185 LE_BITS_TO_4BYTE(__pdesc+8, 28, 2)
186#define GET_TX_DESC_TX_ANT_HT(__pdesc) \
187 LE_BITS_TO_4BYTE(__pdesc+8, 30, 2)
188
189#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
190 SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val)
191#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
192 SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val)
193#define SET_TX_DESC_SEQ(__pdesc, __val) \
194 SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val)
195#define SET_TX_DESC_PKT_ID(__pdesc, __val) \
196 SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val)
197
198#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \
199 LE_BITS_TO_4BYTE(__pdesc+12, 0, 8)
200#define GET_TX_DESC_TAIL_PAGE(__pdesc) \
201 LE_BITS_TO_4BYTE(__pdesc+12, 8, 8)
202#define GET_TX_DESC_SEQ(__pdesc) \
203 LE_BITS_TO_4BYTE(__pdesc+12, 16, 12)
204#define GET_TX_DESC_PKT_ID(__pdesc) \
205 LE_BITS_TO_4BYTE(__pdesc+12, 28, 4)
206
207/* For RTL8723 */
208#define SET_TX_DESC_TRIGGER_INT(__pdesc, __val) \
209 SET_BITS_TO_LE_4BYTE(__pdesc+12, 30, 1, __val)
210#define SET_TX_DESC_HWSEQ_EN_8723(__pdesc, __val) \
211 SET_BITS_TO_LE_4BYTE(__pdesc+12, 31, 1, __val)
212#define SET_TX_DESC_HWSEQ_SEL_8723(__pTxDesc, __Value) \
213 SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 6, 2, __Value)
214
215#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
216 SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val)
217#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \
218 SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val)
219#define SET_TX_DESC_QOS(__pdesc, __val) \
220 SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val)
221#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
222 SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val)
223#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
224 SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val)
225#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
226 SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val)
227#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
228 SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val)
229#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
230 SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val)
231#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
232 SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val)
233#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
234 SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val)
235#define SET_TX_DESC_PORT_ID(__pdesc, __val) \
236 SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val)
237#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \
238 SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val)
239#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \
240 SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val)
241#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
242 SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val)
243#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
244 SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val)
245#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \
246 SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val)
247#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
248 SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val)
249#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
250 SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val)
251#define SET_TX_DESC_RTS_BW(__pdesc, __val) \
252 SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val)
253#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
254 SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val)
255#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
256 SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val)
257
258#define GET_TX_DESC_RTS_RATE(__pdesc) \
259 LE_BITS_TO_4BYTE(__pdesc+16, 0, 5)
260#define GET_TX_DESC_AP_DCFE(__pdesc) \
261 LE_BITS_TO_4BYTE(__pdesc+16, 5, 1)
262#define GET_TX_DESC_QOS(__pdesc) \
263 LE_BITS_TO_4BYTE(__pdesc+16, 6, 1)
264#define GET_TX_DESC_HWSEQ_EN(__pdesc) \
265 LE_BITS_TO_4BYTE(__pdesc+16, 7, 1)
266#define GET_TX_DESC_USE_RATE(__pdesc) \
267 LE_BITS_TO_4BYTE(__pdesc+16, 8, 1)
268#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \
269 LE_BITS_TO_4BYTE(__pdesc+16, 9, 1)
270#define GET_TX_DESC_DISABLE_FB(__pdesc) \
271 LE_BITS_TO_4BYTE(__pdesc+16, 10, 1)
272#define GET_TX_DESC_CTS2SELF(__pdesc) \
273 LE_BITS_TO_4BYTE(__pdesc+16, 11, 1)
274#define GET_TX_DESC_RTS_ENABLE(__pdesc) \
275 LE_BITS_TO_4BYTE(__pdesc+16, 12, 1)
276#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \
277 LE_BITS_TO_4BYTE(__pdesc+16, 13, 1)
278#define GET_TX_DESC_PORT_ID(__pdesc) \
279 LE_BITS_TO_4BYTE(__pdesc+16, 14, 1)
280#define GET_TX_DESC_WAIT_DCTS(__pdesc) \
281 LE_BITS_TO_4BYTE(__pdesc+16, 18, 1)
282#define GET_TX_DESC_CTS2AP_EN(__pdesc) \
283 LE_BITS_TO_4BYTE(__pdesc+16, 19, 1)
284#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \
285 LE_BITS_TO_4BYTE(__pdesc+16, 20, 2)
286#define GET_TX_DESC_TX_STBC(__pdesc) \
287 LE_BITS_TO_4BYTE(__pdesc+16, 22, 2)
288#define GET_TX_DESC_DATA_SHORT(__pdesc) \
289 LE_BITS_TO_4BYTE(__pdesc+16, 24, 1)
290#define GET_TX_DESC_DATA_BW(__pdesc) \
291 LE_BITS_TO_4BYTE(__pdesc+16, 25, 1)
292#define GET_TX_DESC_RTS_SHORT(__pdesc) \
293 LE_BITS_TO_4BYTE(__pdesc+16, 26, 1)
294#define GET_TX_DESC_RTS_BW(__pdesc) \
295 LE_BITS_TO_4BYTE(__pdesc+16, 27, 1)
296#define GET_TX_DESC_RTS_SC(__pdesc) \
297 LE_BITS_TO_4BYTE(__pdesc+16, 28, 2)
298#define GET_TX_DESC_RTS_STBC(__pdesc) \
299 LE_BITS_TO_4BYTE(__pdesc+16, 30, 2)
300
301#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
302 SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val)
303#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
304 SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val)
305#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
306 SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
307#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
308 SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val)
309#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
310 SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
311#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
312 SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val)
313#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
314 SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val)
315#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \
316 SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val)
317
318#define GET_TX_DESC_TX_RATE(__pdesc) \
319 LE_BITS_TO_4BYTE(__pdesc+20, 0, 6)
320#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \
321 LE_BITS_TO_4BYTE(__pdesc+20, 6, 1)
322#define GET_TX_DESC_CCX_TAG(__pdesc) \
323 LE_BITS_TO_4BYTE(__pdesc+20, 7, 1)
324#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \
325 LE_BITS_TO_4BYTE(__pdesc+20, 8, 5)
326#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \
327 LE_BITS_TO_4BYTE(__pdesc+20, 13, 4)
328#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \
329 LE_BITS_TO_4BYTE(__pdesc+20, 17, 1)
330#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \
331 LE_BITS_TO_4BYTE(__pdesc+20, 18, 6)
332#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \
333 LE_BITS_TO_4BYTE(__pdesc+20, 24, 8)
334
335#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \
336 SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val)
337#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \
338 SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val)
339#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
340 SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val)
341#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
342 SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val)
343#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \
344 SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val)
345#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \
346 SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val)
347#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \
348 SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val)
349#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val)\
350 SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val)
351
352#define GET_TX_DESC_TXAGC_A(__pdesc) \
353 LE_BITS_TO_4BYTE(__pdesc+24, 0, 5)
354#define GET_TX_DESC_TXAGC_B(__pdesc) \
355 LE_BITS_TO_4BYTE(__pdesc+24, 5, 5)
356#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \
357 LE_BITS_TO_4BYTE(__pdesc+24, 10, 1)
358#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \
359 LE_BITS_TO_4BYTE(__pdesc+24, 11, 5)
360#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \
361 LE_BITS_TO_4BYTE(__pdesc+24, 16, 4)
362#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \
363 LE_BITS_TO_4BYTE(__pdesc+24, 20, 4)
364#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \
365 LE_BITS_TO_4BYTE(__pdesc+24, 24, 4)
366#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \
367 LE_BITS_TO_4BYTE(__pdesc+24, 28, 4)
368
369#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
370 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
371#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \
372 SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val)
373#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \
374 SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val)
375#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \
376 SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val)
377#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \
378 SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val)
379
380#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
381 LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
382#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \
383 LE_BITS_TO_4BYTE(__pdesc+28, 16, 4)
384#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \
385 LE_BITS_TO_4BYTE(__pdesc+28, 20, 4)
386#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \
387 LE_BITS_TO_4BYTE(__pdesc+28, 24, 4)
388#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \
389 LE_BITS_TO_4BYTE(__pdesc+28, 28, 4)
390
391#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
392 SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val)
393#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
394 SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val)
395
396#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
397 LE_BITS_TO_4BYTE(__pdesc+32, 0, 32)
398#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \
399 LE_BITS_TO_4BYTE(__pdesc+36, 0, 32)
400
401#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
402 SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
403#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
404 SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val)
405
406#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
407 LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
408#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \
409 LE_BITS_TO_4BYTE(__pdesc+44, 0, 32)
410
411#define GET_RX_DESC_PKT_LEN(__pdesc) \
412 LE_BITS_TO_4BYTE(__pdesc, 0, 14)
413#define GET_RX_DESC_CRC32(__pdesc) \
414 LE_BITS_TO_4BYTE(__pdesc, 14, 1)
415#define GET_RX_DESC_ICV(__pdesc) \
416 LE_BITS_TO_4BYTE(__pdesc, 15, 1)
417#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
418 LE_BITS_TO_4BYTE(__pdesc, 16, 4)
419#define GET_RX_DESC_SECURITY(__pdesc) \
420 LE_BITS_TO_4BYTE(__pdesc, 20, 3)
421#define GET_RX_DESC_QOS(__pdesc) \
422 LE_BITS_TO_4BYTE(__pdesc, 23, 1)
423#define GET_RX_DESC_SHIFT(__pdesc) \
424 LE_BITS_TO_4BYTE(__pdesc, 24, 2)
425#define GET_RX_DESC_PHYST(__pdesc) \
426 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
427#define GET_RX_DESC_SWDEC(__pdesc) \
428 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
429#define GET_RX_DESC_LS(__pdesc) \
430 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
431#define GET_RX_DESC_FS(__pdesc) \
432 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
433#define GET_RX_DESC_EOR(__pdesc) \
434 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
435#define GET_RX_DESC_OWN(__pdesc) \
436 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
437
438#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
439 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
440#define SET_RX_DESC_EOR(__pdesc, __val) \
441 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
442#define SET_RX_DESC_OWN(__pdesc, __val) \
443 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
444
445#define GET_RX_DESC_MACID(__pdesc) \
446 LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
447#define GET_RX_DESC_TID(__pdesc) \
448 LE_BITS_TO_4BYTE(__pdesc+4, 5, 4)
449#define GET_RX_DESC_HWRSVD(__pdesc) \
450 LE_BITS_TO_4BYTE(__pdesc+4, 9, 5)
451#define GET_RX_DESC_PAGGR(__pdesc) \
452 LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
453#define GET_RX_DESC_FAGGR(__pdesc) \
454 LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
455#define GET_RX_DESC_A1_FIT(__pdesc) \
456 LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
457#define GET_RX_DESC_A2_FIT(__pdesc) \
458 LE_BITS_TO_4BYTE(__pdesc+4, 20, 4)
459#define GET_RX_DESC_PAM(__pdesc) \
460 LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
461#define GET_RX_DESC_PWR(__pdesc) \
462 LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
463#define GET_RX_DESC_MD(__pdesc) \
464 LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
465#define GET_RX_DESC_MF(__pdesc) \
466 LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
467#define GET_RX_DESC_TYPE(__pdesc) \
468 LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
469#define GET_RX_DESC_MC(__pdesc) \
470 LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
471#define GET_RX_DESC_BC(__pdesc) \
472 LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
473#define GET_RX_DESC_SEQ(__pdesc) \
474 LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
475#define GET_RX_DESC_FRAG(__pdesc) \
476 LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
477#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \
478 LE_BITS_TO_4BYTE(__pdesc+8, 16, 14)
479#define GET_RX_DESC_NEXT_IND(__pdesc) \
480 LE_BITS_TO_4BYTE(__pdesc+8, 30, 1)
481#define GET_RX_DESC_RSVD(__pdesc) \
482 LE_BITS_TO_4BYTE(__pdesc+8, 31, 1)
483
484#define GET_RX_DESC_RXMCS(__pdesc) \
485 LE_BITS_TO_4BYTE(__pdesc+12, 0, 6)
486#define GET_RX_DESC_RXHT(__pdesc) \
487 LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
488#define GET_RX_DESC_SPLCP(__pdesc) \
489 LE_BITS_TO_4BYTE(__pdesc+12, 8, 1)
490#define GET_RX_DESC_BW(__pdesc) \
491 LE_BITS_TO_4BYTE(__pdesc+12, 9, 1)
492#define GET_RX_DESC_HTC(__pdesc) \
493 LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
494#define GET_RX_DESC_HWPC_ERR(__pdesc) \
495 LE_BITS_TO_4BYTE(__pdesc+12, 14, 1)
496#define GET_RX_DESC_HWPC_IND(__pdesc) \
497 LE_BITS_TO_4BYTE(__pdesc+12, 15, 1)
498#define GET_RX_DESC_IV0(__pdesc) \
499 LE_BITS_TO_4BYTE(__pdesc+12, 16, 16)
500
501#define GET_RX_DESC_IV1(__pdesc) \
502 LE_BITS_TO_4BYTE(__pdesc+16, 0, 32)
503#define GET_RX_DESC_TSFL(__pdesc) \
504 LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
505
506#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
507 LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
508#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
509 LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
510
511#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
512 SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
513#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
514 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
515
516#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
517do { \
518 if (_size > TX_DESC_NEXT_DESC_OFFSET) \
519 memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
520 else \
521 memset(__pdesc, 0, _size); \
522} while (0)
523
524#define RTL8723E_RX_HAL_IS_CCK_RATE(rxmcs) \
525 ((rxmcs) == DESC92_RATE1M || \
526 (rxmcs) == DESC92_RATE2M || \
527 (rxmcs) == DESC92_RATE5_5M || \
528 (rxmcs) == DESC92_RATE11M)
529
530struct rx_fwinfo_8723e {
531 u8 gain_trsw[4];
532 u8 pwdb_all;
533 u8 cfosho[4];
534 u8 cfotail[4];
535 char rxevm[2];
536 char rxsnr[4];
537 u8 pdsnr[2];
538 u8 csi_current[2];
539 u8 csi_target[2];
540 u8 sigevm;
541 u8 max_ex_pwr;
542 u8 ex_intf_flag:1;
543 u8 sgi_en:1;
544 u8 rxsc:2;
545 u8 reserve:4;
546} __packed;
547
548struct tx_desc_8723e {
549 u32 pktsize:16;
550 u32 offset:8;
551 u32 bmc:1;
552 u32 htc:1;
553 u32 lastseg:1;
554 u32 firstseg:1;
555 u32 linip:1;
556 u32 noacm:1;
557 u32 gf:1;
558 u32 own:1;
559
560 u32 macid:5;
561 u32 agg_en:1;
562 u32 bk:1;
563 u32 rdg_en:1;
564 u32 queuesel:5;
565 u32 rd_nav_ext:1;
566 u32 lsig_txop_en:1;
567 u32 pifs:1;
568 u32 rateid:4;
569 u32 nav_usehdr:1;
570 u32 en_descid:1;
571 u32 sectype:2;
572 u32 pktoffset:8;
573
574 u32 rts_rc:6;
575 u32 data_rc:6;
576 u32 rsvd0:2;
577 u32 bar_retryht:2;
578 u32 rsvd1:1;
579 u32 morefrag:1;
580 u32 raw:1;
581 u32 ccx:1;
582 u32 ampdudensity:3;
583 u32 rsvd2:1;
584 u32 ant_sela:1;
585 u32 ant_selb:1;
586 u32 txant_cck:2;
587 u32 txant_l:2;
588 u32 txant_ht:2;
589
590 u32 nextheadpage:8;
591 u32 tailpage:8;
592 u32 seq:12;
593 u32 pktid:4;
594
595 u32 rtsrate:5;
596 u32 apdcfe:1;
597 u32 qos:1;
598 u32 hwseq_enable:1;
599 u32 userrate:1;
600 u32 dis_rtsfb:1;
601 u32 dis_datafb:1;
602 u32 cts2self:1;
603 u32 rts_en:1;
604 u32 hwrts_en:1;
605 u32 portid:1;
606 u32 rsvd3:3;
607 u32 waitdcts:1;
608 u32 cts2ap_en:1;
609 u32 txsc:2;
610 u32 stbc:2;
611 u32 txshort:1;
612 u32 txbw:1;
613 u32 rtsshort:1;
614 u32 rtsbw:1;
615 u32 rtssc:2;
616 u32 rtsstbc:2;
617
618 u32 txrate:6;
619 u32 shortgi:1;
620 u32 ccxt:1;
621 u32 txrate_fb_lmt:5;
622 u32 rtsrate_fb_lmt:4;
623 u32 retrylmt_en:1;
624 u32 txretrylmt:6;
625 u32 usb_txaggnum:8;
626
627 u32 txagca:5;
628 u32 txagcb:5;
629 u32 usemaxlen:1;
630 u32 maxaggnum:5;
631 u32 mcsg1maxlen:4;
632 u32 mcsg2maxlen:4;
633 u32 mcsg3maxlen:4;
634 u32 mcs7sgimaxlen:4;
635
636 u32 txbuffersize:16;
637 u32 mcsg4maxlen:4;
638 u32 mcsg5maxlen:4;
639 u32 mcsg6maxlen:4;
640 u32 mcsg15sgimaxlen:4;
641
642 u32 txbuffaddr;
643 u32 txbufferaddr64;
644 u32 nextdescaddress;
645 u32 nextdescaddress64;
646
647 u32 reserve_pass_pcie_mm_limit[4];
648} __packed;
649
650struct rx_desc_8723e {
651 u32 length:14;
652 u32 crc32:1;
653 u32 icverror:1;
654 u32 drv_infosize:4;
655 u32 security:3;
656 u32 qos:1;
657 u32 shift:2;
658 u32 phystatus:1;
659 u32 swdec:1;
660 u32 lastseg:1;
661 u32 firstseg:1;
662 u32 eor:1;
663 u32 own:1;
664
665 u32 macid:5;
666 u32 tid:4;
667 u32 hwrsvd:5;
668 u32 paggr:1;
669 u32 faggr:1;
670 u32 a1_fit:4;
671 u32 a2_fit:4;
672 u32 pam:1;
673 u32 pwr:1;
674 u32 moredata:1;
675 u32 morefrag:1;
676 u32 type:2;
677 u32 mc:1;
678 u32 bc:1;
679
680 u32 seq:12;
681 u32 frag:4;
682 u32 nextpktlen:14;
683 u32 nextind:1;
684 u32 rsvd:1;
685
686 u32 rxmcs:6;
687 u32 rxht:1;
688 u32 amsdu:1;
689 u32 splcp:1;
690 u32 bandwidth:1;
691 u32 htc:1;
692 u32 tcpchk_rpt:1;
693 u32 ipcchk_rpt:1;
694 u32 tcpchk_valid:1;
695 u32 hwpcerr:1;
696 u32 hwpcind:1;
697 u32 iv0:16;
698
699 u32 iv1;
700
701 u32 tsfl;
702
703 u32 bufferaddress;
704 u32 bufferaddress64;
705
706} __packed;
707
708void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,
709 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
710 struct ieee80211_tx_info *info,
711 struct ieee80211_sta *sta,
712 struct sk_buff *skb, u8 hw_queue,
713 struct rtl_tcb_desc *ptcb_desc);
714bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,
715 struct rtl_stats *status,
716 struct ieee80211_rx_status *rx_status,
717 u8 *pdesc, struct sk_buff *skb);
718void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
719u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name);
720void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
721void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
722 bool b_firstseg, bool b_lastseg,
723 struct sk_buff *skb);
724
725#endif