staging: rtl8821ae: Fix typo in rtl8821ae/rtl8821ae.
[deliverable/linux.git] / drivers / staging / rtl8821ae / rtl8821ae / dm.c
1 /******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30 #include "../wifi.h"
31 #include "../base.h"
32 #include "../pci.h"
33 #include "reg.h"
34 #include "def.h"
35 #include "phy.h"
36 #include "dm.h"
37 #include "fw.h"
38 #include "trx.h"
39 #include "../btcoexist/rtl_btc.h"
40
41 struct dig_t dm_digtable;
42 static struct ps_t dm_pstable;
43
44 static const u32 rtl8812ae_txscaling_table[TXSCALE_TABLE_SIZE] =
45 {
46 0x081, // 0, -12.0dB
47 0x088, // 1, -11.5dB
48 0x090, // 2, -11.0dB
49 0x099, // 3, -10.5dB
50 0x0A2, // 4, -10.0dB
51 0x0AC, // 5, -9.5dB
52 0x0B6, // 6, -9.0dB
53 0x0C0, // 7, -8.5dB
54 0x0CC, // 8, -8.0dB
55 0x0D8, // 9, -7.5dB
56 0x0E5, // 10, -7.0dB
57 0x0F2, // 11, -6.5dB
58 0x101, // 12, -6.0dB
59 0x110, // 13, -5.5dB
60 0x120, // 14, -5.0dB
61 0x131, // 15, -4.5dB
62 0x143, // 16, -4.0dB
63 0x156, // 17, -3.5dB
64 0x16A, // 18, -3.0dB
65 0x180, // 19, -2.5dB
66 0x197, // 20, -2.0dB
67 0x1AF, // 21, -1.5dB
68 0x1C8, // 22, -1.0dB
69 0x1E3, // 23, -0.5dB
70 0x200, // 24, +0 dB
71 0x21E, // 25, +0.5dB
72 0x23E, // 26, +1.0dB
73 0x261, // 27, +1.5dB
74 0x285, // 28, +2.0dB
75 0x2AB, // 29, +2.5dB
76 0x2D3, // 30, +3.0dB
77 0x2FE, // 31, +3.5dB
78 0x32B, // 32, +4.0dB
79 0x35C, // 33, +4.5dB
80 0x38E, // 34, +5.0dB
81 0x3C4, // 35, +5.5dB
82 0x3FE // 36, +6.0dB
83 };
84
85 static const u32 rtl8821ae_txscaling_table[TXSCALE_TABLE_SIZE] = {
86 0x081, // 0, -12.0dB
87 0x088, // 1, -11.5dB
88 0x090, // 2, -11.0dB
89 0x099, // 3, -10.5dB
90 0x0A2, // 4, -10.0dB
91 0x0AC, // 5, -9.5dB
92 0x0B6, // 6, -9.0dB
93 0x0C0, // 7, -8.5dB
94 0x0CC, // 8, -8.0dB
95 0x0D8, // 9, -7.5dB
96 0x0E5, // 10, -7.0dB
97 0x0F2, // 11, -6.5dB
98 0x101, // 12, -6.0dB
99 0x110, // 13, -5.5dB
100 0x120, // 14, -5.0dB
101 0x131, // 15, -4.5dB
102 0x143, // 16, -4.0dB
103 0x156, // 17, -3.5dB
104 0x16A, // 18, -3.0dB
105 0x180, // 19, -2.5dB
106 0x197, // 20, -2.0dB
107 0x1AF, // 21, -1.5dB
108 0x1C8, // 22, -1.0dB
109 0x1E3, // 23, -0.5dB
110 0x200, // 24, +0 dB
111 0x21E, // 25, +0.5dB
112 0x23E, // 26, +1.0dB
113 0x261, // 27, +1.5dB
114 0x285, // 28, +2.0dB
115 0x2AB, // 29, +2.5dB
116 0x2D3, // 30, +3.0dB
117 0x2FE, // 31, +3.5dB
118 0x32B, // 32, +4.0dB
119 0x35C, // 33, +4.5dB
120 0x38E, // 34, +5.0dB
121 0x3C4, // 35, +5.5dB
122 0x3FE // 36, +6.0dB
123 };
124
125 static const u32 ofdmswing_table[] = {
126 0x0b40002d, // 0, -15.0dB
127 0x0c000030, // 1, -14.5dB
128 0x0cc00033, // 2, -14.0dB
129 0x0d800036, // 3, -13.5dB
130 0x0e400039, // 4, -13.0dB
131 0x0f00003c, // 5, -12.5dB
132 0x10000040, // 6, -12.0dB
133 0x11000044, // 7, -11.5dB
134 0x12000048, // 8, -11.0dB
135 0x1300004c, // 9, -10.5dB
136 0x14400051, // 10, -10.0dB
137 0x15800056, // 11, -9.5dB
138 0x16c0005b, // 12, -9.0dB
139 0x18000060, // 13, -8.5dB
140 0x19800066, // 14, -8.0dB
141 0x1b00006c, // 15, -7.5dB
142 0x1c800072, // 16, -7.0dB
143 0x1e400079, // 17, -6.5dB
144 0x20000080, // 18, -6.0dB
145 0x22000088, // 19, -5.5dB
146 0x24000090, // 20, -5.0dB
147 0x26000098, // 21, -4.5dB
148 0x288000a2, // 22, -4.0dB
149 0x2ac000ab, // 23, -3.5dB
150 0x2d4000b5, // 24, -3.0dB
151 0x300000c0, // 25, -2.5dB
152 0x32c000cb, // 26, -2.0dB
153 0x35c000d7, // 27, -1.5dB
154 0x390000e4, // 28, -1.0dB
155 0x3c8000f2, // 29, -0.5dB
156 0x40000100, // 30, +0dB
157 0x43c0010f, // 31, +0.5dB
158 0x47c0011f, // 32, +1.0dB
159 0x4c000130, // 33, +1.5dB
160 0x50800142, // 34, +2.0dB
161 0x55400155, // 35, +2.5dB
162 0x5a400169, // 36, +3.0dB
163 0x5fc0017f, // 37, +3.5dB
164 0x65400195, // 38, +4.0dB
165 0x6b8001ae, // 39, +4.5dB
166 0x71c001c7, // 40, +5.0dB
167 0x788001e2, // 41, +5.5dB
168 0x7f8001fe // 42, +6.0dB
169 };
170
171 static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
172 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, // 0, -16.0dB
173 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, // 1, -15.5dB
174 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, // 2, -15.0dB
175 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, // 3, -14.5dB
176 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, // 4, -14.0dB
177 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, // 5, -13.5dB
178 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, // 6, -13.0dB
179 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, // 7, -12.5dB
180 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, // 8, -12.0dB
181 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, // 9, -11.5dB
182 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, // 10, -11.0dB
183 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, // 11, -10.5dB
184 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 12, -10.0dB
185 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 13, -9.5dB
186 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, // 14, -9.0dB
187 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, // 15, -8.5dB
188 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, // 16, -8.0dB
189 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, // 17, -7.5dB
190 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, // 18, -7.0dB
191 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, // 19, -6.5dB
192 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, // 20, -6.0dB
193 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, // 21, -5.5dB
194 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, // 22, -5.0dB
195 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, // 23, -4.5dB
196 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, // 24, -4.0dB
197 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, // 25, -3.5dB
198 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, // 26, -3.0dB
199 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, // 27, -2.5dB
200 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, // 28, -2.0dB
201 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, // 29, -1.5dB
202 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, // 30, -1.0dB
203 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, // 31, -0.5dB
204 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} // 32, +0dB
205 };
206
207 static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8]= {
208 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, // 0, -16.0dB
209 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, // 1, -15.5dB
210 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, // 2, -15.0dB
211 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, // 3, -14.5dB
212 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, // 4, -14.0dB
213 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, // 5, -13.5dB
214 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, // 6, -13.0dB
215 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, // 7, -12.5dB
216 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, // 8, -12.0dB
217 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, // 9, -11.5dB
218 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, // 10, -11.0dB
219 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, // 11, -10.5dB
220 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 12, -10.0dB
221 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 13, -9.5dB
222 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 14, -9.0dB
223 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 15, -8.5dB
224 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 16, -8.0dB
225 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 17, -7.5dB
226 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, // 18, -7.0dB
227 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, // 19, -6.5dB
228 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 20, -6.0dB
229 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 21, -5.5dB
230 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, // 22, -5.0dB
231 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, // 23, -4.5dB
232 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, // 24, -4.0dB
233 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, // 25, -3.5dB
234 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, // 26, -3.0dB
235 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, // 27, -2.5dB
236 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, // 28, -2.0dB
237 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, // 29, -1.5dB
238 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, // 30, -1.0dB
239 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, // 31, -0.5dB
240 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} // 32, +0dB
241 };
242
243 static const u32 edca_setting_dl[PEER_MAX] = {
244 0xa44f, /* 0 UNKNOWN */
245 0x5ea44f, /* 1 REALTEK_90 */
246 0x5e4322, /* 2 REALTEK_92SE */
247 0x5ea42b, /* 3 BROAD */
248 0xa44f, /* 4 RAL */
249 0xa630, /* 5 ATH */
250 0x5ea630, /* 6 CISCO */
251 0x5ea42b, /* 7 MARVELL */
252 };
253
254 static const u32 edca_setting_ul[PEER_MAX] = {
255 0x5e4322, /* 0 UNKNOWN */
256 0xa44f, /* 1 REALTEK_90 */
257 0x5ea44f, /* 2 REALTEK_92SE */
258 0x5ea32b, /* 3 BROAD */
259 0x5ea422, /* 4 RAL */
260 0x5ea322, /* 5 ATH */
261 0x3ea430, /* 6 CISCO */
262 0x5ea44f, /* 7 MARV */
263 };
264
265 static u8 rtl8818e_delta_swing_table_idx_24gb_p_txpwrtrack[] =
266 {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9};
267 static u8 rtl8818e_delta_swing_table_idx_24gb_n_txpwrtrack[] =
268 {0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11};
269
270
271 u8 rtl8812ae_delta_swing_table_idx_24gb_n_txpwrtrack[] =
272 {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11};
273 u8 rtl8812ae_delta_swing_table_idx_24gb_p_txpwrtrack[] =
274 {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
275 u8 rtl8812ae_delta_swing_table_idx_24ga_n_txpwrtrack[] =
276 {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11};
277 u8 rtl8812ae_delta_swing_table_idx_24ga_p_txpwrtrack[] =
278 {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
279 u8 rtl8812ae_delta_swing_table_idx_24gcckb_n_txpwrtrack[] =
280 {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11};
281 u8 rtl8812ae_delta_swing_table_idx_24gcckb_p_txpwrtrack[] =
282 {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
283 u8 rtl8812ae_delta_swing_table_idx_24gccka_n_txpwrtrack[] =
284 {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11};
285 u8 rtl8812ae_delta_swing_table_idx_24gccka_p_txpwrtrack[] =
286 {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
287
288 u8 rtl8812ae_delta_swing_table_idx_5gb_n_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
289 {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13},
290 {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13},
291 {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 14, 15, 16, 17, 17, 17, 18, 18, 18},
292 };
293 u8 rtl8812ae_delta_swing_table_idx_5gb_p_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
294 {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
295 {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
296 {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
297 };
298 u8 rtl8812ae_delta_swing_table_idx_5ga_n_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
299 {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13},
300 {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13},
301 {0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 18, 18},
302 };
303 u8 rtl8812ae_delta_swing_table_idx_5ga_p_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
304 {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
305 {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
306 {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
307 };
308
309 u8 rtl8821ae_delta_swing_table_idx_24gb_n_txpwrtrack[] =
310 {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
311 u8 rtl8821ae_delta_swing_table_idx_24gb_p_txpwrtrack[] =
312 {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
313 u8 rtl8821ae_delta_swing_table_idx_24ga_n_txpwrtrack[] =
314 {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
315 u8 rtl8821ae_delta_swing_table_idx_24ga_p_txpwrtrack[] =
316 {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
317 u8 rtl8821ae_delta_swing_table_idx_24gcckb_n_txpwrtrack[] =
318 {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
319 u8 rtl8821ae_delta_swing_table_idx_24gcckb_p_txpwrtrack[] =
320 {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
321 u8 rtl8821ae_delta_swing_table_idx_24gccka_n_txpwrtrack[] =
322 {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
323 u8 rtl8821ae_delta_swing_table_idx_24gccka_p_txpwrtrack[] =
324 {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
325
326 u8 rtl8821ae_delta_swing_table_idx_5gb_n_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
327 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
328 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
329 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
330 };
331
332 u8 rtl8821ae_delta_swing_table_idx_5gb_p_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
333 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
334 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
335 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
336 };
337
338 u8 rtl8821ae_delta_swing_table_idx_5ga_n_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
339 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
340 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
341 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
342 };
343
344 u8 rtl8821ae_delta_swing_table_idx_5ga_p_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
345 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
346 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
347 {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
348 };
349
350 void rtl8812ae_dm_read_and_config_txpower_track(
351 struct ieee80211_hw *hw)
352 {
353 struct rtl_priv *rtlpriv = rtl_priv(hw);
354 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
355 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
356 ("===> rtl8821ae_dm_read_and_config_txpower_track\n"));
357
358
359 memcpy(rtldm->delta_swing_table_idx_24ga_p,
360 rtl8812ae_delta_swing_table_idx_24ga_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
361 memcpy(rtldm->delta_swing_table_idx_24ga_n,
362 rtl8812ae_delta_swing_table_idx_24ga_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
363 memcpy(rtldm->delta_swing_table_idx_24gb_p,
364 rtl8812ae_delta_swing_table_idx_24gb_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
365 memcpy(rtldm->delta_swing_table_idx_24gb_n,
366 rtl8812ae_delta_swing_table_idx_24gb_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
367
368 memcpy(rtldm->delta_swing_table_idx_24gccka_p,
369 rtl8812ae_delta_swing_table_idx_24gccka_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
370 memcpy(rtldm->delta_swing_table_idx_24gccka_n,
371 rtl8812ae_delta_swing_table_idx_24gccka_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
372 memcpy(rtldm->delta_swing_table_idx_24gcckb_p,
373 rtl8812ae_delta_swing_table_idx_24gcckb_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
374 memcpy(rtldm->delta_swing_table_idx_24gcckb_n,
375 rtl8812ae_delta_swing_table_idx_24gcckb_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
376
377 memcpy(rtldm->delta_swing_table_idx_5ga_p,
378 rtl8812ae_delta_swing_table_idx_5ga_p_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
379 memcpy(rtldm->delta_swing_table_idx_5ga_n,
380 rtl8812ae_delta_swing_table_idx_5ga_n_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
381 memcpy(rtldm->delta_swing_table_idx_5gb_p,
382 rtl8812ae_delta_swing_table_idx_5gb_p_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
383 memcpy(rtldm->delta_swing_table_idx_5gb_n,
384 rtl8812ae_delta_swing_table_idx_5gb_n_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
385 }
386
387 void rtl8821ae_dm_read_and_config_txpower_track(
388 struct ieee80211_hw *hw)
389 {
390 struct rtl_priv *rtlpriv = rtl_priv(hw);
391 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
392 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
393 ("===> rtl8821ae_dm_read_and_config_txpower_track\n"));
394
395
396 memcpy(rtldm->delta_swing_table_idx_24ga_p,
397 rtl8821ae_delta_swing_table_idx_24ga_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
398 memcpy(rtldm->delta_swing_table_idx_24ga_n,
399 rtl8821ae_delta_swing_table_idx_24ga_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
400 memcpy(rtldm->delta_swing_table_idx_24gb_p,
401 rtl8821ae_delta_swing_table_idx_24gb_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
402 memcpy(rtldm->delta_swing_table_idx_24gb_n,
403 rtl8821ae_delta_swing_table_idx_24gb_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
404
405 memcpy(rtldm->delta_swing_table_idx_24gccka_p,
406 rtl8821ae_delta_swing_table_idx_24gccka_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
407 memcpy(rtldm->delta_swing_table_idx_24gccka_n,
408 rtl8821ae_delta_swing_table_idx_24gccka_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
409 memcpy(rtldm->delta_swing_table_idx_24gcckb_p,
410 rtl8821ae_delta_swing_table_idx_24gcckb_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
411 memcpy(rtldm->delta_swing_table_idx_24gcckb_n,
412 rtl8821ae_delta_swing_table_idx_24gcckb_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
413
414 memcpy(rtldm->delta_swing_table_idx_5ga_p,
415 rtl8821ae_delta_swing_table_idx_5ga_p_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
416 memcpy(rtldm->delta_swing_table_idx_5ga_n,
417 rtl8821ae_delta_swing_table_idx_5ga_n_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
418 memcpy(rtldm->delta_swing_table_idx_5gb_p,
419 rtl8821ae_delta_swing_table_idx_5gb_p_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
420 memcpy(rtldm->delta_swing_table_idx_5gb_n,
421 rtl8821ae_delta_swing_table_idx_5gb_n_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
422 }
423
424
425
426 #define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _deltaThermal) \
427 do {\
428 for(_offset = 0; _offset < _size; _offset++)\
429 {\
430 if(_deltaThermal < thermal_threshold[_direction][_offset])\
431 {\
432 if(_offset != 0)\
433 _offset--;\
434 break;\
435 }\
436 } \
437 if(_offset >= _size)\
438 _offset = _size-1;\
439 } while(0)
440
441
442 void rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw *hw,
443 u8 type,u8 *pdirection,
444 u32 *poutwrite_val)
445 {
446 struct rtl_priv *rtlpriv = rtl_priv(hw);
447 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
448 u8 pwr_val = 0;
449
450 if (type == 0){
451 if (rtlpriv->dm.bb_swing_idx_ofdm[RF90_PATH_A] <=
452 rtlpriv->dm.bb_swing_idx_ofdm_base[RF90_PATH_A]) {
453 *pdirection = 1;
454 pwr_val = rtldm->bb_swing_idx_ofdm_base[RF90_PATH_A] - rtldm->bb_swing_idx_ofdm[RF90_PATH_A];
455 } else {
456 *pdirection = 2;
457 pwr_val = rtldm->bb_swing_idx_ofdm[RF90_PATH_A] - rtldm->bb_swing_idx_ofdm_base[RF90_PATH_A];
458 }
459 } else if (type ==1) {
460 if (rtldm->bb_swing_idx_cck <= rtldm->bb_swing_idx_cck_base) {
461 *pdirection = 1;
462 pwr_val = rtldm->bb_swing_idx_cck_base - rtldm->bb_swing_idx_cck;
463 } else {
464 *pdirection = 2;
465 pwr_val = rtldm->bb_swing_idx_cck - rtldm->bb_swing_idx_cck_base;
466 }
467 }
468
469 if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
470 pwr_val = TXPWRTRACK_MAX_IDX;
471
472 *poutwrite_val = pwr_val |(pwr_val << 8)|(pwr_val << 16) | (pwr_val << 24);
473 }
474
475 void rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw *hw)
476 {
477 struct rtl_priv *rtlpriv = rtl_priv(hw);
478 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
479 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
480 u8 p = 0;
481 rtldm->bb_swing_idx_cck_base = rtldm->default_cck_index;
482 rtldm->bb_swing_idx_cck = rtldm->default_cck_index;
483 rtldm->cck_index = 0;
484
485 for (p = RF90_PATH_A; p < MAX_RF_PATH; ++p) {
486 rtldm->bb_swing_idx_ofdm_base[p] = rtldm->default_ofdm_index;
487 rtldm->bb_swing_idx_ofdm[p] = rtldm->default_ofdm_index;
488 rtldm->ofdm_index[p] = rtldm->default_ofdm_index;
489
490 rtldm->power_index_offset[p] = 0;
491 rtldm->delta_power_index[p] = 0;
492 rtldm->delta_power_index_last[p] = 0;
493
494 rtldm->aboslute_ofdm_swing_idx[p] = 0; /*Initial Mix mode power tracking*/
495 rtldm->remnant_ofdm_swing_idx[p] = 0;
496 }
497
498 rtldm->modify_txagc_flag_path_a = false; /*Initial at Modify Tx Scaling Mode*/
499 rtldm->modify_txagc_flag_path_b = false; /*Initial at Modify Tx Scaling Mode*/
500 rtldm->remnant_cck_idx = 0;
501 rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter;
502 rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter;
503 rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter;
504 }
505
506 u8 rtl8821ae_dm_get_swing_index(struct ieee80211_hw *hw)
507 {
508 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
509 u8 i = 0;
510 u32 bb_swing;
511
512 bb_swing =rtl8821ae_phy_query_bb_reg(hw, rtlhal->current_bandtype, RF90_PATH_A);
513
514 for (i = 0; i < TXSCALE_TABLE_SIZE; ++i)
515 if ( bb_swing == rtl8821ae_txscaling_table[i])
516 break;
517
518 return i;
519 }
520
521 void rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(
522 struct ieee80211_hw *hw)
523 {
524 struct rtl_priv *rtlpriv = rtl_priv(hw);
525 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
526 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
527 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
528 u8 default_swing_index = 0;
529 u8 p = 0;
530
531 rtlpriv->dm.txpower_track_control = true;
532 rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter;
533 rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter;
534 rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter;
535
536 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
537 rtl8812ae_dm_read_and_config_txpower_track(hw);
538 else
539 rtl8821ae_dm_read_and_config_txpower_track(hw);
540
541 default_swing_index = rtl8821ae_dm_get_swing_index(hw);
542
543 rtldm->default_ofdm_index = (default_swing_index == TXSCALE_TABLE_SIZE) ? 24 : default_swing_index;
544 rtldm->default_cck_index = 24;
545
546 rtldm->bb_swing_idx_cck_base = rtldm->default_cck_index;
547 rtldm->cck_index = rtldm->default_cck_index;
548
549 for (p = RF90_PATH_A; p < MAX_RF_PATH; ++p)
550 {
551 rtldm->bb_swing_idx_ofdm_base[p] = rtldm->default_ofdm_index;
552 rtldm->ofdm_index[p] = rtldm->default_ofdm_index;
553 rtldm->delta_power_index[p] = 0;
554 rtldm->power_index_offset[p] = 0;
555 rtldm->delta_power_index_last[p] = 0;
556 }
557 }
558
559 static void rtl8821ae_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
560 {
561 dm_pstable.pre_ccastate = CCA_MAX;
562 dm_pstable.cur_ccasate = CCA_MAX;
563 dm_pstable.pre_rfstate = RF_MAX;
564 dm_pstable.cur_rfstate = RF_MAX;
565 dm_pstable.rssi_val_min = 0;
566 dm_pstable.initialize = 0;
567 }
568
569
570 static void rtl8821ae_dm_diginit(struct ieee80211_hw *hw)
571 {
572 struct rtl_priv *rtlpriv = rtl_priv(hw);
573 //dm_digtable.dig_enable_flag = true;
574 dm_digtable.cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
575 /*dm_digtable.pre_igvalue = 0;
576 dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
577 dm_digtable.presta_connectstate = DIG_STA_DISCONNECT;
578 dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT;*/
579 dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW;
580 dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH;
581 dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
582 dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
583 dm_digtable.rx_gain_range_max = DM_DIG_MAX;
584 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
585 dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT;
586 dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX;
587 dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN;
588 dm_digtable.pre_cck_cca_thres = 0xff;
589 dm_digtable.cur_cck_cca_thres = 0x83;
590 dm_digtable.forbidden_igi = DM_DIG_MIN;
591 dm_digtable.large_fa_hit = 0;
592 dm_digtable.recover_cnt = 0;
593 dm_digtable.dig_dynamic_min_0 = DM_DIG_MIN;
594 dm_digtable.dig_dynamic_min_1 = DM_DIG_MIN;
595 dm_digtable.b_media_connect_0 = false;
596 dm_digtable.b_media_connect_1 = false;
597 rtlpriv->dm.b_dm_initialgain_enable = true;
598 dm_digtable.bt30_cur_igi = 0x32;
599 }
600
601 static void rtl8821ae_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
602 {
603 struct rtl_priv *rtlpriv = rtl_priv(hw);
604
605 rtlpriv->dm.bdynamic_txpower_enable = false;
606
607 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
608 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
609 }
610
611
612 void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw)
613 {
614 struct rtl_priv *rtlpriv = rtl_priv(hw);
615 rtlpriv->dm.bcurrent_turbo_edca = false;
616 rtlpriv->dm.bis_any_nonbepkts = false;
617 rtlpriv->dm.bis_cur_rdlstate = false;
618 }
619
620
621 void rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
622 {
623 struct rtl_priv *rtlpriv = rtl_priv(hw);
624 struct rate_adaptive *p_ra = &(rtlpriv->ra);
625
626 p_ra->ratr_state = DM_RATR_STA_INIT;
627 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
628
629 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
630 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
631 rtlpriv->dm.b_useramask = true;
632 else
633 rtlpriv->dm.b_useramask = false;
634
635 p_ra->high_rssi_thresh_for_ra = 50;
636 p_ra->low_rssi_thresh_for_ra = 20;
637 }
638
639
640 static void rtl8821ae_dm_init_txpower_tracking(struct ieee80211_hw *hw)
641 {
642 struct rtl_priv *rtlpriv = rtl_priv(hw);
643
644 rtlpriv->dm.btxpower_tracking = true;
645 rtlpriv->dm.btxpower_trackinginit = false;
646 rtlpriv->dm.txpowercount = 0;
647 rtlpriv->dm.txpower_track_control = true;
648 rtlpriv->dm.thermalvalue = 0;
649
650 rtlpriv->dm.ofdm_index[0] = 30;
651 rtlpriv->dm.cck_index = 20;
652
653 rtlpriv->dm.bb_swing_idx_cck_base = rtlpriv->dm.cck_index;
654
655
656 rtlpriv->dm.bb_swing_idx_ofdm[RF90_PATH_A] = rtlpriv->dm.ofdm_index[0];
657 rtlpriv->dm.bb_swing_idx_ofdm[RF90_PATH_B] = rtlpriv->dm.ofdm_index[0];
658 rtlpriv->dm.delta_power_index[0] = 0;
659 rtlpriv->dm.delta_power_index_last[0] = 0;
660 rtlpriv->dm.power_index_offset[0] = 0;
661
662 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
663 (" rtlpriv->dm.btxpower_tracking = %d\n",
664 rtlpriv->dm.btxpower_tracking));
665 }
666
667
668 void rtl8821ae_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
669 {
670 struct rtl_priv *rtlpriv = rtl_priv(hw);
671
672 rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
673
674 rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11));
675 rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
676 }
677
678
679 void rtl8821ae_dm_init(struct ieee80211_hw *hw)
680 {
681 struct rtl_priv *rtlpriv = rtl_priv(hw);
682 struct rtl_phy *rtlphy = &(rtlpriv->phy);
683
684 spin_lock(&rtlpriv->locks.iqk_lock);
685 rtlphy->b_iqk_in_progress = false;
686 spin_unlock(&rtlpriv->locks.iqk_lock);
687
688 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
689 rtl8821ae_dm_diginit(hw);
690 rtl8821ae_dm_init_rate_adaptive_mask(hw);
691 rtl8812ae_dm_path_diversity_init(hw);
692 rtl8821ae_dm_init_edca_turbo(hw);
693 rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(hw);
694 #if 1
695 rtl8821ae_dm_init_dynamic_bb_powersaving(hw);
696 rtl8821ae_dm_init_dynamic_txpower(hw);
697 rtl8821ae_dm_init_txpower_tracking(hw);
698 #endif
699 rtl8821ae_dm_init_dynamic_atc_switch(hw);
700 }
701
702 void rtl8821ae_dm_find_minimum_rssi(struct ieee80211_hw *hw)
703 {
704 struct rtl_priv *rtlpriv = rtl_priv(hw);
705 struct rtl_dig *rtl_dm_dig = &(rtlpriv->dm.dm_digtable);
706 struct rtl_mac *mac = rtl_mac(rtlpriv);
707
708 /* Determine the minimum RSSI */
709 if ((mac->link_state < MAC80211_LINKED) &&
710 (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
711 rtl_dm_dig->min_undecorated_pwdb_for_dm = 0;
712 RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
713 ("Not connected to any \n"));
714 }
715 if (mac->link_state >= MAC80211_LINKED) {
716 if (mac->opmode == NL80211_IFTYPE_AP ||
717 mac->opmode == NL80211_IFTYPE_ADHOC) {
718 rtl_dm_dig->min_undecorated_pwdb_for_dm =
719 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
720 RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
721 ("AP Client PWDB = 0x%lx \n",
722 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb));
723 } else {
724 rtl_dm_dig->min_undecorated_pwdb_for_dm =
725 rtlpriv->dm.undecorated_smoothed_pwdb;
726 RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
727 ("STA Default Port PWDB = 0x%x \n",
728 rtl_dm_dig->min_undecorated_pwdb_for_dm));
729 }
730 } else {
731 rtl_dm_dig->min_undecorated_pwdb_for_dm =
732 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
733 RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
734 ("AP Ext Port or disconnect PWDB = 0x%x \n",
735 rtl_dm_dig->min_undecorated_pwdb_for_dm));
736 }
737 RT_TRACE(COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n",
738 rtl_dm_dig->min_undecorated_pwdb_for_dm));
739 }
740
741 #if 0
742 void rtl8812ae_dm_rssi_dump_to_register(
743 struct ieee80211_hw *hw
744 )
745 {
746 struct rtl_priv *rtlpriv = rtl_priv(hw);
747
748 rtl_write_byte(rtlpriv, RA_RSSI_DUMP, Adapter->RxStats.RxRSSIPercentage[0]);
749 rtl_write_byte(rtlpriv, RB_RSSI_DUMP, Adapter->RxStats.RxRSSIPercentage[1]);
750
751 /* Rx EVM*/
752 rtl_write_byte(rtlpriv, RS1_RX_EVM_DUMP, Adapter->RxStats.RxEVMdbm[0]);
753 rtl_write_byte(rtlpriv, RS2_RX_EVM_DUMP, Adapter->RxStats.RxEVMdbm[1]);
754
755 /*Rx SNR*/
756 rtl_write_byte(rtlpriv, RA_RX_SNR_DUMP, (u1Byte)(Adapter->RxStats.RxSNRdB[0]));
757 rtl_write_byte(rtlpriv, RB_RX_SNR_DUMP, (u1Byte)(Adapter->RxStats.RxSNRdB[1]));
758
759 /*Rx Cfo_Short*/
760 rtl_write_word(rtlpriv, RA_CFO_SHORT_DUMP, Adapter->RxStats.RxCfoShort[0]);
761 rtl_write_word(rtlpriv, RB_CFO_SHORT_DUMP, Adapter->RxStats.RxCfoShort[1]);
762
763 /*Rx Cfo_Tail*/
764 rtl_write_word(rtlpriv, RA_CFO_LONG_DUMP, Adapter->RxStats.RxCfoTail[0]);
765 rtl_write_word(rtlpriv, RB_CFO_LONG_DUMP, Adapter->RxStats.RxCfoTail[1]);
766
767 }
768 #endif
769
770 static void rtl8821ae_dm_check_rssi_monitor(struct ieee80211_hw *hw)
771 {
772 struct rtl_priv *rtlpriv = rtl_priv(hw);
773 struct rtl_sta_info *drv_priv;
774 u8 h2c_parameter[3] = { 0 };
775 long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
776
777
778 /* AP & ADHOC & MESH */
779 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
780 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
781 if(drv_priv->rssi_stat.undecorated_smoothed_pwdb < tmp_entry_min_pwdb)
782 tmp_entry_min_pwdb = drv_priv->rssi_stat.undecorated_smoothed_pwdb;
783 if(drv_priv->rssi_stat.undecorated_smoothed_pwdb > tmp_entry_max_pwdb)
784 tmp_entry_max_pwdb = drv_priv->rssi_stat.undecorated_smoothed_pwdb;
785
786 /*h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF);
787 h2c_parameter[1] = 0x20;
788 h2c_parameter[0] = drv_priv->rssi_stat;
789 rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter);*/
790 }
791 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
792
793 /* If associated entry is found */
794 if (tmp_entry_max_pwdb != 0) {
795 rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = tmp_entry_max_pwdb;
796 RTPRINT(rtlpriv, FDM, DM_PWDB, ("EntryMaxPWDB = 0x%lx(%ld)\n",
797 tmp_entry_max_pwdb, tmp_entry_max_pwdb));
798 } else {
799 rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0;
800 }
801 /* If associated entry is found */
802 if (tmp_entry_min_pwdb != 0xff) {
803 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = tmp_entry_min_pwdb;
804 RTPRINT(rtlpriv, FDM, DM_PWDB, ("EntryMinPWDB = 0x%lx(%ld)\n",
805 tmp_entry_min_pwdb, tmp_entry_min_pwdb));
806 } else {
807 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0;
808 }
809 /* Indicate Rx signal strength to FW. */
810 if (rtlpriv->dm.b_useramask) {
811 h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF);
812 h2c_parameter[1] = 0x20;
813 h2c_parameter[0] = 0;
814 rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter);
815 } else {
816 rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undecorated_smoothed_pwdb);
817 }
818 rtl8821ae_dm_find_minimum_rssi(hw);
819 dm_digtable.rssi_val_min = rtlpriv->dm.dm_digtable.min_undecorated_pwdb_for_dm;
820 }
821
822 void rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 current_cca)
823 {
824 struct rtl_priv *rtlpriv = rtl_priv(hw);
825
826 if (dm_digtable.cur_cck_cca_thres != current_cca)
827 rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11AC, current_cca);
828
829 dm_digtable.pre_cck_cca_thres = dm_digtable.cur_cck_cca_thres;
830 dm_digtable.cur_cck_cca_thres = current_cca;
831 }
832
833 void rtl8821ae_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
834 {
835 struct rtl_priv *rtlpriv = rtl_priv(hw);
836 if(dm_digtable.stop_dig)
837 return;
838
839 if (dm_digtable.cur_igvalue != current_igi){
840 rtl_set_bbreg(hw, DM_REG_IGI_A_11AC, DM_BIT_IGI_11AC, current_igi);
841 if (rtlpriv->phy.rf_type != RF_1T1R)
842 rtl_set_bbreg(hw, DM_REG_IGI_B_11AC, DM_BIT_IGI_11AC, current_igi);
843 }
844 //dm_digtable.pre_igvalue = dm_digtable.cur_igvalue;
845 dm_digtable.cur_igvalue = current_igi;
846 }
847
848 static void rtl8821ae_dm_dig(struct ieee80211_hw *hw)
849 {
850 struct rtl_priv *rtlpriv = rtl_priv(hw);
851 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
852 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
853 u8 dig_dynamic_min;
854 u8 dig_max_of_min;
855 bool first_connect, first_disconnect;
856 u8 dm_dig_max, dm_dig_min, offset;
857 u8 current_igi =dm_digtable.cur_igvalue;
858
859
860 RT_TRACE(COMP_DIG, DBG_LOUD,("rtl8821ae_dm_dig()==>\n"));
861
862
863 if (mac->act_scanning == true) {
864 RT_TRACE(COMP_DIG, DBG_LOUD,("rtl8821ae_dm_dig() Return: In Scan Progress \n"));
865 return;
866 }
867
868 /*add by Neil Chen to avoid PSD is processing*/
869 dig_dynamic_min = dm_digtable.dig_dynamic_min_0;
870 first_connect = (mac->link_state >= MAC80211_LINKED) &&
871 (dm_digtable.b_media_connect_0 == false);
872 first_disconnect = (mac->link_state < MAC80211_LINKED) &&
873 (dm_digtable.b_media_connect_0 == true);
874
875 /*1 Boundary Decision*/
876
877
878 dm_dig_max = 0x5A;
879
880 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE)
881 dm_dig_min = DM_DIG_MIN;
882 else
883 dm_dig_min = 0x1C;
884
885 dig_max_of_min = DM_DIG_MAX_AP;
886
887 if (mac->link_state >= MAC80211_LINKED) {
888 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE)
889 offset = 20;
890 else
891 offset = 10;
892
893 if ((dm_digtable.rssi_val_min + offset) > dm_dig_max)
894 dm_digtable.rx_gain_range_max = dm_dig_max;
895 else if ((dm_digtable.rssi_val_min + offset) < dm_dig_min)
896 dm_digtable.rx_gain_range_max = dm_dig_min;
897 else
898 dm_digtable.rx_gain_range_max = dm_digtable.rssi_val_min + offset;
899
900 if(rtlpriv->dm.b_one_entry_only){
901 offset = 0;
902
903 if (dm_digtable.rssi_val_min - offset < dm_dig_min)
904 dig_dynamic_min = dm_dig_min;
905 else if (dm_digtable.rssi_val_min - offset > dig_max_of_min)
906 dig_dynamic_min = dig_max_of_min;
907 else
908 dig_dynamic_min = dm_digtable.rssi_val_min - offset;
909
910 RT_TRACE(COMP_DIG, DBG_LOUD,
911 ("rtl8821ae_dm_dig() : bOneEntryOnly=TRUE, dig_dynamic_min=0x%x\n",
912 dig_dynamic_min));
913 RT_TRACE(COMP_DIG, DBG_LOUD,
914 ("rtl8821ae_dm_dig() : dm_digtable.rssi_val_min=%d",dm_digtable.
915 rssi_val_min));
916 } else {
917 dig_dynamic_min = dm_dig_min;
918 }
919 } else {
920 dm_digtable.rx_gain_range_max = dm_dig_max;
921 dig_dynamic_min = dm_dig_min;
922 RT_TRACE(COMP_DIG, DBG_LOUD,
923 ("rtl8821ae_dm_dig() : No Link\n"));
924 }
925
926 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
927 RT_TRACE(COMP_DIG, DBG_LOUD,
928 ("rtl8821ae_dm_dig(): Abnormally false alarm case. \n"));
929
930 if (dm_digtable.large_fa_hit != 3)
931 dm_digtable.large_fa_hit++;
932 if (dm_digtable.forbidden_igi < current_igi) {
933 dm_digtable.forbidden_igi = current_igi;
934 dm_digtable.large_fa_hit = 1;
935 }
936
937 if (dm_digtable.large_fa_hit >= 3) {
938 if((dm_digtable.forbidden_igi + 1) > dm_digtable.rx_gain_range_max)
939 dm_digtable.rx_gain_range_min = dm_digtable.rx_gain_range_max;
940 else
941 dm_digtable.rx_gain_range_min = (dm_digtable.forbidden_igi + 1);
942 dm_digtable.recover_cnt = 3600;
943 }
944
945 } else {
946 /*Recovery mechanism for IGI lower bound*/
947 if (dm_digtable.recover_cnt != 0)
948 dm_digtable.recover_cnt --;
949 else {
950 if (dm_digtable.large_fa_hit < 3) {
951 if ((dm_digtable.forbidden_igi -1) < dig_dynamic_min) {
952 dm_digtable.forbidden_igi = dig_dynamic_min;
953 dm_digtable.rx_gain_range_min = dig_dynamic_min;
954 RT_TRACE(COMP_DIG, DBG_LOUD,
955 ("rtl8821ae_dm_dig(): Normal Case: At Lower Bound\n"));
956 } else {
957 dm_digtable.forbidden_igi --;
958 dm_digtable.rx_gain_range_min = (dm_digtable.forbidden_igi + 1);
959 RT_TRACE(COMP_DIG, DBG_LOUD,
960 ("rtl8821ae_dm_dig(): Normal Case: Approach Lower Bound\n"));
961 }
962 } else {
963 dm_digtable.large_fa_hit = 0;
964 }
965 }
966 }
967 RT_TRACE(COMP_DIG, DBG_LOUD,
968 ("rtl8821ae_dm_dig(): pDM_DigTable->LargeFAHit=%d\n",
969 dm_digtable.large_fa_hit));
970
971 if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10)
972 dm_digtable.rx_gain_range_min = dm_dig_min;
973
974 if (dm_digtable.rx_gain_range_min > dm_digtable.rx_gain_range_max)
975 dm_digtable.rx_gain_range_min = dm_digtable.rx_gain_range_max;
976
977 /*Adjust initial gain by false alarm*/
978 if (mac->link_state >= MAC80211_LINKED) {
979 RT_TRACE(COMP_DIG, DBG_LOUD,
980 ("rtl8821ae_dm_dig(): DIG AfterLink\n"));
981 if (first_connect) {
982 if (dm_digtable.rssi_val_min <= dig_max_of_min)
983 current_igi = dm_digtable.rssi_val_min;
984 else
985 current_igi = dig_max_of_min;
986 RT_TRACE(COMP_DIG, DBG_LOUD,
987 ("rtl8821ae_dm_dig: First Connect\n"));
988 } else {
989 if(rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
990 current_igi = current_igi + 4;
991 else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
992 current_igi = current_igi + 2;
993 else if(rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
994 current_igi = current_igi - 2;
995
996 if((rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10)
997 &&(rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)) {
998 current_igi = dm_digtable.rx_gain_range_min;
999 RT_TRACE(COMP_DIG, DBG_LOUD,
1000 ("rtl8821ae_dm_dig(): Beacon is less than 10 and FA is less than 768, IGI GOES TO 0x1E!!!!!!!!!!!!\n"));
1001 }
1002 }
1003 } else{
1004 RT_TRACE(COMP_DIG, DBG_LOUD,
1005 ("rtl8821ae_dm_dig(): DIG BeforeLink\n"));
1006 if (first_disconnect){
1007 current_igi = dm_digtable.rx_gain_range_min;
1008 RT_TRACE(COMP_DIG, DBG_LOUD,
1009 ("rtl8821ae_dm_dig(): First DisConnect \n"));
1010 } else {
1011 /*2012.03.30 LukeLee: enable DIG before link but with very high thresholds*/
1012 if (rtlpriv->falsealm_cnt.cnt_all > 2000)
1013 current_igi = current_igi + 4;
1014 else if (rtlpriv->falsealm_cnt.cnt_all > 600)
1015 current_igi = current_igi + 2;
1016 else if(rtlpriv->falsealm_cnt.cnt_all < 300)
1017 current_igi = current_igi - 2;
1018 if (current_igi >= 0x3e)
1019 current_igi = 0x3e;
1020 RT_TRACE(COMP_DIG, DBG_LOUD,("rtl8821ae_dm_dig(): England DIG \n"));
1021 }
1022 }
1023 RT_TRACE(COMP_DIG, DBG_LOUD,
1024 ("rtl8821ae_dm_dig(): DIG End Adjust IGI\n"));
1025 /* Check initial gain by upper/lower bound*/
1026
1027 if (current_igi > dm_digtable.rx_gain_range_max)
1028 current_igi = dm_digtable.rx_gain_range_max;
1029 if (current_igi < dm_digtable.rx_gain_range_min)
1030 current_igi = dm_digtable.rx_gain_range_min;
1031
1032 RT_TRACE(COMP_DIG, DBG_LOUD,
1033 ("rtl8821ae_dm_dig(): rx_gain_range_max=0x%x, rx_gain_range_min=0x%x\n",
1034 dm_digtable.rx_gain_range_max, dm_digtable.rx_gain_range_min));
1035 RT_TRACE(COMP_DIG, DBG_LOUD,
1036 ("rtl8821ae_dm_dig(): TotalFA=%d\n", rtlpriv->falsealm_cnt.cnt_all));
1037 RT_TRACE(COMP_DIG, DBG_LOUD,
1038 ("rtl8821ae_dm_dig(): CurIGValue=0x%x\n", current_igi));
1039
1040 rtl8821ae_dm_write_dig(hw, current_igi);
1041 dm_digtable.b_media_connect_0= ((mac->link_state >= MAC80211_LINKED) ? true :false);
1042 dm_digtable.dig_dynamic_min_0 = dig_dynamic_min;
1043 }
1044
1045 static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw)
1046 {
1047 struct rtl_priv *rtlpriv = rtl_priv(hw);
1048 u8 cnt = 0;
1049 struct rtl_sta_info *drv_priv;
1050
1051 rtlpriv->dm.b_one_entry_only = false;
1052
1053 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
1054 rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1055 rtlpriv->dm.b_one_entry_only = true;
1056 return;
1057 }
1058
1059 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1060 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
1061 rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
1062 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1063 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
1064 cnt ++;
1065 }
1066 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1067
1068 if (cnt == 1)
1069 rtlpriv->dm.b_one_entry_only = true;
1070 }
1071 }
1072
1073
1074 static void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
1075 {
1076 struct rtl_priv *rtlpriv = rtl_priv(hw);
1077 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
1078 u32 cck_enable =0;
1079
1080 /*read OFDM FA counter*/
1081 falsealm_cnt->cnt_ofdm_fail = rtl_get_bbreg(hw, ODM_REG_OFDM_FA_11AC, BMASKLWORD);
1082 falsealm_cnt->cnt_cck_fail = rtl_get_bbreg(hw, ODM_REG_CCK_FA_11AC, BMASKLWORD);
1083
1084 cck_enable = rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, BIT(28));
1085 if (cck_enable) /*if(pDM_Odm->pBandType == ODM_BAND_2_4G)*/
1086 falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail + falsealm_cnt->cnt_cck_fail;
1087 else
1088 falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail;
1089
1090 /*reset OFDM FA counter*/
1091 rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
1092 rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
1093 /* reset CCK FA counter*/
1094 rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
1095 rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
1096
1097 RT_TRACE(COMP_DIG, DBG_LOUD, ("Cnt_Cck_fail=%d\n",
1098 falsealm_cnt->cnt_cck_fail));
1099 RT_TRACE(COMP_DIG, DBG_LOUD, ("cnt_ofdm_fail=%d\n",
1100 falsealm_cnt->cnt_ofdm_fail));
1101 RT_TRACE(COMP_DIG, DBG_LOUD, ("Total False Alarm=%d\n",
1102 falsealm_cnt->cnt_all));
1103 }
1104
1105 void rtl8812ae_dm_check_txpower_tracking_thermalmeter(
1106 struct ieee80211_hw *hw)
1107 {
1108 struct rtl_priv *rtlpriv = rtl_priv(hw);
1109 static u8 tm_trigger = 0;
1110
1111 if (!rtlpriv->dm.btxpower_tracking)
1112 return;
1113
1114 if (!tm_trigger) {
1115 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16), 0x03);
1116 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1117 ("Trigger 8812 Thermal Meter!!\n"));
1118 tm_trigger = 1;
1119 return;
1120 } else {
1121 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1122 ("Schedule TxPowerTracking direct call!!\n"));
1123 rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw);
1124 tm_trigger = 0;
1125 }
1126 }
1127
1128 static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw)
1129 {
1130 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1131 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1132 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1133
1134 if (mac->link_state >= MAC80211_LINKED) {
1135 /*if ((*rtldm->p_channel != rtldm->pre_channel )
1136 && (!mac->act_scanning)) {
1137 rtldm->pre_channel = *rtldm->p_channel;
1138 rtldm->linked_interval = 0;
1139 }*/
1140
1141 if(rtldm->linked_interval < 3)
1142 rtldm->linked_interval ++;
1143
1144 if(rtldm->linked_interval == 2)
1145 {
1146 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
1147 rtl8812ae_phy_iq_calibrate(hw, false);
1148 else
1149 rtl8821ae_phy_iq_calibrate(hw, false);
1150 }
1151 } else {
1152 rtldm->linked_interval = 0;
1153 }
1154 }
1155
1156
1157 void rtl8812ae_get_delta_swing_table(
1158 struct ieee80211_hw *hw,
1159 u8 **temperature_up_a,
1160 u8 **temperature_down_a,
1161 u8 **temperature_up_b,
1162 u8 **temperature_down_b
1163 )
1164 {
1165 struct rtl_priv *rtlpriv = rtl_priv(hw);
1166 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1167 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1168 u8 channel = rtlphy->current_channel;
1169 u8 rate = rtldm->tx_rate;
1170
1171
1172 if ( 1 <= channel && channel <= 14) {
1173 if (RX_HAL_IS_CCK_RATE(rate)) {
1174 *temperature_up_a = rtldm->delta_swing_table_idx_24gccka_p;
1175 *temperature_down_a = rtldm->delta_swing_table_idx_24gccka_n;
1176 *temperature_up_b = rtldm->delta_swing_table_idx_24gcckb_p;
1177 *temperature_down_b = rtldm->delta_swing_table_idx_24gcckb_n;
1178 } else {
1179 *temperature_up_a = rtldm->delta_swing_table_idx_24ga_p;
1180 *temperature_down_a = rtldm->delta_swing_table_idx_24ga_n;
1181 *temperature_up_b = rtldm->delta_swing_table_idx_24gb_p;
1182 *temperature_down_b = rtldm->delta_swing_table_idx_24gb_n;
1183 }
1184 } else if ( 36 <= channel && channel <= 64) {
1185 *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[0];
1186 *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[0];
1187 *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[0];
1188 *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[0];
1189 } else if ( 100 <= channel && channel <= 140) {
1190 *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[1];
1191 *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[1];
1192 *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[1];
1193 *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[1];
1194 } else if ( 149 <= channel && channel <= 173) {
1195 *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[2];
1196 *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[2];
1197 *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[2];
1198 *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[2];
1199 } else {
1200 *temperature_up_a = (u8*)rtl8818e_delta_swing_table_idx_24gb_p_txpwrtrack;
1201 *temperature_down_a =(u8*)rtl8818e_delta_swing_table_idx_24gb_n_txpwrtrack;
1202 *temperature_up_b = (u8*)rtl8818e_delta_swing_table_idx_24gb_p_txpwrtrack;
1203 *temperature_down_b = (u8*)rtl8818e_delta_swing_table_idx_24gb_n_txpwrtrack;
1204 }
1205
1206 return;
1207 }
1208
1209 void rtl8812ae_phy_lccalibrate(
1210 struct ieee80211_hw *hw)
1211 {
1212 struct rtl_priv *rtlpriv = rtl_priv(hw);
1213
1214 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("===> rtl8812ae_phy_lccalibrate\n"));
1215
1216 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("<=== rtl8812ae_phy_lccalibrate\n"));
1217
1218 }
1219
1220 void rtl8812ae_dm_update_init_rate(
1221 struct ieee80211_hw *hw,
1222 u8 rate
1223 )
1224 {
1225 struct rtl_priv *rtlpriv = rtl_priv(hw);
1226 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1227 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1228 u8 p = 0;
1229
1230 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1231 ("Get C2H Command! Rate=0x%x\n", rate));
1232
1233 rtldm->tx_rate = rate;
1234
1235 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE){
1236 rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, RF90_PATH_A, 0);
1237 }
1238 else
1239 {
1240 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1241 {
1242 rtl8812ae_dm_txpwr_track_set_pwr(hw, BBSWING, p, 0);
1243 }
1244 }
1245
1246 }
1247
1248 u8 rtl8812ae_hw_rate_to_mrate(
1249 struct ieee80211_hw *hw,
1250 u8 rate
1251 )
1252 {
1253 struct rtl_priv *rtlpriv = rtl_priv(hw);
1254 u8 ret_rate = MGN_1M;
1255
1256
1257 switch(rate)
1258 {
1259 case DESC_RATE1M: ret_rate = MGN_1M; break;
1260 case DESC_RATE2M: ret_rate = MGN_2M; break;
1261 case DESC_RATE5_5M: ret_rate = MGN_5_5M; break;
1262 case DESC_RATE11M: ret_rate = MGN_11M; break;
1263 case DESC_RATE6M: ret_rate = MGN_6M; break;
1264 case DESC_RATE9M: ret_rate = MGN_9M; break;
1265 case DESC_RATE12M: ret_rate = MGN_12M; break;
1266 case DESC_RATE18M: ret_rate = MGN_18M; break;
1267 case DESC_RATE24M: ret_rate = MGN_24M; break;
1268 case DESC_RATE36M: ret_rate = MGN_36M; break;
1269 case DESC_RATE48M: ret_rate = MGN_48M; break;
1270 case DESC_RATE54M: ret_rate = MGN_54M; break;
1271 case DESC_RATEMCS0: ret_rate = MGN_MCS0; break;
1272 case DESC_RATEMCS1: ret_rate = MGN_MCS1; break;
1273 case DESC_RATEMCS2: ret_rate = MGN_MCS2; break;
1274 case DESC_RATEMCS3: ret_rate = MGN_MCS3; break;
1275 case DESC_RATEMCS4: ret_rate = MGN_MCS4; break;
1276 case DESC_RATEMCS5: ret_rate = MGN_MCS5; break;
1277 case DESC_RATEMCS6: ret_rate = MGN_MCS6; break;
1278 case DESC_RATEMCS7: ret_rate = MGN_MCS7; break;
1279 case DESC_RATEMCS8: ret_rate = MGN_MCS8; break;
1280 case DESC_RATEMCS9: ret_rate = MGN_MCS9; break;
1281 case DESC_RATEMCS10: ret_rate = MGN_MCS10; break;
1282 case DESC_RATEMCS11: ret_rate = MGN_MCS11; break;
1283 case DESC_RATEMCS12: ret_rate = MGN_MCS12; break;
1284 case DESC_RATEMCS13: ret_rate = MGN_MCS13; break;
1285 case DESC_RATEMCS14: ret_rate = MGN_MCS14; break;
1286 case DESC_RATEMCS15: ret_rate = MGN_MCS15; break;
1287 case DESC_RATEVHT1SS_MCS0: ret_rate = MGN_VHT1SS_MCS0; break;
1288 case DESC_RATEVHT1SS_MCS1: ret_rate = MGN_VHT1SS_MCS1; break;
1289 case DESC_RATEVHT1SS_MCS2: ret_rate = MGN_VHT1SS_MCS2; break;
1290 case DESC_RATEVHT1SS_MCS3: ret_rate = MGN_VHT1SS_MCS3; break;
1291 case DESC_RATEVHT1SS_MCS4: ret_rate = MGN_VHT1SS_MCS4; break;
1292 case DESC_RATEVHT1SS_MCS5: ret_rate = MGN_VHT1SS_MCS5; break;
1293 case DESC_RATEVHT1SS_MCS6: ret_rate = MGN_VHT1SS_MCS6; break;
1294 case DESC_RATEVHT1SS_MCS7: ret_rate = MGN_VHT1SS_MCS7; break;
1295 case DESC_RATEVHT1SS_MCS8: ret_rate = MGN_VHT1SS_MCS8; break;
1296 case DESC_RATEVHT1SS_MCS9: ret_rate = MGN_VHT1SS_MCS9; break;
1297 case DESC_RATEVHT2SS_MCS0: ret_rate = MGN_VHT2SS_MCS0; break;
1298 case DESC_RATEVHT2SS_MCS1: ret_rate = MGN_VHT2SS_MCS1; break;
1299 case DESC_RATEVHT2SS_MCS2: ret_rate = MGN_VHT2SS_MCS2; break;
1300 case DESC_RATEVHT2SS_MCS3: ret_rate = MGN_VHT2SS_MCS3; break;
1301 case DESC_RATEVHT2SS_MCS4: ret_rate = MGN_VHT2SS_MCS4; break;
1302 case DESC_RATEVHT2SS_MCS5: ret_rate = MGN_VHT2SS_MCS5; break;
1303 case DESC_RATEVHT2SS_MCS6: ret_rate = MGN_VHT2SS_MCS6; break;
1304 case DESC_RATEVHT2SS_MCS7: ret_rate = MGN_VHT2SS_MCS7; break;
1305 case DESC_RATEVHT2SS_MCS8: ret_rate = MGN_VHT2SS_MCS8; break;
1306 case DESC_RATEVHT2SS_MCS9: ret_rate = MGN_VHT2SS_MCS9; break;
1307
1308 default:
1309 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1310 ("HwRateToMRate8812(): Non supported Rate [%x]!!!\n",rate ));
1311 break;
1312 }
1313 return ret_rate;
1314 }
1315
1316 /*-----------------------------------------------------------------------------
1317 * Function: odm_TxPwrTrackSetPwr88E()
1318 *
1319 * Overview: 88E change all channel tx power according to flag.
1320 * OFDM & CCK are all different.
1321 *
1322 * Input: NONE
1323 *
1324 * Output: NONE
1325 *
1326 * Return: NONE
1327 *
1328 * Revised History:
1329 * When Who Remark
1330 * 04/23/2012 MHC Create Version 0.
1331 *
1332 *---------------------------------------------------------------------------*/
1333 void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
1334 enum pwr_track_control_method method, u8 rf_path, u8 channel_mapped_index)
1335 {
1336 struct rtl_priv *rtlpriv = rtl_priv(hw);
1337 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1338 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1339 u32 final_bb_swing_idx[2];
1340 u8 pwr_tracking_limit = 26; /*+1.0dB*/
1341 u8 tx_rate = 0xFF;
1342 s8 final_ofdm_swing_index = 0;
1343
1344 if(rtldm->tx_rate != 0xFF)
1345 tx_rate = rtl8812ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
1346
1347
1348 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1349 ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
1350
1351 if(tx_rate != 0xFF) { /*20130429 Mimic Modify High Rate BBSwing Limit.*/
1352 /*CCK*/
1353 if((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
1354 pwr_tracking_limit = 32; /*+4dB*/
1355 /*OFDM*/
1356 else if((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
1357 pwr_tracking_limit = 30; /*+3dB*/
1358 else if(tx_rate == MGN_54M)
1359 pwr_tracking_limit = 28; /*+2dB*/
1360 /*HT*/
1361 else if((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) /*QPSK/BPSK*/
1362 pwr_tracking_limit = 34; /*+5dB*/
1363 else if((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) /*16QAM*/
1364 pwr_tracking_limit = 30; /*+3dB*/
1365 else if((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) /*64QAM*/
1366 pwr_tracking_limit = 28; /*+2dB*/
1367
1368 else if((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10)) /*QPSK/BPSK*/
1369 pwr_tracking_limit = 34; /*+5dB*/
1370 else if((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12)) /*16QAM*/
1371 pwr_tracking_limit = 30; /*+3dB*/
1372 else if((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15)) /*64QAM*/
1373 pwr_tracking_limit = 28; /*+2dB*/
1374
1375 /*2 VHT*/
1376 else if((tx_rate >= MGN_VHT1SS_MCS0) && (tx_rate <= MGN_VHT1SS_MCS2)) /*QPSK/BPSK*/
1377 pwr_tracking_limit = 34; /*+5dB*/
1378 else if((tx_rate >= MGN_VHT1SS_MCS3) && (tx_rate <= MGN_VHT1SS_MCS4)) /*16QAM*/
1379 pwr_tracking_limit = 30; /*+3dB*/
1380 else if((tx_rate >= MGN_VHT1SS_MCS5)&&(tx_rate <= MGN_VHT1SS_MCS6)) /*64QAM*/
1381 pwr_tracking_limit = 28; /*+2dB*/
1382 else if(tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
1383 pwr_tracking_limit = 26; /*+1dB*/
1384 else if(tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
1385 pwr_tracking_limit = 24; /*+0dB*/
1386 else if(tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
1387 pwr_tracking_limit = 22; /*-1dB*/
1388
1389 else if((tx_rate >= MGN_VHT2SS_MCS0)&&(tx_rate <= MGN_VHT2SS_MCS2)) /*QPSK/BPSK*/
1390 pwr_tracking_limit = 34; /*+5dB*/
1391 else if((tx_rate >= MGN_VHT2SS_MCS3)&&(tx_rate <= MGN_VHT2SS_MCS4)) /*16QAM*/
1392 pwr_tracking_limit = 30; /*+3dB*/
1393 else if((tx_rate >= MGN_VHT2SS_MCS5)&&(tx_rate <= MGN_VHT2SS_MCS6)) /*64QAM*/
1394 pwr_tracking_limit = 28; /*+2dB*/
1395 else if(tx_rate == MGN_VHT2SS_MCS7) /*64QAM*/
1396 pwr_tracking_limit = 26; /*+1dB*/
1397 else if(tx_rate == MGN_VHT2SS_MCS8) /*256QAM*/
1398 pwr_tracking_limit = 24; /*+0dB*/
1399 else if(tx_rate == MGN_VHT2SS_MCS9) /*256QAM*/
1400 pwr_tracking_limit = 22; /*-1dB*/
1401 else
1402 pwr_tracking_limit = 24;
1403 }
1404 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1405 ("TxRate=0x%x, PwrTrackingLimit=%d\n", tx_rate, pwr_tracking_limit));
1406
1407
1408 if (method == BBSWING) {
1409 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1410 ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
1411
1412 if (rf_path == RF90_PATH_A) {
1413 final_bb_swing_idx[RF90_PATH_A] =
1414 (rtldm->ofdm_index[RF90_PATH_A] > pwr_tracking_limit) ?
1415 pwr_tracking_limit : rtldm->ofdm_index[RF90_PATH_A];
1416 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1417 ("pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d, \
1418 pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
1419 rtldm->ofdm_index[RF90_PATH_A], final_bb_swing_idx[RF90_PATH_A]));
1420
1421 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_bb_swing_idx[RF90_PATH_A]]);
1422 } else {
1423 final_bb_swing_idx[RF90_PATH_B] =
1424 rtldm->ofdm_index[RF90_PATH_B] > pwr_tracking_limit ? \
1425 pwr_tracking_limit : rtldm->ofdm_index[RF90_PATH_B];
1426 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1427 ("pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_B]=%d, \
1428 pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_B]=%d\n",
1429 rtldm->ofdm_index[RF90_PATH_B], final_bb_swing_idx[RF90_PATH_B]));
1430
1431 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_bb_swing_idx[RF90_PATH_B]]);
1432 }
1433 } else if (method == MIX_MODE) {
1434 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1435 ("pDM_Odm->DefaultOfdmIndex=%d, \
1436 pDM_Odm->Aboslute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
1437 rtldm->default_ofdm_index, rtldm->aboslute_ofdm_swing_idx[rf_path],
1438 rf_path ));
1439
1440
1441 final_ofdm_swing_index = rtldm->default_ofdm_index + rtldm->aboslute_ofdm_swing_idx[rf_path];
1442
1443 if (rf_path == RF90_PATH_A) {
1444 if(final_ofdm_swing_index > pwr_tracking_limit) { /*BBSwing higher then Limit*/
1445
1446 rtldm->remnant_cck_idx = final_ofdm_swing_index - pwr_tracking_limit;
1447 /* CCK Follow the same compensate value as Path A*/
1448 rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index - pwr_tracking_limit;
1449
1450 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[pwr_tracking_limit]);
1451
1452 rtldm->modify_txagc_flag_path_a = true;
1453
1454 /*Set TxAGC Page C{};*/
1455 rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
1456
1457 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1458 ("******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d \n",
1459 pwr_tracking_limit, rtldm->remnant_ofdm_swing_idx[rf_path]));
1460 } else if (final_ofdm_swing_index < 0) {
1461 rtldm->remnant_cck_idx = final_ofdm_swing_index;
1462 /* CCK Follow the same compensate value as Path A*/
1463 rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index;
1464
1465 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[0]);
1466
1467 rtldm->modify_txagc_flag_path_a = true;
1468
1469 /*Set TxAGC Page C{};*/
1470 rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
1471
1472 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1473 ("******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d \n",
1474 rtldm->remnant_ofdm_swing_idx[rf_path]));
1475 } else {
1476 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_ofdm_swing_index]);
1477
1478 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1479 ("******Path_A Compensate with BBSwing , Final_OFDM_Swing_Index = %d \n",
1480 final_ofdm_swing_index));
1481
1482 if(rtldm->modify_txagc_flag_path_a) { /*If TxAGC has changed, reset TxAGC again*/
1483 rtldm->remnant_cck_idx = 0;
1484 rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
1485
1486 /*Set TxAGC Page C{};*/
1487 rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
1488
1489 rtldm->modify_txagc_flag_path_a = false;
1490
1491 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1492 ("******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE \n"));
1493 }
1494 }
1495 }
1496
1497 if (rf_path == RF90_PATH_B) {
1498 if(final_ofdm_swing_index > pwr_tracking_limit) { /*BBSwing higher then Limit*/
1499 rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index - pwr_tracking_limit;
1500
1501 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[pwr_tracking_limit]);
1502
1503 rtldm->modify_txagc_flag_path_b = true;
1504
1505 /*Set TxAGC Page E{};*/
1506 rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_B);
1507
1508 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1509 ("******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d \n",
1510 pwr_tracking_limit, rtldm->remnant_ofdm_swing_idx[rf_path]));
1511 } else if (final_ofdm_swing_index < 0) {
1512 rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index;
1513
1514 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[0]);
1515
1516 rtldm->modify_txagc_flag_path_b = true;
1517
1518 /*Set TxAGC Page E{};*/
1519 rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_B);
1520
1521 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1522 ("******Path_B Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d \n",
1523 rtldm->remnant_ofdm_swing_idx[rf_path] ));
1524 } else {
1525 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_ofdm_swing_index]);
1526
1527 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1528 ("******Path_B Compensate with BBSwing , Final_OFDM_Swing_Index = %d \n",
1529 final_ofdm_swing_index));
1530
1531 if(rtldm->modify_txagc_flag_path_b) { /*If TxAGC has changed, reset TxAGC again*/
1532 rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
1533
1534 /*Set TxAGC Page E{};*/
1535 rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_B);
1536
1537 rtldm->modify_txagc_flag_path_b = false;
1538
1539 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1540 ("******Path_B dm_Odm->Modify_TxAGC_Flag = FALSE \n"));
1541 }
1542 }
1543 }
1544
1545 } else {
1546 return;
1547 }
1548 }
1549
1550 void rtl8812ae_dm_txpower_tracking_callback_thermalmeter
1551 (struct ieee80211_hw *hw)
1552 {
1553 struct rtl_priv *rtlpriv = rtl_priv(hw);
1554 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1555 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1556 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1557 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1558
1559 u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
1560 u8 thermal_value_avg_count = 0;
1561 u32 thermal_value_avg = 0;
1562
1563 u8 ofdm_min_index = 6; /*OFDM BB Swing should be less than +3.0dB, which is required by Arthur*/
1564 u8 index_for_channel = 0; /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
1565
1566 /* 1. The following TWO tables decide the final index of OFDM/CCK swing table.*/
1567 u8 *delta_swing_table_idx_tup_a;
1568 u8 *delta_swing_table_idx_tdown_a;
1569 u8 *delta_swing_table_idx_tup_b;
1570 u8 *delta_swing_table_idx_tdown_b;
1571
1572 /*2. Initilization ( 7 steps in total )*/
1573 rtl8812ae_get_delta_swing_table(hw, (u8**)&delta_swing_table_idx_tup_a,
1574 (u8**)&delta_swing_table_idx_tdown_a,
1575 (u8**)&delta_swing_table_idx_tup_b,
1576 (u8**)&delta_swing_table_idx_tdown_b);
1577
1578 rtldm->btxpower_trackinginit = true;
1579
1580 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1581 ("===>rtl8812ae_dm_txpower_tracking_callback_thermalmeter, \
1582 \n pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:\
1583 %d, pDM_Odm->DefaultOfdmIndex: %d\n",
1584 rtldm->bb_swing_idx_cck_base,
1585 rtldm->bb_swing_idx_ofdm_base[RF90_PATH_A],
1586 rtldm->default_ofdm_index));
1587
1588 thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER_8812A, 0xfc00); /*0x42: RF Reg[15:10] 88E*/
1589 if( ! rtldm->txpower_track_control || rtlefuse->eeprom_thermalmeter == 0 ||
1590 rtlefuse->eeprom_thermalmeter == 0xFF)
1591 return;
1592
1593
1594 /* 3. Initialize ThermalValues of RFCalibrateInfo*/
1595
1596 if(rtlhal->reloadtxpowerindex)
1597 {
1598 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1599 ("reload ofdm index for band switch\n"));
1600 }
1601
1602 /*4. Calculate average thermal meter*/
1603 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
1604 rtldm->thermalvalue_avg_index++;
1605 if(rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
1606 /*Average times = c.AverageThermalNum*/
1607 rtldm->thermalvalue_avg_index = 0;
1608
1609 for(i = 0; i < AVG_THERMAL_NUM_8812A; i++)
1610 {
1611 if(rtldm->thermalvalue_avg[i])
1612 {
1613 thermal_value_avg += rtldm->thermalvalue_avg[i];
1614 thermal_value_avg_count++;
1615 }
1616 }
1617
1618 if(thermal_value_avg_count) /*Calculate Average ThermalValue after average enough times*/
1619 {
1620 thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
1621 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1622 ("AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
1623 thermal_value, rtlefuse->eeprom_thermalmeter));
1624 }
1625
1626 /*5. Calculate delta, delta_LCK, delta_IQK.*/
1627 /*"delta" here is used to determine whether thermal value changes or not.*/
1628 delta = (thermal_value > rtldm->thermalvalue) ? \
1629 (thermal_value - rtldm->thermalvalue): \
1630 (rtldm->thermalvalue - thermal_value);
1631 delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? \
1632 (thermal_value - rtldm->thermalvalue_lck) : \
1633 (rtldm->thermalvalue_lck - thermal_value);
1634 delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? \
1635 (thermal_value - rtldm->thermalvalue_iqk) : \
1636 (rtldm->thermalvalue_iqk - thermal_value);
1637
1638 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1639 ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
1640 delta, delta_lck, delta_iqk));
1641
1642 /* 6. If necessary, do LCK. */
1643
1644 if (delta_lck >= IQK_THRESHOLD) /*Delta temperature is equal to or larger than 20 centigrade.*/
1645 {
1646 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1647 ("delta_LCK(%d) >= Threshold_IQK(%d)\n",
1648 delta_lck, IQK_THRESHOLD));
1649 rtldm->thermalvalue_lck = thermal_value;
1650 rtl8812ae_phy_lccalibrate(hw);
1651 }
1652
1653 /*7. If necessary, move the index of swing table to adjust Tx power.*/
1654
1655 if (delta > 0 && rtldm->txpower_track_control)
1656 {
1657 /*"delta" here is used to record the absolute value of difference.*/
1658 delta = thermal_value > rtlefuse->eeprom_thermalmeter ? \
1659 (thermal_value - rtlefuse->eeprom_thermalmeter) : \
1660 (rtlefuse->eeprom_thermalmeter - thermal_value);
1661
1662 if (delta >= TXPWR_TRACK_TABLE_SIZE)
1663 delta = TXPWR_TRACK_TABLE_SIZE - 1;
1664
1665 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
1666
1667 if(thermal_value > rtlefuse->eeprom_thermalmeter) {
1668
1669 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1670 ("delta_swing_table_idx_tup_a[%d] = %d\n",
1671 delta, delta_swing_table_idx_tup_a[delta]));
1672 rtldm->delta_power_index_last[RF90_PATH_A] = rtldm->delta_power_index[RF90_PATH_A];
1673 rtldm->delta_power_index[RF90_PATH_A] = delta_swing_table_idx_tup_a[delta];
1674
1675 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A] = delta_swing_table_idx_tup_a[delta];
1676 /*Record delta swing for mix mode power tracking*/
1677
1678 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1679 ("******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
1680 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A]));
1681
1682
1683 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1684 ("delta_swing_table_idx_tup_b[%d] = %d\n",
1685 delta, delta_swing_table_idx_tup_b[delta]));
1686 rtldm->delta_power_index_last[RF90_PATH_B] = rtldm->delta_power_index[RF90_PATH_B];
1687 rtldm->delta_power_index[RF90_PATH_B] = delta_swing_table_idx_tup_b[delta];
1688
1689 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_B] = delta_swing_table_idx_tup_b[delta];
1690 /*Record delta swing for mix mode power tracking*/
1691
1692 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1693 ("******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
1694 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_B]));
1695
1696 } else {
1697 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1698 ("delta_swing_table_idx_tdown_a[%d] = %d\n",
1699 delta, delta_swing_table_idx_tdown_a[delta]));
1700
1701 rtldm->delta_power_index_last[RF90_PATH_A] = rtldm->delta_power_index[RF90_PATH_A];
1702 rtldm->delta_power_index[RF90_PATH_A] = -1 * delta_swing_table_idx_tdown_a[delta];
1703
1704 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A] = -1 * delta_swing_table_idx_tdown_a[delta];
1705 /* Record delta swing for mix mode power tracking*/
1706 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1707 ("******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
1708 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A]));
1709
1710
1711 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1712 ("deltaSwingTableIdx_TDOWN_B[%d] = %d\n",
1713 delta, delta_swing_table_idx_tdown_b[delta]));
1714
1715 rtldm->delta_power_index_last[RF90_PATH_B] = rtldm->delta_power_index[RF90_PATH_B];
1716 rtldm->delta_power_index[RF90_PATH_B] = -1 * delta_swing_table_idx_tdown_b[delta];
1717
1718 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_B] = -1 * delta_swing_table_idx_tdown_b[delta];
1719 /*Record delta swing for mix mode power tracking*/
1720
1721 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1722 ("******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
1723 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_B]));
1724 }
1725
1726 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1727 {
1728 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1729 ("\n\n================================ [Path-%c] \
1730 Calculating PowerIndexOffset ================================\n",
1731 (p == RF90_PATH_A ? 'A' : 'B')));
1732
1733 if (rtldm->delta_power_index[p] == rtldm->delta_power_index_last[p])
1734 /*If Thermal value changes but lookup table value still the same*/
1735 rtldm->power_index_offset[p] = 0;
1736 else
1737 rtldm->power_index_offset[p] =
1738 rtldm->delta_power_index[p] - rtldm->delta_power_index_last[p];
1739 /*Power Index Diff between 2 times Power Tracking*/
1740
1741 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1742 ("[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n",
1743 (p == RF90_PATH_A ? 'A' : 'B'),
1744 rtldm->power_index_offset[p],
1745 rtldm->delta_power_index[p] ,
1746 rtldm->delta_power_index_last[p]));
1747
1748 rtldm->ofdm_index[p] =
1749 rtldm->bb_swing_idx_ofdm_base[p] + rtldm->power_index_offset[p];
1750 rtldm->cck_index =
1751 rtldm->bb_swing_idx_cck_base + rtldm->power_index_offset[p];
1752
1753 rtldm->bb_swing_idx_cck = rtldm->cck_index;
1754 rtldm->bb_swing_idx_ofdm[p] = rtldm->ofdm_index[p];
1755
1756 /*************Print BB Swing Base and Index Offset*************/
1757
1758 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1759 ("The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
1760 rtldm->bb_swing_idx_cck,
1761 rtldm->bb_swing_idx_cck_base,
1762 rtldm->power_index_offset[p]));
1763 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1764 ("The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
1765 rtldm->bb_swing_idx_ofdm[p],
1766 (p == RF90_PATH_A ? 'A' : 'B'),
1767 rtldm->bb_swing_idx_ofdm_base[p],
1768 rtldm->power_index_offset[p]));
1769
1770 /*7.1 Handle boundary conditions of index.*/
1771
1772
1773 if(rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE -1)
1774 {
1775 rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE -1;
1776 }
1777 else if (rtldm->ofdm_index[p] < ofdm_min_index)
1778 {
1779 rtldm->ofdm_index[p] = ofdm_min_index;
1780 }
1781 }
1782 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1783 ("\n\n======================================================\
1784 ==================================================\n"));
1785 if(rtldm->cck_index > TXSCALE_TABLE_SIZE -1)
1786 rtldm->cck_index = TXSCALE_TABLE_SIZE -1;
1787 else if (rtldm->cck_index < 0)
1788 rtldm->cck_index = 0;
1789 } else {
1790 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1791 ("The thermal meter is unchanged or TxPowerTracking OFF(%d): \
1792 ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
1793 rtldm->txpower_track_control,
1794 thermal_value,
1795 rtldm->thermalvalue));
1796
1797 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1798 rtldm->power_index_offset[p] = 0;
1799 }
1800 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1801 ("TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
1802 rtldm->cck_index, rtldm->bb_swing_idx_cck_base)); /*Print Swing base & current*/
1803 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1804 {
1805 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1806 ("TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n",
1807 rtldm->ofdm_index[p],
1808 (p == RF90_PATH_A ? 'A' : 'B'),
1809 rtldm->bb_swing_idx_ofdm_base[p]));
1810 }
1811
1812 if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
1813 rtldm->power_index_offset[RF90_PATH_B] != 0 ) &&
1814 rtldm->txpower_track_control)
1815 {
1816 /*7.2 Configure the Swing Table to adjust Tx Power.*/
1817 /*Always TRUE after Tx Power is adjusted by power tracking.*/
1818 /*
1819 2012/04/23 MH According to Luke's suggestion, we can not write BB digital
1820 to increase TX power. Otherwise, EVM will be bad.
1821
1822 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E.
1823 */
1824 if (thermal_value > rtldm->thermalvalue)
1825 {
1826 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1827 ("Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1828 rtldm->power_index_offset[RF90_PATH_A],
1829 delta, thermal_value,
1830 rtlefuse->eeprom_thermalmeter,
1831 rtldm->thermalvalue));
1832
1833 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1834 ("Temperature Increasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1835 rtldm->power_index_offset[RF90_PATH_B],
1836 delta, thermal_value,
1837 rtlefuse->eeprom_thermalmeter,
1838 rtldm->thermalvalue));
1839
1840 } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
1841 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1842 ("Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1843 rtldm->power_index_offset[RF90_PATH_A],
1844 delta, thermal_value,
1845 rtlefuse->eeprom_thermalmeter,
1846 rtldm->thermalvalue));
1847
1848 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1849 ("Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1850 rtldm->power_index_offset[RF90_PATH_B],
1851 delta, thermal_value,
1852 rtlefuse->eeprom_thermalmeter,
1853 rtldm->thermalvalue));
1854 }
1855
1856 if (thermal_value > rtlefuse->eeprom_thermalmeter) {
1857 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1858 ("Temperature(%d) higher than PG value(%d)\n",
1859 thermal_value, rtlefuse->eeprom_thermalmeter));
1860
1861
1862 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1863 ("**********Enter POWER Tracking MIX_MODE**********\n"));
1864 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1865 rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, 0);
1866
1867 } else {
1868 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1869 ("Temperature(%d) lower than PG value(%d)\n",
1870 thermal_value, rtlefuse->eeprom_thermalmeter));
1871
1872
1873 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1874 ("**********Enter POWER Tracking MIX_MODE**********\n"));
1875 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1876 rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, index_for_channel);
1877
1878 }
1879
1880 rtldm->bb_swing_idx_cck_base = rtldm->bb_swing_idx_cck; /*Record last time Power Tracking result as base.*/
1881 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1882 rtldm->bb_swing_idx_ofdm_base[p] = rtldm->bb_swing_idx_ofdm[p];
1883
1884 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1885 ("pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
1886 rtldm->thermalvalue, thermal_value));
1887
1888 rtldm->thermalvalue = thermal_value; /*Record last Power Tracking Thermal Value*/
1889
1890 }
1891 /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
1892 if ((delta_iqk >= IQK_THRESHOLD)) {
1893
1894 if ( !rtlphy->b_iqk_in_progress) {
1895
1896 spin_lock(&rtlpriv->locks.iqk_lock);
1897 rtlphy->b_iqk_in_progress = true;
1898 spin_unlock(&rtlpriv->locks.iqk_lock);
1899
1900 rtl8812ae_do_iqk(hw, delta_iqk, thermal_value, 8);
1901
1902 spin_lock(&rtlpriv->locks.iqk_lock);
1903 rtlphy->b_iqk_in_progress = false;
1904 spin_unlock(&rtlpriv->locks.iqk_lock);
1905 }
1906 }
1907
1908 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
1909 ("<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n"));
1910 }
1911
1912
1913 void rtl8821ae_get_delta_swing_table(
1914 struct ieee80211_hw *hw,
1915 u8 **temperature_up_a,
1916 u8 **temperature_down_a,
1917 u8 **temperature_up_b,
1918 u8 **temperature_down_b
1919 )
1920 {
1921 struct rtl_priv *rtlpriv = rtl_priv(hw);
1922 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1923 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1924 u8 channel = rtlphy->current_channel;
1925 u8 rate = rtldm->tx_rate;
1926
1927
1928 if ( 1 <= channel && channel <= 14) {
1929 if (RX_HAL_IS_CCK_RATE(rate)) {
1930 *temperature_up_a = rtldm->delta_swing_table_idx_24gccka_p;
1931 *temperature_down_a = rtldm->delta_swing_table_idx_24gccka_n;
1932 *temperature_up_b = rtldm->delta_swing_table_idx_24gcckb_p;
1933 *temperature_down_b = rtldm->delta_swing_table_idx_24gcckb_n;
1934 } else {
1935 *temperature_up_a = rtldm->delta_swing_table_idx_24ga_p;
1936 *temperature_down_a = rtldm->delta_swing_table_idx_24ga_n;
1937 *temperature_up_b = rtldm->delta_swing_table_idx_24gb_p;
1938 *temperature_down_b = rtldm->delta_swing_table_idx_24gb_n;
1939 }
1940 } else if ( 36 <= channel && channel <= 64) {
1941 *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[0];
1942 *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[0];
1943 *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[0];
1944 *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[0];
1945 } else if ( 100 <= channel && channel <= 140) {
1946 *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[1];
1947 *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[1];
1948 *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[1];
1949 *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[1];
1950 } else if ( 149 <= channel && channel <= 173) {
1951 *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[2];
1952 *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[2];
1953 *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[2];
1954 *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[2];
1955 } else {
1956 *temperature_up_a = (u8*)rtl8818e_delta_swing_table_idx_24gb_p_txpwrtrack;
1957 *temperature_down_a =(u8*)rtl8818e_delta_swing_table_idx_24gb_n_txpwrtrack;
1958 *temperature_up_b = (u8*)rtl8818e_delta_swing_table_idx_24gb_p_txpwrtrack;
1959 *temperature_down_b = (u8*)rtl8818e_delta_swing_table_idx_24gb_n_txpwrtrack;
1960 }
1961
1962 return;
1963 }
1964
1965 void rtl8821ae_phy_lccalibrate(
1966 struct ieee80211_hw *hw)
1967 {
1968 struct rtl_priv *rtlpriv = rtl_priv(hw);
1969
1970 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("===> rtl8812ae_phy_lccalibrate\n"));
1971
1972 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("<=== rtl8812ae_phy_lccalibrate\n"));
1973
1974 }
1975
1976 /*-----------------------------------------------------------------------------
1977 * Function: odm_TxPwrTrackSetPwr88E()
1978 *
1979 * Overview: 88E change all channel tx power according to flag.
1980 * OFDM & CCK are all different.
1981 *
1982 * Input: NONE
1983 *
1984 * Output: NONE
1985 *
1986 * Return: NONE
1987 *
1988 * Revised History:
1989 * When Who Remark
1990 * 04/23/2012 MHC Create Version 0.
1991 *
1992 *---------------------------------------------------------------------------*/
1993 void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
1994 enum pwr_track_control_method method, u8 rf_path, u8 channel_mapped_index)
1995 {
1996 struct rtl_priv *rtlpriv = rtl_priv(hw);
1997 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1998 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1999 u32 final_bb_swing_idx[1];
2000 u8 pwr_tracking_limit = 26; /*+1.0dB*/
2001 u8 tx_rate = 0xFF;
2002 s8 final_ofdm_swing_index = 0;
2003
2004 if(rtldm->tx_rate != 0xFF)
2005 tx_rate = rtl8812ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
2006
2007
2008 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2009 ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
2010
2011 if(tx_rate != 0xFF) { /*20130429 Mimic Modify High Rate BBSwing Limit.*/
2012 /*CCK*/
2013 if((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
2014 pwr_tracking_limit = 32; /*+4dB*/
2015 /*OFDM*/
2016 else if((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
2017 pwr_tracking_limit = 30; /*+3dB*/
2018 else if(tx_rate == MGN_54M)
2019 pwr_tracking_limit = 28; /*+2dB*/
2020 /*HT*/
2021 else if((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) /*QPSK/BPSK*/
2022 pwr_tracking_limit = 34; /*+5dB*/
2023 else if((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) /*16QAM*/
2024 pwr_tracking_limit = 30; /*+3dB*/
2025 else if((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) /*64QAM*/
2026 pwr_tracking_limit = 28; /*+2dB*/
2027 #if 0
2028 else if((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10)) /*QPSK/BPSK*/
2029 pwr_tracking_limit = 34; /*+5dB*/
2030 else if((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12)) /*16QAM*/
2031 pwr_tracking_limit = 30; /*+3dB*/
2032 else if((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15)) /*64QAM*/
2033 pwr_tracking_limit = 28; /*+2dB*/
2034 #endif
2035 /*2 VHT*/
2036 else if((tx_rate >= MGN_VHT1SS_MCS0) && (tx_rate <= MGN_VHT1SS_MCS2)) /*QPSK/BPSK*/
2037 pwr_tracking_limit = 34; /*+5dB*/
2038 else if((tx_rate >= MGN_VHT1SS_MCS3) && (tx_rate <= MGN_VHT1SS_MCS4)) /*16QAM*/
2039 pwr_tracking_limit = 30; /*+3dB*/
2040 else if((tx_rate >= MGN_VHT1SS_MCS5)&&(tx_rate <= MGN_VHT1SS_MCS6)) /*64QAM*/
2041 pwr_tracking_limit = 28; /*+2dB*/
2042 else if(tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
2043 pwr_tracking_limit = 26; /*+1dB*/
2044 else if(tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
2045 pwr_tracking_limit = 24; /*+0dB*/
2046 else if(tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
2047 pwr_tracking_limit = 22; /*-1dB*/
2048 else
2049 pwr_tracking_limit = 24;
2050 }
2051 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2052 ("TxRate=0x%x, PwrTrackingLimit=%d\n", tx_rate, pwr_tracking_limit));
2053
2054
2055 if (method == BBSWING) {
2056 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2057 ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
2058
2059 if (rf_path == RF90_PATH_A) {
2060 final_bb_swing_idx[RF90_PATH_A] =
2061 (rtldm->ofdm_index[RF90_PATH_A] > pwr_tracking_limit) ?
2062 pwr_tracking_limit : rtldm->ofdm_index[RF90_PATH_A];
2063 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2064 ("pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d, \
2065 pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
2066 rtldm->ofdm_index[RF90_PATH_A], final_bb_swing_idx[RF90_PATH_A]));
2067
2068 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_bb_swing_idx[RF90_PATH_A]]);
2069 }
2070 } else if (method == MIX_MODE) {
2071 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2072 ("pDM_Odm->DefaultOfdmIndex=%d, \
2073 pDM_Odm->Aboslute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
2074 rtldm->default_ofdm_index, rtldm->aboslute_ofdm_swing_idx[rf_path],
2075 rf_path ));
2076
2077
2078 final_ofdm_swing_index = rtldm->default_ofdm_index + rtldm->aboslute_ofdm_swing_idx[rf_path];
2079
2080 if (rf_path == RF90_PATH_A) {
2081 if(final_ofdm_swing_index > pwr_tracking_limit) { /*BBSwing higher then Limit*/
2082
2083 rtldm->remnant_cck_idx = final_ofdm_swing_index - pwr_tracking_limit;
2084 /* CCK Follow the same compensate value as Path A*/
2085 rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index - pwr_tracking_limit;
2086
2087 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[pwr_tracking_limit]);
2088
2089 rtldm->modify_txagc_flag_path_a = true;
2090
2091 /*Set TxAGC Page C{};*/
2092 rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
2093
2094 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2095 ("******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d \n",
2096 pwr_tracking_limit, rtldm->remnant_ofdm_swing_idx[rf_path]));
2097 } else if (final_ofdm_swing_index < 0) {
2098 rtldm->remnant_cck_idx = final_ofdm_swing_index;
2099 /* CCK Follow the same compensate value as Path A*/
2100 rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index;
2101
2102 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[0]);
2103
2104 rtldm->modify_txagc_flag_path_a = true;
2105
2106 /*Set TxAGC Page C{};*/
2107 rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
2108
2109 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2110 ("******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d \n",
2111 rtldm->remnant_ofdm_swing_idx[rf_path]));
2112 } else {
2113 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_ofdm_swing_index]);
2114
2115 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2116 ("******Path_A Compensate with BBSwing , Final_OFDM_Swing_Index = %d \n",
2117 final_ofdm_swing_index));
2118
2119 if(rtldm->modify_txagc_flag_path_a) { /*If TxAGC has changed, reset TxAGC again*/
2120 rtldm->remnant_cck_idx = 0;
2121 rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
2122
2123 /*Set TxAGC Page C{};*/
2124 rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
2125
2126 rtldm->modify_txagc_flag_path_a = false;
2127
2128 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2129 ("******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE \n"));
2130 }
2131 }
2132 }
2133
2134 } else {
2135 return;
2136 }
2137 }
2138
2139
2140 void rtl8821ae_dm_txpower_tracking_callback_thermalmeter
2141 (struct ieee80211_hw *hw)
2142 {
2143 struct rtl_priv *rtlpriv = rtl_priv(hw);
2144 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2145 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2146 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2147 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2148
2149 u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
2150 u8 thermal_value_avg_count = 0;
2151 u32 thermal_value_avg = 0;
2152
2153 u8 ofdm_min_index = 6; /*OFDM BB Swing should be less than +3.0dB, which is required by Arthur*/
2154 u8 index_for_channel = 0; /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
2155
2156 /* 1. The following TWO tables decide the final index of OFDM/CCK swing table.*/
2157 u8 *delta_swing_table_idx_tup_a;
2158 u8 *delta_swing_table_idx_tdown_a;
2159 u8 *delta_swing_table_idx_tup_b;
2160 u8 *delta_swing_table_idx_tdown_b;
2161
2162 /*2. Initialization ( 7 steps in total )*/
2163 rtl8821ae_get_delta_swing_table(hw, (u8**)&delta_swing_table_idx_tup_a,
2164 (u8**)&delta_swing_table_idx_tdown_a,
2165 (u8**)&delta_swing_table_idx_tup_b,
2166 (u8**)&delta_swing_table_idx_tdown_b);
2167
2168 rtldm->btxpower_trackinginit = true;
2169
2170 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2171 ("===>rtl8812ae_dm_txpower_tracking_callback_thermalmeter, \
2172 \n pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:\
2173 %d, pDM_Odm->DefaultOfdmIndex: %d\n",
2174 rtldm->bb_swing_idx_cck_base,
2175 rtldm->bb_swing_idx_ofdm_base[RF90_PATH_A],
2176 rtldm->default_ofdm_index));
2177
2178 thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER_8812A, 0xfc00); /*0x42: RF Reg[15:10] 88E*/
2179 if( ! rtldm->txpower_track_control || rtlefuse->eeprom_thermalmeter == 0 ||
2180 rtlefuse->eeprom_thermalmeter == 0xFF)
2181 return;
2182
2183
2184 /* 3. Initialize ThermalValues of RFCalibrateInfo*/
2185
2186 if(rtlhal->reloadtxpowerindex)
2187 {
2188 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2189 ("reload ofdm index for band switch\n"));
2190 }
2191
2192 /*4. Calculate average thermal meter*/
2193 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
2194 rtldm->thermalvalue_avg_index++;
2195 if(rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
2196 /*Average times = c.AverageThermalNum*/
2197 rtldm->thermalvalue_avg_index = 0;
2198
2199 for(i = 0; i < AVG_THERMAL_NUM_8812A; i++)
2200 {
2201 if(rtldm->thermalvalue_avg[i])
2202 {
2203 thermal_value_avg += rtldm->thermalvalue_avg[i];
2204 thermal_value_avg_count++;
2205 }
2206 }
2207
2208 if(thermal_value_avg_count) /*Calculate Average ThermalValue after average enough times*/
2209 {
2210 thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
2211 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2212 ("AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
2213 thermal_value, rtlefuse->eeprom_thermalmeter));
2214 }
2215
2216 /*5. Calculate delta, delta_LCK, delta_IQK.*/
2217 /*"delta" here is used to determine whether thermal value changes or not.*/
2218 delta = (thermal_value > rtldm->thermalvalue) ? \
2219 (thermal_value - rtldm->thermalvalue): \
2220 (rtldm->thermalvalue - thermal_value);
2221 delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? \
2222 (thermal_value - rtldm->thermalvalue_lck) : \
2223 (rtldm->thermalvalue_lck - thermal_value);
2224 delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? \
2225 (thermal_value - rtldm->thermalvalue_iqk) : \
2226 (rtldm->thermalvalue_iqk - thermal_value);
2227
2228 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2229 ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
2230 delta, delta_lck, delta_iqk));
2231
2232 /* 6. If necessary, do LCK. */
2233
2234 if (delta_lck >= IQK_THRESHOLD) /*Delta temperature is equal to or larger than 20 centigrade.*/
2235 {
2236 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2237 ("delta_LCK(%d) >= Threshold_IQK(%d)\n",
2238 delta_lck, IQK_THRESHOLD));
2239 rtldm->thermalvalue_lck = thermal_value;
2240 rtl8821ae_phy_lccalibrate(hw);
2241 }
2242
2243 /*7. If necessary, move the index of swing table to adjust Tx power.*/
2244
2245 if (delta > 0 && rtldm->txpower_track_control)
2246 {
2247 /*"delta" here is used to record the absolute value of difference.*/
2248 delta = thermal_value > rtlefuse->eeprom_thermalmeter ? \
2249 (thermal_value - rtlefuse->eeprom_thermalmeter) : \
2250 (rtlefuse->eeprom_thermalmeter - thermal_value);
2251
2252 if (delta >= TXSCALE_TABLE_SIZE)
2253 delta = TXSCALE_TABLE_SIZE - 1;
2254
2255 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
2256
2257 if(thermal_value > rtlefuse->eeprom_thermalmeter) {
2258
2259 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2260 ("delta_swing_table_idx_tup_a[%d] = %d\n",
2261 delta, delta_swing_table_idx_tup_a[delta]));
2262 rtldm->delta_power_index_last[RF90_PATH_A] = rtldm->delta_power_index[RF90_PATH_A];
2263 rtldm->delta_power_index[RF90_PATH_A] = delta_swing_table_idx_tup_a[delta];
2264
2265 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A] = delta_swing_table_idx_tup_a[delta];
2266 /*Record delta swing for mix mode power tracking*/
2267
2268 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2269 ("******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
2270 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A]));
2271
2272 } else {
2273 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2274 ("delta_swing_table_idx_tdown_a[%d] = %d\n",
2275 delta, delta_swing_table_idx_tdown_a[delta]));
2276
2277 rtldm->delta_power_index_last[RF90_PATH_A] = rtldm->delta_power_index[RF90_PATH_A];
2278 rtldm->delta_power_index[RF90_PATH_A] = -1 * delta_swing_table_idx_tdown_a[delta];
2279
2280 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A] = -1 * delta_swing_table_idx_tdown_a[delta];
2281 /* Record delta swing for mix mode power tracking*/
2282 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2283 ("******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
2284 rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A]));
2285 }
2286
2287 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2288 {
2289 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2290 ("\n\n================================ [Path-%c] \
2291 Calculating PowerIndexOffset ================================\n",
2292 (p == RF90_PATH_A ? 'A' : 'B')));
2293
2294 if (rtldm->delta_power_index[p] == rtldm->delta_power_index_last[p])
2295 /*If Thermal value changes but lookup table value still the same*/
2296 rtldm->power_index_offset[p] = 0;
2297 else
2298 rtldm->power_index_offset[p] =
2299 rtldm->delta_power_index[p] - rtldm->delta_power_index_last[p];
2300 /*Power Index Diff between 2 times Power Tracking*/
2301
2302 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2303 ("[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n",
2304 (p == RF90_PATH_A ? 'A' : 'B'),
2305 rtldm->power_index_offset[p],
2306 rtldm->delta_power_index[p] ,
2307 rtldm->delta_power_index_last[p]));
2308
2309 rtldm->ofdm_index[p] =
2310 rtldm->bb_swing_idx_ofdm_base[p] + rtldm->power_index_offset[p];
2311 rtldm->cck_index =
2312 rtldm->bb_swing_idx_cck_base + rtldm->power_index_offset[p];
2313
2314 rtldm->bb_swing_idx_cck = rtldm->cck_index;
2315 rtldm->bb_swing_idx_ofdm[p] = rtldm->ofdm_index[p];
2316
2317 /*************Print BB Swing Base and Index Offset*************/
2318
2319 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2320 ("The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
2321 rtldm->bb_swing_idx_cck,
2322 rtldm->bb_swing_idx_cck_base,
2323 rtldm->power_index_offset[p]));
2324 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2325 ("The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
2326 rtldm->bb_swing_idx_ofdm[p],
2327 (p == RF90_PATH_A ? 'A' : 'B'),
2328 rtldm->bb_swing_idx_ofdm_base[p],
2329 rtldm->power_index_offset[p]));
2330
2331 /*7.1 Handle boundary conditions of index.*/
2332
2333
2334 if(rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE -1)
2335 {
2336 rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE -1;
2337 }
2338 else if (rtldm->ofdm_index[p] < ofdm_min_index)
2339 {
2340 rtldm->ofdm_index[p] = ofdm_min_index;
2341 }
2342 }
2343 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2344 ("\n\n======================================================\
2345 ==================================================\n"));
2346 if(rtldm->cck_index > TXSCALE_TABLE_SIZE -1)
2347 rtldm->cck_index = TXSCALE_TABLE_SIZE -1;
2348 else if (rtldm->cck_index < 0)
2349 rtldm->cck_index = 0;
2350 } else {
2351 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2352 ("The thermal meter is unchanged or TxPowerTracking OFF(%d): \
2353 ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
2354 rtldm->txpower_track_control,
2355 thermal_value,
2356 rtldm->thermalvalue));
2357
2358 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2359 rtldm->power_index_offset[p] = 0;
2360 }
2361 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2362 ("TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
2363 rtldm->cck_index, rtldm->bb_swing_idx_cck_base)); /*Print Swing base & current*/
2364 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2365 {
2366 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2367 ("TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n",
2368 rtldm->ofdm_index[p],
2369 (p == RF90_PATH_A ? 'A' : 'B'),
2370 rtldm->bb_swing_idx_ofdm_base[p]));
2371 }
2372
2373 if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
2374 rtldm->power_index_offset[RF90_PATH_B] != 0 ) &&
2375 rtldm->txpower_track_control)
2376 {
2377 /*7.2 Configure the Swing Table to adjust Tx Power.*/
2378 /*Always TRUE after Tx Power is adjusted by power tracking.*/
2379 /*
2380 2012/04/23 MH According to Luke's suggestion, we can not write BB digital
2381 to increase TX power. Otherwise, EVM will be bad.
2382
2383 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E.
2384 */
2385 if (thermal_value > rtldm->thermalvalue)
2386 {
2387 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2388 ("Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
2389 rtldm->power_index_offset[RF90_PATH_A],
2390 delta, thermal_value,
2391 rtlefuse->eeprom_thermalmeter,
2392 rtldm->thermalvalue));
2393 } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
2394 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2395 ("Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
2396 rtldm->power_index_offset[RF90_PATH_A],
2397 delta, thermal_value,
2398 rtlefuse->eeprom_thermalmeter,
2399 rtldm->thermalvalue));
2400 }
2401
2402 if (thermal_value > rtlefuse->eeprom_thermalmeter) {
2403 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2404 ("Temperature(%d) higher than PG value(%d)\n",
2405 thermal_value, rtlefuse->eeprom_thermalmeter));
2406
2407
2408 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2409 ("**********Enter POWER Tracking MIX_MODE**********\n"));
2410 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2411 rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, index_for_channel);
2412
2413 } else {
2414 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2415 ("Temperature(%d) lower than PG value(%d)\n",
2416 thermal_value, rtlefuse->eeprom_thermalmeter));
2417
2418
2419 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2420 ("**********Enter POWER Tracking MIX_MODE**********\n"));
2421 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2422 rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, index_for_channel);
2423
2424 }
2425
2426 rtldm->bb_swing_idx_cck_base = rtldm->bb_swing_idx_cck; /*Record last time Power Tracking result as base.*/
2427 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2428 rtldm->bb_swing_idx_ofdm_base[p] = rtldm->bb_swing_idx_ofdm[p];
2429
2430 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2431 ("pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
2432 rtldm->thermalvalue, thermal_value));
2433
2434 rtldm->thermalvalue = thermal_value; /*Record last Power Tracking Thermal Value*/
2435
2436 }
2437 /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
2438 if ((delta_iqk >= IQK_THRESHOLD)) {
2439
2440 if ( !rtlphy->b_iqk_in_progress) {
2441
2442 spin_lock(&rtlpriv->locks.iqk_lock);
2443 rtlphy->b_iqk_in_progress = true;
2444 spin_unlock(&rtlpriv->locks.iqk_lock);
2445
2446 rtl8821ae_do_iqk(hw, delta_iqk, thermal_value, 8);
2447
2448 spin_lock(&rtlpriv->locks.iqk_lock);
2449 rtlphy->b_iqk_in_progress = false;
2450 spin_unlock(&rtlpriv->locks.iqk_lock);
2451 }
2452 }
2453
2454 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2455 ("<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n"));
2456 }
2457
2458
2459 void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw)
2460 {
2461 struct rtl_priv *rtlpriv = rtl_priv(hw);
2462 static u8 tm_trigger = 0;
2463
2464 //if (!rtlpriv->dm.btxpower_tracking)
2465 // return;
2466
2467 if (!tm_trigger) {
2468 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16),
2469 0x03);
2470 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2471 ("Trigger 8821ae Thermal Meter!!\n"));
2472 tm_trigger = 1;
2473 return;
2474 } else {
2475 RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
2476 ("Schedule TxPowerTracking !!\n"));
2477
2478 rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw);
2479 tm_trigger = 0;
2480 }
2481 }
2482
2483
2484 void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
2485 {
2486 struct rtl_priv *rtlpriv = rtl_priv(hw);
2487 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2488 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2489 struct rate_adaptive *p_ra = &(rtlpriv->ra);
2490 u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra;
2491 u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
2492 u8 go_up_gap = 5;
2493 struct ieee80211_sta *sta = NULL;
2494
2495 if (is_hal_stop(rtlhal)) {
2496 RT_TRACE(COMP_RATE, DBG_LOUD,
2497 ("driver is going to unload\n"));
2498 return;
2499 }
2500
2501 if (!rtlpriv->dm.b_useramask) {
2502 RT_TRACE(COMP_RATE, DBG_LOUD,
2503 ("driver does not control rate adaptive mask\n"));
2504 return;
2505 }
2506
2507 if (mac->link_state == MAC80211_LINKED &&
2508 mac->opmode == NL80211_IFTYPE_STATION) {
2509
2510 switch (p_ra->pre_ratr_state) {
2511 case DM_RATR_STA_MIDDLE:
2512 high_rssithresh_for_ra += go_up_gap;
2513 break;
2514 case DM_RATR_STA_LOW:
2515 high_rssithresh_for_ra += go_up_gap;
2516 low_rssithresh_for_ra += go_up_gap;
2517 break;
2518 default:
2519 break;
2520 }
2521
2522 if (rtlpriv->dm.undecorated_smoothed_pwdb >
2523 (long)high_rssithresh_for_ra)
2524 p_ra->ratr_state = DM_RATR_STA_HIGH;
2525 else if (rtlpriv->dm.undecorated_smoothed_pwdb >
2526 (long)low_rssithresh_for_ra)
2527 p_ra->ratr_state = DM_RATR_STA_MIDDLE;
2528 else
2529 p_ra->ratr_state = DM_RATR_STA_LOW;
2530
2531 if (p_ra->pre_ratr_state != p_ra->ratr_state ) {
2532 RT_TRACE(COMP_RATE, DBG_LOUD,
2533 ("RSSI = %ld\n",
2534 rtlpriv->dm.undecorated_smoothed_pwdb));
2535 RT_TRACE(COMP_RATE, DBG_LOUD,
2536 ("RSSI_LEVEL = %d\n", p_ra->ratr_state));
2537 RT_TRACE(COMP_RATE, DBG_LOUD,
2538 ("PreState = %d, CurState = %d\n",
2539 p_ra->pre_ratr_state, p_ra->ratr_state));
2540
2541 rcu_read_lock();
2542 sta = rtl_find_sta(hw, mac->bssid);
2543 if (sta)
2544 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, p_ra->ratr_state);
2545 rcu_read_unlock();
2546
2547 p_ra->pre_ratr_state = p_ra->ratr_state;
2548 }
2549 }
2550 }
2551
2552 bool rtl8821ae_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
2553 {
2554 struct rtl_priv *rtlpriv = rtl_priv(hw);
2555
2556 if (rtlpriv->btcoexist.btc_ops->btc_is_disable_edca_turbo(rtlpriv))
2557 return true;
2558 if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
2559 return true;
2560
2561 return false;
2562 }
2563
2564 void rtl8821ae_dm_edca_choose_traffic_idx(
2565 struct ieee80211_hw *hw, u64 cur_tx_bytes, u64 cur_rx_bytes, bool b_bias_on_rx,
2566 bool *pb_is_cur_rdl_state)
2567 {
2568 struct rtl_priv *rtlpriv = rtl_priv(hw);
2569
2570 if(b_bias_on_rx)
2571 {
2572 if (cur_tx_bytes > (cur_rx_bytes*4)) {
2573 *pb_is_cur_rdl_state = false;
2574 RT_TRACE(COMP_TURBO, DBG_LOUD,
2575 ("Uplink Traffic\n "));
2576 } else {
2577 *pb_is_cur_rdl_state = true;
2578 RT_TRACE(COMP_TURBO, DBG_LOUD,
2579 ("Balance Traffic\n"));
2580 }
2581 } else {
2582 if (cur_rx_bytes > (cur_tx_bytes*4)) {
2583 *pb_is_cur_rdl_state = true;
2584 RT_TRACE(COMP_TURBO, DBG_LOUD,
2585 ("Downlink Traffic\n"));
2586 } else {
2587 *pb_is_cur_rdl_state = false;
2588 RT_TRACE(COMP_TURBO, DBG_LOUD,
2589 ("Balance Traffic\n"));
2590 }
2591 }
2592 return ;
2593 }
2594
2595 static void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
2596 {
2597 struct rtl_priv *rtlpriv = rtl_priv(hw);
2598 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2599 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2600
2601 /*Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.*/
2602 unsigned long cur_tx_ok_cnt = 0;
2603 unsigned long cur_rx_ok_cnt = 0;
2604 u32 edca_be_ul = 0x5ea42b;
2605 u32 edca_be_dl = 0x5ea42b;
2606 u32 edca_be = 0x5ea42b;
2607 u8 iot_peer = 0;
2608 bool *pb_is_cur_rdl_state = NULL;
2609 bool b_last_is_cur_rdl_state = false;
2610 bool b_bias_on_rx = false;
2611 bool b_edca_turbo_on = false;
2612
2613 RT_TRACE(COMP_TURBO, DBG_LOUD,
2614 ("rtl8821ae_dm_check_edca_turbo=====>"));
2615 RT_TRACE(COMP_TURBO, DBG_LOUD,
2616 ("Original BE PARAM: 0x%x\n",
2617 rtl_read_dword(rtlpriv, DM_REG_EDCA_BE_11N)));
2618
2619 /*===============================
2620 list parameter for different platform
2621 ===============================*/
2622 b_last_is_cur_rdl_state = rtlpriv->dm.bis_cur_rdlstate;
2623 pb_is_cur_rdl_state = &( rtlpriv->dm.bis_cur_rdlstate);
2624
2625 cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast - rtldm->last_tx_ok_cnt;
2626 cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast - rtldm->last_rx_ok_cnt;
2627
2628 rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
2629 rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
2630
2631 iot_peer = rtlpriv->mac80211.vendor;
2632 b_bias_on_rx = (iot_peer == PEER_RAL || iot_peer == PEER_ATH) ?
2633 true : false;
2634 b_edca_turbo_on = ((!rtlpriv->dm.bis_any_nonbepkts) &&
2635 (!rtlpriv->dm.b_disable_framebursting)) ?
2636 true : false;
2637
2638 /*if (rtl8821ae_dm_is_edca_turbo_disable(hw))
2639 goto dm_CheckEdcaTurbo_EXIT;*/
2640
2641 if ((iot_peer == PEER_CISCO) && (mac->mode == WIRELESS_MODE_N_24G))
2642 {
2643 edca_be_dl = edca_setting_dl[iot_peer];
2644 edca_be_ul = edca_setting_ul[iot_peer];
2645 }
2646
2647 RT_TRACE(COMP_TURBO, DBG_LOUD,
2648 ("bIsAnyNonBEPkts : 0x%x bDisableFrameBursting : 0x%x \n",
2649 rtlpriv->dm.bis_any_nonbepkts, rtlpriv->dm.b_disable_framebursting));
2650
2651 RT_TRACE(COMP_TURBO, DBG_LOUD,
2652 ("bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n",
2653 b_edca_turbo_on, b_bias_on_rx));
2654
2655 if (b_edca_turbo_on) {
2656 RT_TRACE(COMP_TURBO, DBG_LOUD,
2657 ("curTxOkCnt : 0x%lx \n",cur_tx_ok_cnt));
2658 RT_TRACE(COMP_TURBO, DBG_LOUD,
2659 ("curRxOkCnt : 0x%lx \n",cur_rx_ok_cnt));
2660 if(b_bias_on_rx)
2661 rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
2662 cur_rx_ok_cnt, true, pb_is_cur_rdl_state);
2663 else
2664 rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
2665 cur_rx_ok_cnt, false, pb_is_cur_rdl_state);
2666
2667 edca_be = ((*pb_is_cur_rdl_state) == true) ? edca_be_dl : edca_be_ul;
2668
2669 rtl_write_dword(rtlpriv, DM_REG_EDCA_BE_11N, edca_be);
2670
2671 RT_TRACE(COMP_TURBO, DBG_LOUD,
2672 ("EDCA Turbo on: EDCA_BE:0x%x\n", edca_be));
2673
2674 rtlpriv->dm.bcurrent_turbo_edca = true;
2675
2676 RT_TRACE(COMP_TURBO, DBG_LOUD,
2677 ("EDCA_BE_DL : 0x%x EDCA_BE_UL : 0x%x EDCA_BE : 0x%x \n",
2678 edca_be_dl, edca_be_ul, edca_be));
2679 } else {
2680 if (rtlpriv->dm.bcurrent_turbo_edca) {
2681 u8 tmp = AC0_BE;
2682 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
2683 (u8 *) (&tmp));
2684 }
2685 rtlpriv->dm.bcurrent_turbo_edca = false;
2686 }
2687
2688 /* dm_CheckEdcaTurbo_EXIT: */
2689 rtlpriv->dm.bis_any_nonbepkts = false;
2690 rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
2691 rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
2692 }
2693
2694 static void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
2695 {
2696 struct rtl_priv *rtlpriv = rtl_priv(hw);
2697 u8 cur_cck_cca_thresh;
2698
2699 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
2700 /*dm_digtable.rssi_val_min = rtl8821ae_dm_initial_gain_min_pwdb(hw);*/
2701 if (dm_digtable.rssi_val_min > 25)
2702 cur_cck_cca_thresh = 0xcd;
2703 else if ((dm_digtable.rssi_val_min <= 25) && (dm_digtable.rssi_val_min > 10))
2704 cur_cck_cca_thresh = 0x83;
2705 else {
2706 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
2707 cur_cck_cca_thresh = 0x83;
2708 else
2709 cur_cck_cca_thresh = 0x40;
2710 }
2711
2712 } else {
2713 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
2714 cur_cck_cca_thresh = 0x83;
2715 else
2716 cur_cck_cca_thresh = 0x40;
2717 }
2718
2719 if (dm_digtable.cur_cck_cca_thres != cur_cck_cca_thresh) {
2720 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
2721 }
2722
2723 dm_digtable.pre_cck_cca_thres = dm_digtable.cur_cck_cca_thres;
2724 dm_digtable.cur_cck_cca_thres = cur_cck_cca_thresh;
2725 RT_TRACE(COMP_DIG, DBG_TRACE,
2726 ("CCK cca thresh hold =%x\n", dm_digtable.cur_cck_cca_thres));
2727
2728 }
2729
2730 void rtl8821ae_dm_dynamic_edcca(struct ieee80211_hw *hw)
2731 {
2732 struct rtl_priv *rtlpriv = rtl_priv(hw);
2733 bool b_fw_current_in_ps_mode = false;
2734
2735 rtlpriv->cfg->ops->get_hw_reg(hw,HW_VAR_FW_PSMODE_STATUS, \
2736 (u8*)(&b_fw_current_in_ps_mode));
2737 if (b_fw_current_in_ps_mode)
2738 return;
2739 }
2740
2741 void rtl8812ae_dm_update_txpath(struct ieee80211_hw *hw, u8 path)
2742 {
2743 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2744 struct rtl_priv *rtlpriv = rtl_priv(hw);
2745
2746 if (rtldm->resp_tx_path != path) {
2747 RT_TRACE(COMP_DIG, DBG_LOUD, \
2748 ("Need to Update Tx Path\n"));
2749 if (path == RF90_PATH_A) {
2750 /*Tx by Reg*/
2751 rtl_set_bbreg(hw, 0x80c, 0xFFF0, 0x111);
2752 /*Resp Tx by Txinfo*/
2753 rtl_set_bbreg(hw, 0x6d8, BIT(7) | BIT(6), 1);
2754 } else {
2755 /*Tx by Reg*/
2756 rtl_set_bbreg(hw, 0x80c, 0xFFF0, 0x222);
2757 /*Resp Tx by Txinfo*/
2758 rtl_set_bbreg(hw, 0x6d8, BIT(7) |BIT(6), 2);
2759 }
2760 }
2761 rtldm->resp_tx_path = path;
2762 RT_TRACE(COMP_DIG, DBG_LOUD, \
2763 ("Path=%s\n",(path == RF90_PATH_A) ? \
2764 "RF90_PATH_A":"RF90_PATH_A"));
2765 }
2766
2767 void rtl8812ae_dm_path_diversity_init(struct ieee80211_hw *hw)
2768 {
2769 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2770
2771 //rtl_set_bbreg(hw, 0x80c , BIT(29), 1); /*Tx path from Reg*/
2772 rtl_set_bbreg(hw, 0x80c , 0xFFF0, 0x111); /*Tx by Reg*/
2773 rtl_set_bbreg(hw, 0x6d8 , BIT(7) | BIT(6), 1); /*Resp Tx by Txinfo*/
2774 rtl8812ae_dm_update_txpath(hw, RF90_PATH_A);
2775
2776 rtldm->path_sel = 1; /* TxInfo default at path-A*/
2777 }
2778
2779 void rtl812ae_dm_set_txpath_by_txinfo(struct ieee80211_hw *hw,
2780 u8 *pdesc)
2781 {
2782 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2783
2784 SET_TX_DESC_TX_ANT(pdesc, rtldm->path_sel);
2785 }
2786
2787 void rtl8812ae_dm_path_statistics(struct ieee80211_hw *hw,
2788 u32 rssi_a, u32 rssi_b)
2789 {
2790 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2791
2792 rtldm->patha_sum += rssi_a;
2793 rtldm->patha_cnt ++;
2794
2795 rtldm->pathb_sum += rssi_b;
2796 rtldm->pathb_cnt ++;
2797 }
2798
2799 void rtl8812ae_dm_path_diversity(struct ieee80211_hw *hw)
2800 {
2801 struct rtl_priv *rtlpriv = rtl_priv(hw);
2802 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2803 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2804 u32 rssi_avg_a = 0;
2805 u32 rssi_avg_b = 0;
2806 u32 local_min_rssi = 0;
2807 u32 min_rssi = 0xFF;
2808 u8 tx_resp_path=0, target_path;
2809 struct ieee80211_sta *sta = NULL;
2810
2811 sta = rtl_find_sta(hw, mac->bssid);
2812 if (sta) {
2813 /*Caculate RSSI per Path*/
2814 rssi_avg_a = (rtldm->patha_cnt != 0) ? \
2815 (rtldm->patha_sum / rtldm->patha_cnt) : 0;
2816 rssi_avg_b = (rtldm->pathb_cnt != 0) ? \
2817 (rtldm->pathb_sum / rtldm->pathb_cnt) : 0;
2818
2819 target_path = (rssi_avg_a == rssi_avg_b) ? rtldm->resp_tx_path : \
2820 ((rssi_avg_a>=rssi_avg_b) ? RF90_PATH_A : RF90_PATH_B);
2821
2822 RT_TRACE(COMP_DIG, DBG_TRACE, \
2823 ("assoc_id=%d, PathA_Sum=%d, PathA_Cnt=%d\n", \
2824 mac->assoc_id, rtldm->patha_sum, rtldm->patha_cnt));
2825 RT_TRACE(COMP_DIG, DBG_TRACE, \
2826 ("assoc_id=%d, PathB_Sum=%d, PathB_Cnt=%d\n", \
2827 mac->assoc_id, rtldm->pathb_sum, rtldm->pathb_cnt));
2828 RT_TRACE(COMP_DIG, DBG_TRACE, \
2829 ("assoc_id=%d, RssiAvgA= %d, RssiAvgB= %d\n", \
2830 mac->assoc_id, rssi_avg_a, rssi_avg_b));
2831
2832 /*Select Resp Tx Path*/
2833 local_min_rssi = (rssi_avg_a > rssi_avg_b) ? rssi_avg_b : rssi_avg_a;
2834 if(local_min_rssi < min_rssi)
2835 {
2836 min_rssi = local_min_rssi;
2837 tx_resp_path = target_path;
2838 }
2839
2840 /*Select Tx DESC*/
2841 if(target_path == RF90_PATH_A)
2842 rtldm->path_sel = 1;
2843 else
2844 rtldm->path_sel = 2;
2845
2846 RT_TRACE(COMP_DIG, DBG_TRACE, \
2847 ("Tx from TxInfo, TargetPath=%s\n", \
2848 (target_path==RF90_PATH_A) ? \
2849 "ODM_RF_PATH_A":"ODM_RF_PATH_B"));
2850 RT_TRACE(COMP_DIG, DBG_TRACE, \
2851 ("pDM_PathDiv->PathSel= %d\n", \
2852 rtldm->path_sel));
2853 }
2854 rtldm->patha_cnt = 0;
2855 rtldm->patha_sum = 0;
2856 rtldm->pathb_cnt = 0;
2857 rtldm->pathb_sum = 0;
2858 }
2859
2860 void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
2861 {
2862 struct rtl_priv *rtlpriv = rtl_priv(hw);
2863 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2864 u8 crystal_cap;
2865 u32 packet_count;
2866 int cfo_khz_a,cfo_khz_b,cfo_ave = 0, adjust_xtal = 0;
2867 int cfo_ave_diff;
2868
2869 if (rtlpriv->mac80211.link_state < MAC80211_LINKED){
2870 /*1.Enable ATC*/
2871 if (rtldm->atc_status == ATC_STATUS_OFF)
2872 {
2873 rtl_set_bbreg(hw, RFC_AREA, BIT(14), ATC_STATUS_ON);
2874 rtldm->atc_status = ATC_STATUS_ON;
2875 }
2876
2877 RT_TRACE(COMP_DIG, DBG_LOUD, \
2878 ("rtl8821ae_dm_dynamic_atc_switch(): No link!!\n"));
2879 RT_TRACE(COMP_DIG, DBG_LOUD, \
2880 ("rtl8821ae_dm_dynamic_atc_switch(): atc_status = %d\n", \
2881 rtldm->atc_status));
2882
2883 if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap)
2884 {
2885 rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
2886 crystal_cap = rtldm->crystal_cap & 0x3f;
2887 crystal_cap = crystal_cap & 0x3f;
2888 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, \
2889 0x7ff80000, (crystal_cap | (crystal_cap << 6)));
2890 }
2891 RT_TRACE(COMP_DIG, DBG_LOUD, \
2892 ("rtl8821ae_dm_dynamic_atc_switch(): crystal_cap = 0x%x\n", \
2893 rtldm->crystal_cap));
2894 }else{
2895 /*1. Calculate CFO for path-A & path-B*/
2896 cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
2897 cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
2898 packet_count = rtldm->packet_count;
2899
2900 /*2.No new packet*/
2901 if (packet_count == rtldm->packet_count_pre) {
2902 RT_TRACE(COMP_DIG, DBG_LOUD, \
2903 ("rtl8821ae_dm_dynamic_atc_switch(): packet counter doesn't change\n"));
2904 return;
2905 }
2906
2907 rtldm->packet_count_pre = packet_count;
2908 RT_TRACE(COMP_DIG, DBG_LOUD, \
2909 ("rtl8821ae_dm_dynamic_atc_switch(): packet counter = %d\n", \
2910 rtldm->packet_count));
2911
2912 /*3.Average CFO*/
2913 if (rtlpriv->phy.rf_type == RF_1T1R)
2914 cfo_ave = cfo_khz_a;
2915 else
2916 cfo_ave = (cfo_khz_a + cfo_khz_b) >> 1;
2917
2918 RT_TRACE(COMP_DIG, DBG_LOUD, \
2919 ("rtl8821ae_dm_dynamic_atc_switch():"
2920 "cfo_khz_a = %dkHz, cfo_khz_b = %dkHz, cfo_ave = %dkHz\n",
2921 cfo_khz_a, cfo_khz_b, cfo_ave));
2922
2923 /*4.Avoid abnormal large CFO*/
2924 cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave)?
2925 (rtldm->cfo_ave_pre - cfo_ave):
2926 (cfo_ave - rtldm->cfo_ave_pre);
2927
2928 if (cfo_ave_diff > 20 && rtldm->large_cfo_hit == 0){
2929 RT_TRACE(COMP_DIG, DBG_LOUD, \
2930 ("rtl8821ae_dm_dynamic_atc_switch(): first large CFO hit\n"));
2931 rtldm->large_cfo_hit = 1;
2932 return;
2933 }
2934 else
2935 rtldm->large_cfo_hit = 0;
2936
2937 rtldm->cfo_ave_pre = cfo_ave;
2938
2939 /*CFO tracking by adjusting Xtal cap.*/
2940
2941 /*1.Dynamic Xtal threshold*/
2942 if (cfo_ave >= -rtldm->cfo_threshold &&
2943 cfo_ave <= rtldm->cfo_threshold &&
2944 rtldm->is_freeze == 0){
2945 if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL){
2946 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
2947 rtldm->is_freeze = 1;
2948 }
2949 else
2950 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
2951 }
2952 RT_TRACE(COMP_DIG, DBG_LOUD, \
2953 ("rtl8821ae_dm_dynamic_atc_switch(): Dynamic threshold = %d\n", \
2954 rtldm->cfo_threshold));
2955
2956 /* 2.Calculate Xtal offset*/
2957 if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
2958 adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1;
2959 else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) && rtlpriv->dm.crystal_cap > 0)
2960 adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1;
2961 RT_TRACE(COMP_DIG, DBG_LOUD, \
2962 ("rtl8821ae_dm_dynamic_atc_switch(): "
2963 "Crystal cap = 0x%x, Crystal cap offset = %d\n",
2964 rtldm->crystal_cap, adjust_xtal));
2965
2966 /*3.Adjust Crystal Cap.*/
2967 if (adjust_xtal != 0){
2968 rtldm->is_freeze = 0;
2969 rtldm->crystal_cap += adjust_xtal;
2970
2971 if (rtldm->crystal_cap > 0x3f)
2972 rtldm->crystal_cap = 0x3f;
2973 else if (rtldm->crystal_cap < 0)
2974 rtldm->crystal_cap = 0;
2975
2976 crystal_cap = rtldm->crystal_cap & 0x3f;
2977 crystal_cap = crystal_cap & 0x3f;
2978 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, \
2979 0x7ff80000, (crystal_cap | (crystal_cap << 6)));
2980 RT_TRACE(COMP_DIG, DBG_LOUD, \
2981 ("rtl8821ae_dm_dynamic_atc_switch(): New crystal cap = 0x%x \n", \
2982 rtldm->crystal_cap));
2983 }
2984 }
2985
2986 }
2987
2988 void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw)
2989 {
2990 struct rtl_priv *rtlpriv = rtl_priv(hw);
2991 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2992 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2993 bool b_fw_current_inpsmode = false;
2994 bool b_fw_ps_awake = true;
2995
2996 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
2997 (u8 *) (&b_fw_current_inpsmode));
2998
2999 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
3000 (u8 *) (&b_fw_ps_awake));
3001
3002 if(ppsc->p2p_ps_info.p2p_ps_mode)
3003 b_fw_ps_awake = false;
3004
3005 if((ppsc->rfpwr_state == ERFON) &&
3006 ((!b_fw_current_inpsmode) && b_fw_ps_awake) &&
3007 (!ppsc->rfchange_inprogress)) {
3008 rtl8821ae_dm_common_info_self_update(hw);
3009 rtl8821ae_dm_false_alarm_counter_statistics(hw);
3010 rtl8821ae_dm_check_rssi_monitor(hw);
3011 rtl8821ae_dm_dig(hw);
3012 rtl8821ae_dm_dynamic_edcca(hw);
3013 rtl8821ae_dm_cck_packet_detection_thresh(hw);
3014 rtl8821ae_dm_refresh_rate_adaptive_mask(hw);
3015 rtl8821ae_dm_check_edca_turbo(hw);
3016 rtl8821ae_dm_dynamic_atc_switch(hw);
3017 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
3018 rtl8812ae_dm_check_txpower_tracking_thermalmeter(hw);
3019 else
3020 rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw);
3021 rtl8821ae_dm_iq_calibrate(hw);
3022 if (rtlpriv->cfg->ops->get_btc_status()){
3023 rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv);
3024 }
3025 }
3026
3027 rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
3028 }
3029
3030 void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
3031 u8 *pdesc, u32 mac_id)
3032 {
3033 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
3034 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3035 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
3036 struct fast_ant_trainning *pfat_table= &(rtldm->fat_table);
3037
3038 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8812AE)
3039 return;
3040
3041 if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
3042 (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)){
3043 SET_TX_DESC_TX_ANT(pdesc, pfat_table->antsel_a[mac_id]);
3044 }
3045 }
This page took 0.102067 seconds and 5 git commands to generate.