diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2012-10-25 14:46:32 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-11-14 14:54:53 -0500 |
commit | c592e631bcec4d858695eee8bf321d60390d38e9 (patch) | |
tree | 721760de02b9b0df3bc0294b77b7ba15b45d6e6b /drivers/net/wireless/rtlwifi | |
parent | b7fd76d114568d0b1e0d443049ed597b3a55f9c6 (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')
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 | |||
36 | struct 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 | |||
49 | enum 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 | |||
83 | enum rf_optype { | ||
84 | RF_OP_BY_SW_3WIRE = 0, | ||
85 | RF_OP_BY_FW, | ||
86 | RF_OP_MAX | ||
87 | }; | ||
88 | |||
89 | enum rf_power_state { | ||
90 | RF_ON, | ||
91 | RF_OFF, | ||
92 | RF_SLEEP, | ||
93 | RF_SHUT_DOWN, | ||
94 | }; | ||
95 | |||
96 | enum power_save_mode { | ||
97 | POWER_SAVE_MODE_ACTIVE, | ||
98 | POWER_SAVE_MODE_SAVE, | ||
99 | }; | ||
100 | |||
101 | enum power_polocy_config { | ||
102 | POWERCFG_MAX_POWER_SAVINGS, | ||
103 | POWERCFG_GLOBAL_POWER_SAVINGS, | ||
104 | POWERCFG_LOCAL_POWER_SAVINGS, | ||
105 | POWERCFG_LENOVO, | ||
106 | }; | ||
107 | |||
108 | enum 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 | |||
115 | enum 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 | |||
140 | enum 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 | |||
151 | struct phy_sts_cck_8723e_t { | ||
152 | u8 adc_pwdb_X[4]; | ||
153 | u8 sq_rpt; | ||
154 | u8 cck_agc_rpt; | ||
155 | }; | ||
156 | |||
157 | struct 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 | |||
41 | static 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 | |||
81 | static 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 | |||
117 | static 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 | |||
153 | static 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 | |||
178 | static 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 | |||
204 | static 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 | |||
253 | static 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 | |||
276 | static 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 | |||
309 | static 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 | |||
359 | static 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 | } | ||
386 | static 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 | |||
451 | static 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 | |||
473 | static 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 | |||
486 | static 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 | |||
496 | static 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 | |||
567 | void 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 | |||
588 | static void rtl8723ae_dm_pwdmonitor(struct ieee80211_hw *hw) | ||
589 | { | ||
590 | } | ||
591 | |||
592 | void 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 | |||
601 | static 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 | |||
684 | static 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 | |||
696 | void 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 | |||
710 | static 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 | |||
721 | void 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 | |||
794 | static 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 | |||
831 | void 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 | |||
844 | void 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 | |||
872 | static 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 | |||
896 | void 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 | |||
71 | struct 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 | |||
81 | enum 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 | |||
92 | enum 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 | |||
100 | enum dm_1r_cca_e { | ||
101 | CCA_1R = 0, | ||
102 | CCA_2R = 1, | ||
103 | CCA_MAX = 2, | ||
104 | }; | ||
105 | |||
106 | enum dm_rf_e { | ||
107 | RF_SAVE = 0, | ||
108 | RF_NORMAL = 1, | ||
109 | RF_MAX = 2, | ||
110 | }; | ||
111 | |||
112 | enum dm_sw_ant_switch_e { | ||
113 | ANS_ANTENNA_B = 1, | ||
114 | ANS_ANTENNA_A = 2, | ||
115 | ANS_ANTENNA_MAX = 3, | ||
116 | }; | ||
117 | |||
118 | enum 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 | |||
126 | enum 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 | |||
141 | void rtl8723ae_dm_init(struct ieee80211_hw *hw); | ||
142 | void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw); | ||
143 | void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw); | ||
144 | void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw); | ||
145 | void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); | ||
146 | void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); | ||
147 | void 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 | |||
38 | static 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 | |||
59 | static 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 | |||
87 | static 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 | |||
100 | static 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 | |||
135 | static 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 | |||
181 | exit: | ||
182 | return err; | ||
183 | } | ||
184 | |||
185 | int 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 | |||
231 | static 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 | |||
245 | static 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 | |||
450 | void 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 | |||
466 | void 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 | |||
488 | void 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 | |||
508 | static 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 | |||
541 | static 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 | |||
651 | void 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 | |||
738 | void 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 | |||
49 | struct 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 | |||
68 | enum 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 | |||
93 | int rtl8723ae_download_fw(struct ieee80211_hw *hw); | ||
94 | void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, | ||
95 | u32 cmd_len, u8 *p_cmdbuffer); | ||
96 | void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw); | ||
97 | void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); | ||
98 | void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); | ||
99 | void 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 | |||
38 | void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw, | ||
39 | bool reject) | ||
40 | { | ||
41 | } | ||
42 | |||
43 | void _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 | |||
97 | u8 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 | |||
227 | u8 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 | |||
354 | long 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 | |||
370 | void 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 | |||
398 | void 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 | |||
446 | void 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 | |||
463 | void 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 | |||
479 | void 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 | |||
496 | void 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 | |||
514 | void 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 | |||
521 | bool 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 | |||
534 | bool 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 | |||
137 | void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw); | ||
138 | void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw); | ||
139 | |||
140 | void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw); | ||
141 | void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw); | ||
142 | long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw); | ||
143 | void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw, | ||
144 | bool balance_on, u8 ms0, u8 ms1); | ||
145 | void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type); | ||
146 | void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type); | ||
147 | u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw, | ||
148 | u8 level_num, u8 rssi_thresh, | ||
149 | u8 rssi_thresh1); | ||
150 | u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw, | ||
151 | u8 level_num, u8 rssi_thresh, | ||
152 | u8 rssi_thresh1); | ||
153 | void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw); | ||
154 | void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw, | ||
155 | bool reject); | ||
156 | |||
157 | bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw); | ||
158 | bool 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 | |||
37 | void 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 | |||
57 | static 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 | |||
71 | void 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 | |||
106 | static 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 | |||
117 | static 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 | |||
136 | static 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 | |||
152 | static 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 | |||
171 | static 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 | |||
190 | static 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 | |||
206 | static 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 | |||
228 | static 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 | |||
250 | static 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 | |||
293 | static 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 | |||
302 | static 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 | |||
384 | static 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 | |||
404 | static 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 | |||
425 | static 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 | |||
446 | static 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 | |||
513 | static 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 | |||
537 | static 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 | |||
591 | static 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 | |||
607 | static 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 | |||
628 | static 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 | |||
644 | static 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 | |||
668 | void 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 | */ | ||
933 | static 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 | |||
943 | static 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 | |||
951 | static 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 | |||
991 | static 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 | |||
1169 | static 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 | |||
1382 | static 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 | |||
1417 | static 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 | |||
1431 | static 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 | |||
1501 | static void _rtl8723ae_dm_bt_coexist_1_ant(struct ieee80211_hw *hw) | ||
1502 | { | ||
1503 | } | ||
1504 | |||
1505 | void 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 | |||
1511 | void 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 | |||
1527 | void 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 | |||
1538 | static 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 | |||
1555 | static 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 | |||
1595 | static 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 | |||
1647 | void 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 | |||
1680 | static 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 | } | ||
1726 | void 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 | |||
68 | enum 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 | |||
75 | enum 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 | |||
83 | enum 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 | |||
97 | enum 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 | |||
107 | struct c2h_evt_hdr { | ||
108 | u8 cmd_id; | ||
109 | u8 cmd_len; | ||
110 | u8 cmd_seq; | ||
111 | }; | ||
112 | |||
113 | enum 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 | |||
126 | enum 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 | |||
140 | void rtl8723ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw); | ||
141 | void rtl8723ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw); | ||
142 | void rtl8723ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw); | ||
143 | void rtl8723ae_dm_bt_coexist_8723(struct ieee80211_hw *hw); | ||
144 | void rtl8723ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw, | ||
145 | struct btdm_8723 *p_btdm); | ||
146 | void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw); | ||
147 | void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw, | ||
148 | bool mstatus); | ||
149 | void 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 | |||
48 | static 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 | |||
60 | static 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 | |||
73 | static 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 | |||
86 | static void _rtl8723ae_enable_bcn_sufunc(struct ieee80211_hw *hw) | ||
87 | { | ||
88 | _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(1)); | ||
89 | } | ||
90 | |||
91 | static void _rtl8723ae_disable_bcn_sufunc(struct ieee80211_hw *hw) | ||
92 | { | ||
93 | _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(1), 0); | ||
94 | } | ||
95 | |||
96 | void 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 | |||
148 | void 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 | |||
484 | static 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 | |||
511 | static 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 | |||
567 | static 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 | |||
585 | static 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 | |||
700 | static 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 | |||
786 | static 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 | |||
804 | void 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 | |||
838 | int 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 | |||
944 | static 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 | |||
1012 | static 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 | |||
1078 | void 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 *)(®_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 *) (®_rcr)); | ||
1097 | } | ||
1098 | } | ||
1099 | |||
1100 | int 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 */ | ||
1118 | void 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 | |||
1142 | void 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 | |||
1152 | void 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 | |||
1163 | static 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 | |||
1203 | void 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 | |||
1224 | void 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 | |||
1234 | void 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 | |||
1253 | void 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 | |||
1266 | void 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 | |||
1283 | static 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 | |||
1296 | static 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 | |||
1514 | static 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 | |||
1712 | static 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 | |||
1735 | void 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 | |||
1778 | static 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 | |||
1861 | static 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 | |||
2002 | void 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 | |||
2013 | void 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 | |||
2028 | bool 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 | |||
2098 | void 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 | |||
2225 | static 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 | |||
2305 | void 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 | |||
2336 | void 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 | |||
2349 | void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw) | ||
2350 | { | ||
2351 | } | ||
2352 | |||
2353 | void rtl8723ae_suspend(struct ieee80211_hw *hw) | ||
2354 | { | ||
2355 | } | ||
2356 | |||
2357 | void rtl8723ae_resume(struct ieee80211_hw *hw) | ||
2358 | { | ||
2359 | } | ||
2360 | |||
2361 | /* Turn on AAP (RCR:bit 0) for promicuous mode. */ | ||
2362 | void 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 | |||
37 | void rtl8723ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | ||
38 | void rtl8723ae_read_eeprom_info(struct ieee80211_hw *hw); | ||
39 | |||
40 | void rtl8723ae_interrupt_recognized(struct ieee80211_hw *hw, | ||
41 | u32 *p_inta, u32 *p_intb); | ||
42 | int rtl8723ae_hw_init(struct ieee80211_hw *hw); | ||
43 | void rtl8723ae_card_disable(struct ieee80211_hw *hw); | ||
44 | void rtl8723ae_enable_interrupt(struct ieee80211_hw *hw); | ||
45 | void rtl8723ae_disable_interrupt(struct ieee80211_hw *hw); | ||
46 | int rtl8723ae_set_network_type(struct ieee80211_hw *hw, | ||
47 | enum nl80211_iftype type); | ||
48 | void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); | ||
49 | void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci); | ||
50 | void rtl8723ae_set_beacon_related_registers(struct ieee80211_hw *hw); | ||
51 | void rtl8723ae_set_beacon_interval(struct ieee80211_hw *hw); | ||
52 | void rtl8723ae_update_interrupt_mask(struct ieee80211_hw *hw, | ||
53 | u32 add_msr, u32 rm_msr); | ||
54 | void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | ||
55 | void rtl8723ae_update_hal_rate_tbl(struct ieee80211_hw *hw, | ||
56 | struct ieee80211_sta *sta, u8 rssi_level); | ||
57 | void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw); | ||
58 | bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); | ||
59 | void rtl8723ae_enable_hw_security_config(struct ieee80211_hw *hw); | ||
60 | void 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 | |||
64 | void rtl8723ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, | ||
65 | bool autoload_fail, u8 *hwinfo); | ||
66 | void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw); | ||
67 | void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw); | ||
68 | void rtl8723ae_suspend(struct ieee80211_hw *hw); | ||
69 | void rtl8723ae_resume(struct ieee80211_hw *hw); | ||
70 | void 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 | |||
35 | static 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 | |||
43 | void 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 | |||
71 | void 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 | |||
106 | void 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 | |||
114 | static 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 | |||
134 | void 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 | |||
33 | void rtl8723ae_init_sw_leds(struct ieee80211_hw *hw); | ||
34 | void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); | ||
35 | void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); | ||
36 | void 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 */ | ||
41 | static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw, | ||
42 | enum radio_path rfpath, u32 offset); | ||
43 | static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
44 | enum radio_path rfpath, | ||
45 | u32 offset, u32 data); | ||
46 | static u32 _phy_rf_serial_read(struct ieee80211_hw *hw, | ||
47 | enum radio_path rfpath, u32 offset); | ||
48 | static void _phy_rf_serial_write(struct ieee80211_hw *hw, | ||
49 | enum radio_path rfpath, u32 offset, u32 data); | ||
50 | static u32 _phy_calculate_bit_shift(u32 bitmask); | ||
51 | static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw); | ||
52 | static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw); | ||
53 | static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype); | ||
54 | static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype); | ||
55 | static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw); | ||
56 | static 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); | ||
61 | static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel, | ||
62 | u8 *stage, u8 *step, u32 *delay); | ||
63 | static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
64 | enum wireless_mode wirelessmode, | ||
65 | long power_indbm); | ||
66 | static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
67 | enum wireless_mode wirelessmode, u8 txpwridx); | ||
68 | static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw); | ||
69 | |||
70 | u32 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 | |||
89 | void 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 | |||
112 | u32 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 | |||
143 | void 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 | |||
186 | static 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 | |||
193 | static 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 | |||
200 | static 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 | |||
249 | static 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 | |||
270 | static 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 | |||
281 | static 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 | |||
295 | bool 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 | |||
303 | bool 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 | |||
342 | bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw) | ||
343 | { | ||
344 | return rtl8723ae_phy_rf6052_config(hw); | ||
345 | } | ||
346 | |||
347 | static 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 | |||
383 | static 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 | |||
401 | static 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 | |||
451 | static 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 | |||
576 | static 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 | |||
612 | bool 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 | |||
668 | void 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 | |||
699 | static 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 | |||
785 | void 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 | |||
808 | static 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 | |||
833 | static 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 | |||
844 | void 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 | |||
859 | bool 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 | |||
890 | static 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 | |||
921 | static 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 | |||
943 | void 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 | |||
972 | void 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 | |||
1041 | void 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 | |||
1062 | void 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 | |||
1091 | u8 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 | |||
1119 | static 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 | |||
1139 | static 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 | |||
1242 | static 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 | |||
1265 | static 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 | |||
1308 | static 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 | |||
1335 | static 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 | |||
1375 | static 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 | |||
1385 | static 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 | |||
1396 | static 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 | |||
1405 | static 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 | |||
1416 | static 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 | |||
1435 | static 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 | |||
1449 | static 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 | |||
1456 | static 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 | |||
1465 | static 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 | |||
1517 | static 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 | |||
1635 | static 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 | |||
1680 | static 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 | |||
1708 | void 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 | |||
1809 | void 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 | |||
1818 | void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) | ||
1819 | { | ||
1820 | _rtl8723ae_phy_set_rfpath_switch(hw, bmain, false); | ||
1821 | } | ||
1822 | |||
1823 | bool 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 | |||
1861 | static 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 | |||
1891 | static 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 | |||
1903 | static 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 | |||
1933 | static 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 | |||
2034 | bool 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 | |||
79 | enum 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 | |||
89 | struct swchnlcmd { | ||
90 | enum swchnlcmd_id cmdid; | ||
91 | u32 para1; | ||
92 | u32 para2; | ||
93 | u32 msdelay; | ||
94 | }; | ||
95 | |||
96 | enum 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 | |||
104 | enum baseband_config_type { | ||
105 | BASEBAND_CONFIG_PHY_REG = 0, | ||
106 | BASEBAND_CONFIG_AGC_TAB = 1, | ||
107 | }; | ||
108 | |||
109 | enum 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 | |||
119 | enum 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 | |||
138 | struct 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 | |||
150 | struct 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 | |||
156 | struct 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 | |||
173 | struct 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 | |||
186 | extern u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, | ||
187 | u32 regaddr, u32 bitmask); | ||
188 | extern void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, | ||
189 | u32 regaddr, u32 bitmask, u32 data); | ||
190 | extern u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, | ||
191 | enum radio_path rfpath, u32 regaddr, | ||
192 | u32 bitmask); | ||
193 | extern void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, | ||
194 | enum radio_path rfpath, u32 regaddr, | ||
195 | u32 bitmask, u32 data); | ||
196 | extern bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw); | ||
197 | extern bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw); | ||
198 | extern bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw); | ||
199 | extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, | ||
200 | enum radio_path rfpath); | ||
201 | extern void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); | ||
202 | extern void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, | ||
203 | long *powerlevel); | ||
204 | extern void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, | ||
205 | u8 channel); | ||
206 | extern bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, | ||
207 | long power_indbm); | ||
208 | extern void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, | ||
209 | u8 operation); | ||
210 | extern void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw); | ||
211 | extern void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
212 | enum nl80211_channel_type ch_type); | ||
213 | extern void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw); | ||
214 | extern u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw); | ||
215 | extern void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); | ||
216 | void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw); | ||
217 | void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); | ||
218 | bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | ||
219 | enum radio_path rfpath); | ||
220 | bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); | ||
221 | extern 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*/ | ||
36 | struct 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 */ | ||
43 | struct 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*/ | ||
50 | struct wlan_pwr_cfg | ||
51 | rtl8723A_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*/ | ||
60 | struct 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*/ | ||
69 | struct 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*/ | ||
78 | struct 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*/ | ||
87 | struct 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 */ | ||
96 | struct 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 */ | ||
104 | struct 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 | |||
278 | extern struct | ||
279 | wlan_pwr_cfg rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STPS | ||
280 | + RTL8723A_TRANS_END_STPS]; | ||
281 | extern struct | ||
282 | wlan_pwr_cfg rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
283 | + RTL8723A_TRANS_END_STPS]; | ||
284 | extern struct | ||
285 | wlan_pwr_cfg rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
286 | + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS | ||
287 | + RTL8723A_TRANS_END_STPS]; | ||
288 | extern struct | ||
289 | wlan_pwr_cfg rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
290 | + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS | ||
291 | + RTL8723A_TRANS_END_STPS]; | ||
292 | extern struct | ||
293 | wlan_pwr_cfg rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
294 | + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS | ||
295 | + RTL8723A_TRANS_END_STPS]; | ||
296 | extern struct | ||
297 | wlan_pwr_cfg rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
298 | + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS | ||
299 | + RTL8723A_TRANS_END_STPS]; | ||
300 | extern struct | ||
301 | wlan_pwr_cfg rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
302 | + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS | ||
303 | + RTL8723A_TRANS_END_STPS]; | ||
304 | extern struct | ||
305 | wlan_pwr_cfg rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STPS | ||
306 | + RTL8723A_TRANS_END_STPS]; | ||
307 | extern struct | ||
308 | wlan_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 | */ | ||
38 | bool 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 | |||
69 | enum pwrseq_delay_unit { | ||
70 | PWRSEQ_DELAY_US, | ||
71 | PWRSEQ_DELAY_MS, | ||
72 | }; | ||
73 | |||
74 | struct 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 | |||
94 | bool 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 | |||
37 | void 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 | |||
62 | void 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 | |||
149 | static 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 | |||
190 | static 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 | |||
335 | static 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 | |||
400 | void 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 | |||
419 | static 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 | |||
494 | bool 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 | |||
35 | extern void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, | ||
36 | u8 bandwidth); | ||
37 | extern void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | ||
38 | u8 *ppowerlevel); | ||
39 | extern void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, | ||
40 | u8 *ppowerlevel, u8 channel); | ||
41 | extern 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 | |||
47 | static 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 | |||
88 | int 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 | |||
185 | void 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 | |||
195 | static 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 | |||
242 | static 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 | |||
250 | static 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 | |||
344 | static struct pci_device_id rtl8723ae_pci_ids[] __devinitdata = { | ||
345 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8723, rtl8723ae_hal_cfg)}, | ||
346 | {}, | ||
347 | }; | ||
348 | |||
349 | MODULE_DEVICE_TABLE(pci, rtl8723ae_pci_ids); | ||
350 | |||
351 | MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>"); | ||
352 | MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); | ||
353 | MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); | ||
354 | MODULE_LICENSE("GPL"); | ||
355 | MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless"); | ||
356 | MODULE_FIRMWARE("rtlwifi/rtl8723aefw.bin"); | ||
357 | MODULE_FIRMWARE("rtlwifi/rtl8723aefw_B.bin"); | ||
358 | |||
359 | module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444); | ||
360 | module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444); | ||
361 | module_param_named(ips, rtl8723ae_mod_params.inactiveps, bool, 0444); | ||
362 | module_param_named(swlps, rtl8723ae_mod_params.swctrl_lps, bool, 0444); | ||
363 | module_param_named(fwlps, rtl8723ae_mod_params.fwctrl_lps, bool, 0444); | ||
364 | MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); | ||
365 | MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); | ||
366 | MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); | ||
367 | MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); | ||
368 | MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); | ||
369 | |||
370 | static 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 | |||
379 | static 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 | |||
387 | module_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 | |||
33 | int rtl8723ae_init_sw_vars(struct ieee80211_hw *hw); | ||
34 | void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw); | ||
35 | void 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 | |||
34 | u32 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 | |||
223 | u32 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 | |||
338 | u32 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 | |||
483 | u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH] = { | ||
484 | 0x0, | ||
485 | }; | ||
486 | |||
487 | |||
488 | u32 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 | |||
577 | u32 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 | ||
38 | extern u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH]; | ||
39 | #define RTL8723E_PHY_REG_ARRAY_PGLENGTH 336 | ||
40 | extern u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH]; | ||
41 | #define Rtl8723ERADIOA_1TARRAYLENGTH 282 | ||
42 | extern u32 RTL8723E_RADIOA_1TARRAY[Rtl8723ERADIOA_1TARRAYLENGTH]; | ||
43 | #define RTL8723E_RADIOB_1TARRAYLENGTH 1 | ||
44 | extern u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH]; | ||
45 | #define RTL8723E_MACARRAYLENGTH 172 | ||
46 | extern u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH]; | ||
47 | #define RTL8723E_AGCTAB_1TARRAYLENGTH 320 | ||
48 | extern 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 | |||
40 | static 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 | |||
52 | static 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 | |||
238 | static 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 | |||
281 | bool 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 | |||
365 | void 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 | |||
532 | void 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 | |||
590 | void 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 | |||
627 | u32 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 | |||
661 | void 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) \ | ||
517 | do { \ | ||
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 | |||
530 | struct 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 | |||
548 | struct 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 | |||
650 | struct 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 | |||
708 | void 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); | ||
714 | bool 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); | ||
718 | void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); | ||
719 | u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name); | ||
720 | void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); | ||
721 | void 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 | ||