1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
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.
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
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
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
26 * Larry Finger <Larry.Finger@lwfinger.net>
28 *****************************************************************************/
39 #include "../btcoexist/rtl_btc.h"
41 struct dig_t dm_digtable
;
42 static struct ps_t dm_pstable
;
44 static const u32 rtl8812ae_txscaling_table
[TXSCALE_TABLE_SIZE
] =
85 static const u32 rtl8821ae_txscaling_table
[TXSCALE_TABLE_SIZE
] = {
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
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
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
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 */
250 0x5ea630, /* 6 CISCO */
251 0x5ea42b, /* 7 MARVELL */
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 */
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};
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};
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},
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},
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},
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},
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};
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},
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},
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},
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},
350 void rtl8812ae_dm_read_and_config_txpower_track(
351 struct ieee80211_hw
*hw
)
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"));
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
);
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
);
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);
387 void rtl8821ae_dm_read_and_config_txpower_track(
388 struct ieee80211_hw
*hw
)
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"));
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
);
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
);
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);
426 #define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _deltaThermal) \
428 for(_offset = 0; _offset < _size; _offset++)\
430 if(_deltaThermal < thermal_threshold[_direction][_offset])\
437 if(_offset >= _size)\
442 void rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw
*hw
,
443 u8 type
,u8
*pdirection
,
446 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
447 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
451 if (rtlpriv
->dm
.bb_swing_idx_ofdm
[RF90_PATH_A
] <=
452 rtlpriv
->dm
.bb_swing_idx_ofdm_base
[RF90_PATH_A
]) {
454 pwr_val
= rtldm
->bb_swing_idx_ofdm_base
[RF90_PATH_A
] - rtldm
->bb_swing_idx_ofdm
[RF90_PATH_A
];
457 pwr_val
= rtldm
->bb_swing_idx_ofdm
[RF90_PATH_A
] - rtldm
->bb_swing_idx_ofdm_base
[RF90_PATH_A
];
459 } else if (type
==1) {
460 if (rtldm
->bb_swing_idx_cck
<= rtldm
->bb_swing_idx_cck_base
) {
462 pwr_val
= rtldm
->bb_swing_idx_cck_base
- rtldm
->bb_swing_idx_cck
;
465 pwr_val
= rtldm
->bb_swing_idx_cck
- rtldm
->bb_swing_idx_cck_base
;
469 if (pwr_val
>= TXPWRTRACK_MAX_IDX
&& (*pdirection
== 1))
470 pwr_val
= TXPWRTRACK_MAX_IDX
;
472 *poutwrite_val
= pwr_val
|(pwr_val
<< 8)|(pwr_val
<< 16) | (pwr_val
<< 24);
475 void rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw
*hw
)
477 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
478 struct rtl_dm
*rtldm
= rtl_dm(rtlpriv
);
479 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtlpriv
);
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;
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
;
490 rtldm
->power_index_offset
[p
] = 0;
491 rtldm
->delta_power_index
[p
] = 0;
492 rtldm
->delta_power_index_last
[p
] = 0;
494 rtldm
->aboslute_ofdm_swing_idx
[p
] = 0; /*Initial Mix mode power tracking*/
495 rtldm
->remnant_ofdm_swing_idx
[p
] = 0;
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
;
506 u8
rtl8821ae_dm_get_swing_index(struct ieee80211_hw
*hw
)
508 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
512 bb_swing
=rtl8821ae_phy_query_bb_reg(hw
, rtlhal
->current_bandtype
, RF90_PATH_A
);
514 for (i
= 0; i
< TXSCALE_TABLE_SIZE
; ++i
)
515 if ( bb_swing
== rtl8821ae_txscaling_table
[i
])
521 void rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(
522 struct ieee80211_hw
*hw
)
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;
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
;
536 if (rtlhal
->hw_type
== HARDWARE_TYPE_RTL8812AE
)
537 rtl8812ae_dm_read_and_config_txpower_track(hw
);
539 rtl8821ae_dm_read_and_config_txpower_track(hw
);
541 default_swing_index
= rtl8821ae_dm_get_swing_index(hw
);
543 rtldm
->default_ofdm_index
= (default_swing_index
== TXSCALE_TABLE_SIZE
) ? 24 : default_swing_index
;
544 rtldm
->default_cck_index
= 24;
546 rtldm
->bb_swing_idx_cck_base
= rtldm
->default_cck_index
;
547 rtldm
->cck_index
= rtldm
->default_cck_index
;
549 for (p
= RF90_PATH_A
; p
< MAX_RF_PATH
; ++p
)
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;
559 static void rtl8821ae_dm_init_dynamic_bb_powersaving(struct ieee80211_hw
*hw
)
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;
570 static void rtl8821ae_dm_diginit(struct ieee80211_hw
*hw
)
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;
601 static void rtl8821ae_dm_init_dynamic_txpower(struct ieee80211_hw
*hw
)
603 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
605 rtlpriv
->dm
.bdynamic_txpower_enable
= false;
607 rtlpriv
->dm
.last_dtp_lvl
= TXHIGHPWRLEVEL_NORMAL
;
608 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_NORMAL
;
612 void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw
*hw
)
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;
621 void rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw
*hw
)
623 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
624 struct rate_adaptive
*p_ra
= &(rtlpriv
->ra
);
626 p_ra
->ratr_state
= DM_RATR_STA_INIT
;
627 p_ra
->pre_ratr_state
= DM_RATR_STA_INIT
;
629 rtlpriv
->dm
.dm_type
= DM_TYPE_BYDRIVER
;
630 if (rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
)
631 rtlpriv
->dm
.b_useramask
= true;
633 rtlpriv
->dm
.b_useramask
= false;
635 p_ra
->high_rssi_thresh_for_ra
= 50;
636 p_ra
->low_rssi_thresh_for_ra
= 20;
640 static void rtl8821ae_dm_init_txpower_tracking(struct ieee80211_hw
*hw
)
642 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
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;
650 rtlpriv
->dm
.ofdm_index
[0] = 30;
651 rtlpriv
->dm
.cck_index
= 20;
653 rtlpriv
->dm
.bb_swing_idx_cck_base
= rtlpriv
->dm
.cck_index
;
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;
662 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
663 (" rtlpriv->dm.btxpower_tracking = %d\n",
664 rtlpriv
->dm
.btxpower_tracking
));
668 void rtl8821ae_dm_init_dynamic_atc_switch(struct ieee80211_hw
*hw
)
670 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
672 rtlpriv
->dm
.crystal_cap
= rtlpriv
->efuse
.crystalcap
;
674 rtlpriv
->dm
.atc_status
= rtl_get_bbreg(hw
, ROFDM1_CFOTRACKING
, BIT(11));
675 rtlpriv
->dm
.cfo_threshold
= CFO_THRESHOLD_XTAL
;
679 void rtl8821ae_dm_init(struct ieee80211_hw
*hw
)
681 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
682 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
684 spin_lock(&rtlpriv
->locks
.iqk_lock
);
685 rtlphy
->b_iqk_in_progress
= false;
686 spin_unlock(&rtlpriv
->locks
.iqk_lock
);
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
);
695 rtl8821ae_dm_init_dynamic_bb_powersaving(hw
);
696 rtl8821ae_dm_init_dynamic_txpower(hw
);
697 rtl8821ae_dm_init_txpower_tracking(hw
);
699 rtl8821ae_dm_init_dynamic_atc_switch(hw
);
702 void rtl8821ae_dm_find_minimum_rssi(struct ieee80211_hw
*hw
)
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
);
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"));
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
));
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
));
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
));
737 RT_TRACE(COMP_DIG
, DBG_LOUD
, ("MinUndecoratedPWDBForDM =%d\n",
738 rtl_dm_dig
->min_undecorated_pwdb_for_dm
));
742 void rtl8812ae_dm_rssi_dump_to_register(
743 struct ieee80211_hw
*hw
746 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
748 rtl_write_byte(rtlpriv
, RA_RSSI_DUMP
, Adapter
->RxStats
.RxRSSIPercentage
[0]);
749 rtl_write_byte(rtlpriv
, RB_RSSI_DUMP
, Adapter
->RxStats
.RxRSSIPercentage
[1]);
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]);
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]));
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]);
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]);
770 static void rtl8821ae_dm_check_rssi_monitor(struct ieee80211_hw
*hw
)
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;
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
;
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);*/
791 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
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
));
799 rtlpriv
->dm
.entry_max_undecoratedsmoothed_pwdb
= 0;
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
));
807 rtlpriv
->dm
.entry_min_undecoratedsmoothed_pwdb
= 0;
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
);
816 rtl_write_byte(rtlpriv
, 0x4fe, rtlpriv
->dm
.undecorated_smoothed_pwdb
);
818 rtl8821ae_dm_find_minimum_rssi(hw
);
819 dm_digtable
.rssi_val_min
= rtlpriv
->dm
.dm_digtable
.min_undecorated_pwdb_for_dm
;
822 void rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw
*hw
, u8 current_cca
)
824 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
826 if (dm_digtable
.cur_cck_cca_thres
!= current_cca
)
827 rtl_write_byte(rtlpriv
, DM_REG_CCK_CCA_11AC
, current_cca
);
829 dm_digtable
.pre_cck_cca_thres
= dm_digtable
.cur_cck_cca_thres
;
830 dm_digtable
.cur_cck_cca_thres
= current_cca
;
833 void rtl8821ae_dm_write_dig(struct ieee80211_hw
*hw
, u8 current_igi
)
835 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
836 if(dm_digtable
.stop_dig
)
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
);
844 //dm_digtable.pre_igvalue = dm_digtable.cur_igvalue;
845 dm_digtable
.cur_igvalue
= current_igi
;
848 static void rtl8821ae_dm_dig(struct ieee80211_hw
*hw
)
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
));
855 bool first_connect
, first_disconnect
;
856 u8 dm_dig_max
, dm_dig_min
, offset
;
857 u8 current_igi
=dm_digtable
.cur_igvalue
;
860 RT_TRACE(COMP_DIG
, DBG_LOUD
,("rtl8821ae_dm_dig()==>\n"));
863 if (mac
->act_scanning
== true) {
864 RT_TRACE(COMP_DIG
, DBG_LOUD
,("rtl8821ae_dm_dig() Return: In Scan Progress \n"));
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);
875 /*1 Boundary Decision*/
880 if (rtlhal
->hw_type
!= HARDWARE_TYPE_RTL8821AE
)
881 dm_dig_min
= DM_DIG_MIN
;
885 dig_max_of_min
= DM_DIG_MAX_AP
;
887 if (mac
->link_state
>= MAC80211_LINKED
) {
888 if (rtlhal
->hw_type
!= HARDWARE_TYPE_RTL8821AE
)
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
;
898 dm_digtable
.rx_gain_range_max
= dm_digtable
.rssi_val_min
+ offset
;
900 if(rtlpriv
->dm
.b_one_entry_only
){
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
;
908 dig_dynamic_min
= dm_digtable
.rssi_val_min
- offset
;
910 RT_TRACE(COMP_DIG
, DBG_LOUD
,
911 ("rtl8821ae_dm_dig() : bOneEntryOnly=TRUE, dig_dynamic_min=0x%x\n",
913 RT_TRACE(COMP_DIG
, DBG_LOUD
,
914 ("rtl8821ae_dm_dig() : dm_digtable.rssi_val_min=%d",dm_digtable
.
917 dig_dynamic_min
= dm_dig_min
;
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"));
926 if (rtlpriv
->falsealm_cnt
.cnt_all
> 10000) {
927 RT_TRACE(COMP_DIG
, DBG_LOUD
,
928 ("rtl8821ae_dm_dig(): Abnormally false alarm case. \n"));
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;
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
;
941 dm_digtable
.rx_gain_range_min
= (dm_digtable
.forbidden_igi
+ 1);
942 dm_digtable
.recover_cnt
= 3600;
946 /*Recovery mechanism for IGI lower bound*/
947 if (dm_digtable
.recover_cnt
!= 0)
948 dm_digtable
.recover_cnt
--;
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"));
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"));
963 dm_digtable
.large_fa_hit
= 0;
967 RT_TRACE(COMP_DIG
, DBG_LOUD
,
968 ("rtl8821ae_dm_dig(): pDM_DigTable->LargeFAHit=%d\n",
969 dm_digtable
.large_fa_hit
));
971 if (rtlpriv
->dm
.dbginfo
.num_qry_beacon_pkt
< 10)
972 dm_digtable
.rx_gain_range_min
= dm_dig_min
;
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
;
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"));
982 if (dm_digtable
.rssi_val_min
<= dig_max_of_min
)
983 current_igi
= dm_digtable
.rssi_val_min
;
985 current_igi
= dig_max_of_min
;
986 RT_TRACE(COMP_DIG
, DBG_LOUD
,
987 ("rtl8821ae_dm_dig: First Connect\n"));
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;
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"));
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"));
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)
1020 RT_TRACE(COMP_DIG
, DBG_LOUD
,("rtl8821ae_dm_dig(): England DIG \n"));
1023 RT_TRACE(COMP_DIG
, DBG_LOUD
,
1024 ("rtl8821ae_dm_dig(): DIG End Adjust IGI\n"));
1025 /* Check initial gain by upper/lower bound*/
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
;
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
));
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
;
1045 static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw
*hw
)
1047 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1049 struct rtl_sta_info
*drv_priv
;
1051 rtlpriv
->dm
.b_one_entry_only
= false;
1053 if (rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_STATION
&&
1054 rtlpriv
->mac80211
.link_state
>= MAC80211_LINKED
) {
1055 rtlpriv
->dm
.b_one_entry_only
= true;
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
) {
1066 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
1069 rtlpriv
->dm
.b_one_entry_only
= true;
1074 static void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw
*hw
)
1076 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1077 struct false_alarm_statistics
*falsealm_cnt
= &(rtlpriv
->falsealm_cnt
);
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
);
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
;
1088 falsealm_cnt
->cnt_all
= falsealm_cnt
->cnt_ofdm_fail
;
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);
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
));
1105 void rtl8812ae_dm_check_txpower_tracking_thermalmeter(
1106 struct ieee80211_hw
*hw
)
1108 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1109 static u8 tm_trigger
= 0;
1111 if (!rtlpriv
->dm
.btxpower_tracking
)
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"));
1121 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1122 ("Schedule TxPowerTracking direct call!!\n"));
1123 rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw
);
1128 static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw
*hw
)
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
));
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;
1141 if(rtldm
->linked_interval
< 3)
1142 rtldm
->linked_interval
++;
1144 if(rtldm
->linked_interval
== 2)
1146 if (rtlhal
->hw_type
== HARDWARE_TYPE_RTL8812AE
)
1147 rtl8812ae_phy_iq_calibrate(hw
, false);
1149 rtl8821ae_phy_iq_calibrate(hw
, false);
1152 rtldm
->linked_interval
= 0;
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
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
;
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
;
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
;
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];
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
;
1209 void rtl8812ae_phy_lccalibrate(
1210 struct ieee80211_hw
*hw
)
1212 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1214 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
, ("===> rtl8812ae_phy_lccalibrate\n"));
1216 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
, ("<=== rtl8812ae_phy_lccalibrate\n"));
1220 void rtl8812ae_dm_update_init_rate(
1221 struct ieee80211_hw
*hw
,
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
));
1230 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1231 ("Get C2H Command! Rate=0x%x\n", rate
));
1233 rtldm
->tx_rate
= rate
;
1235 if (rtlhal
->hw_type
== HARDWARE_TYPE_RTL8821AE
){
1236 rtl8821ae_dm_txpwr_track_set_pwr(hw
, MIX_MODE
, RF90_PATH_A
, 0);
1240 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++)
1242 rtl8812ae_dm_txpwr_track_set_pwr(hw
, BBSWING
, p
, 0);
1248 u8
rtl8812ae_hw_rate_to_mrate(
1249 struct ieee80211_hw
*hw
,
1253 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1254 u8 ret_rate
= MGN_1M
;
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;
1309 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1310 ("HwRateToMRate8812(): Non supported Rate [%x]!!!\n",rate
));
1316 /*-----------------------------------------------------------------------------
1317 * Function: odm_TxPwrTrackSetPwr88E()
1319 * Overview: 88E change all channel tx power according to flag.
1320 * OFDM & CCK are all different.
1330 * 04/23/2012 MHC Create Version 0.
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
)
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*/
1342 s8 final_ofdm_swing_index
= 0;
1344 if(rtldm
->tx_rate
!= 0xFF)
1345 tx_rate
= rtl8812ae_hw_rate_to_mrate(hw
, rtldm
->tx_rate
);
1348 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1349 ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
1351 if(tx_rate
!= 0xFF) { /*20130429 Mimic Modify High Rate BBSwing Limit.*/
1353 if((tx_rate
>= MGN_1M
) && (tx_rate
<= MGN_11M
))
1354 pwr_tracking_limit
= 32; /*+4dB*/
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*/
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*/
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*/
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*/
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*/
1402 pwr_tracking_limit
= 24;
1404 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1405 ("TxRate=0x%x, PwrTrackingLimit=%d\n", tx_rate
, pwr_tracking_limit
));
1408 if (method
== BBSWING
) {
1409 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1410 ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
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
]));
1421 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[final_bb_swing_idx
[RF90_PATH_A
]]);
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
]));
1431 rtl_set_bbreg(hw
, RB_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[final_bb_swing_idx
[RF90_PATH_B
]]);
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
],
1441 final_ofdm_swing_index
= rtldm
->default_ofdm_index
+ rtldm
->aboslute_ofdm_swing_idx
[rf_path
];
1443 if (rf_path
== RF90_PATH_A
) {
1444 if(final_ofdm_swing_index
> pwr_tracking_limit
) { /*BBSwing higher then Limit*/
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
;
1450 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[pwr_tracking_limit
]);
1452 rtldm
->modify_txagc_flag_path_a
= true;
1454 /*Set TxAGC Page C{};*/
1455 rtl8821ae_phy_set_txpower_level_by_path(hw
, rtlphy
->current_channel
, RF90_PATH_A
);
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
;
1465 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[0]);
1467 rtldm
->modify_txagc_flag_path_a
= true;
1469 /*Set TxAGC Page C{};*/
1470 rtl8821ae_phy_set_txpower_level_by_path(hw
, rtlphy
->current_channel
, RF90_PATH_A
);
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
]));
1476 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[final_ofdm_swing_index
]);
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
));
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;
1486 /*Set TxAGC Page C{};*/
1487 rtl8821ae_phy_set_txpower_level_by_path(hw
, rtlphy
->current_channel
, RF90_PATH_A
);
1489 rtldm
->modify_txagc_flag_path_a
= false;
1491 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1492 ("******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE \n"));
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
;
1501 rtl_set_bbreg(hw
, RB_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[pwr_tracking_limit
]);
1503 rtldm
->modify_txagc_flag_path_b
= true;
1505 /*Set TxAGC Page E{};*/
1506 rtl8821ae_phy_set_txpower_level_by_path(hw
, rtlphy
->current_channel
, RF90_PATH_B
);
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
;
1514 rtl_set_bbreg(hw
, RB_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[0]);
1516 rtldm
->modify_txagc_flag_path_b
= true;
1518 /*Set TxAGC Page E{};*/
1519 rtl8821ae_phy_set_txpower_level_by_path(hw
, rtlphy
->current_channel
, RF90_PATH_B
);
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
] ));
1525 rtl_set_bbreg(hw
, RB_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[final_ofdm_swing_index
]);
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
));
1531 if(rtldm
->modify_txagc_flag_path_b
) { /*If TxAGC has changed, reset TxAGC again*/
1532 rtldm
->remnant_ofdm_swing_idx
[rf_path
] = 0;
1534 /*Set TxAGC Page E{};*/
1535 rtl8821ae_phy_set_txpower_level_by_path(hw
, rtlphy
->current_channel
, RF90_PATH_B
);
1537 rtldm
->modify_txagc_flag_path_b
= false;
1539 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1540 ("******Path_B dm_Odm->Modify_TxAGC_Flag = FALSE \n"));
1550 void rtl8812ae_dm_txpower_tracking_callback_thermalmeter
1551 (struct ieee80211_hw
*hw
)
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
);
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;
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)*/
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
;
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
);
1578 rtldm
->btxpower_trackinginit
= true;
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
));
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)
1594 /* 3. Initialize ThermalValues of RFCalibrateInfo*/
1596 if(rtlhal
->reloadtxpowerindex
)
1598 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1599 ("reload ofdm index for band switch\n"));
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;
1609 for(i
= 0; i
< AVG_THERMAL_NUM_8812A
; i
++)
1611 if(rtldm
->thermalvalue_avg
[i
])
1613 thermal_value_avg
+= rtldm
->thermalvalue_avg
[i
];
1614 thermal_value_avg_count
++;
1618 if(thermal_value_avg_count
) /*Calculate Average ThermalValue after average enough times*/
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
));
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
);
1638 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1639 ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
1640 delta
, delta_lck
, delta_iqk
));
1642 /* 6. If necessary, do LCK. */
1644 if (delta_lck
>= IQK_THRESHOLD
) /*Delta temperature is equal to or larger than 20 centigrade.*/
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
);
1653 /*7. If necessary, move the index of swing table to adjust Tx power.*/
1655 if (delta
> 0 && rtldm
->txpower_track_control
)
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
);
1662 if (delta
>= TXPWR_TRACK_TABLE_SIZE
)
1663 delta
= TXPWR_TRACK_TABLE_SIZE
- 1;
1665 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
1667 if(thermal_value
> rtlefuse
->eeprom_thermalmeter
) {
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
];
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*/
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
]));
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
];
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*/
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
]));
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
]));
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
];
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
]));
1711 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1712 ("deltaSwingTableIdx_TDOWN_B[%d] = %d\n",
1713 delta
, delta_swing_table_idx_tdown_b
[delta
]));
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
];
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*/
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
]));
1726 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++)
1728 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1729 ("\n\n================================ [Path-%c] \
1730 Calculating PowerIndexOffset ================================\n",
1731 (p
== RF90_PATH_A
? 'A' : 'B')));
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;
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*/
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
]));
1748 rtldm
->ofdm_index
[p
] =
1749 rtldm
->bb_swing_idx_ofdm_base
[p
] + rtldm
->power_index_offset
[p
];
1751 rtldm
->bb_swing_idx_cck_base
+ rtldm
->power_index_offset
[p
];
1753 rtldm
->bb_swing_idx_cck
= rtldm
->cck_index
;
1754 rtldm
->bb_swing_idx_ofdm
[p
] = rtldm
->ofdm_index
[p
];
1756 /*************Print BB Swing Base and Index Offset*************/
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
]));
1770 /*7.1 Handle boundary conditions of index.*/
1773 if(rtldm
->ofdm_index
[p
] > TXSCALE_TABLE_SIZE
-1)
1775 rtldm
->ofdm_index
[p
] = TXSCALE_TABLE_SIZE
-1;
1777 else if (rtldm
->ofdm_index
[p
] < ofdm_min_index
)
1779 rtldm
->ofdm_index
[p
] = ofdm_min_index
;
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;
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
,
1795 rtldm
->thermalvalue
));
1797 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++)
1798 rtldm
->power_index_offset
[p
] = 0;
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
++)
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
]));
1812 if ((rtldm
->power_index_offset
[RF90_PATH_A
] != 0 ||
1813 rtldm
->power_index_offset
[RF90_PATH_B
] != 0 ) &&
1814 rtldm
->txpower_track_control
)
1816 /*7.2 Configure the Swing Table to adjust Tx Power.*/
1817 /*Always TRUE after Tx Power is adjusted by power tracking.*/
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.
1822 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E.
1824 if (thermal_value
> rtldm
->thermalvalue
)
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
));
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
));
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
));
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
));
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
));
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);
1868 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1869 ("Temperature(%d) lower than PG value(%d)\n",
1870 thermal_value
, rtlefuse
->eeprom_thermalmeter
));
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
);
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
];
1884 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1885 ("pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
1886 rtldm
->thermalvalue
, thermal_value
));
1888 rtldm
->thermalvalue
= thermal_value
; /*Record last Power Tracking Thermal Value*/
1891 /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
1892 if ((delta_iqk
>= IQK_THRESHOLD
)) {
1894 if ( !rtlphy
->b_iqk_in_progress
) {
1896 spin_lock(&rtlpriv
->locks
.iqk_lock
);
1897 rtlphy
->b_iqk_in_progress
= true;
1898 spin_unlock(&rtlpriv
->locks
.iqk_lock
);
1900 rtl8812ae_do_iqk(hw
, delta_iqk
, thermal_value
, 8);
1902 spin_lock(&rtlpriv
->locks
.iqk_lock
);
1903 rtlphy
->b_iqk_in_progress
= false;
1904 spin_unlock(&rtlpriv
->locks
.iqk_lock
);
1908 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
1909 ("<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n"));
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
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
;
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
;
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
;
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];
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
;
1965 void rtl8821ae_phy_lccalibrate(
1966 struct ieee80211_hw
*hw
)
1968 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1970 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
, ("===> rtl8812ae_phy_lccalibrate\n"));
1972 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
, ("<=== rtl8812ae_phy_lccalibrate\n"));
1976 /*-----------------------------------------------------------------------------
1977 * Function: odm_TxPwrTrackSetPwr88E()
1979 * Overview: 88E change all channel tx power according to flag.
1980 * OFDM & CCK are all different.
1990 * 04/23/2012 MHC Create Version 0.
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
)
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*/
2002 s8 final_ofdm_swing_index
= 0;
2004 if(rtldm
->tx_rate
!= 0xFF)
2005 tx_rate
= rtl8812ae_hw_rate_to_mrate(hw
, rtldm
->tx_rate
);
2008 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2009 ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
2011 if(tx_rate
!= 0xFF) { /*20130429 Mimic Modify High Rate BBSwing Limit.*/
2013 if((tx_rate
>= MGN_1M
) && (tx_rate
<= MGN_11M
))
2014 pwr_tracking_limit
= 32; /*+4dB*/
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*/
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*/
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*/
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*/
2049 pwr_tracking_limit
= 24;
2051 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2052 ("TxRate=0x%x, PwrTrackingLimit=%d\n", tx_rate
, pwr_tracking_limit
));
2055 if (method
== BBSWING
) {
2056 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2057 ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
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
]));
2068 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[final_bb_swing_idx
[RF90_PATH_A
]]);
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
],
2078 final_ofdm_swing_index
= rtldm
->default_ofdm_index
+ rtldm
->aboslute_ofdm_swing_idx
[rf_path
];
2080 if (rf_path
== RF90_PATH_A
) {
2081 if(final_ofdm_swing_index
> pwr_tracking_limit
) { /*BBSwing higher then Limit*/
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
;
2087 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[pwr_tracking_limit
]);
2089 rtldm
->modify_txagc_flag_path_a
= true;
2091 /*Set TxAGC Page C{};*/
2092 rtl8821ae_phy_set_txpower_level_by_path(hw
, rtlphy
->current_channel
, RF90_PATH_A
);
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
;
2102 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[0]);
2104 rtldm
->modify_txagc_flag_path_a
= true;
2106 /*Set TxAGC Page C{};*/
2107 rtl8821ae_phy_set_txpower_level_by_path(hw
, rtlphy
->current_channel
, RF90_PATH_A
);
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
]));
2113 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000, rtl8812ae_txscaling_table
[final_ofdm_swing_index
]);
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
));
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;
2123 /*Set TxAGC Page C{};*/
2124 rtl8821ae_phy_set_txpower_level_by_path(hw
, rtlphy
->current_channel
, RF90_PATH_A
);
2126 rtldm
->modify_txagc_flag_path_a
= false;
2128 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2129 ("******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE \n"));
2140 void rtl8821ae_dm_txpower_tracking_callback_thermalmeter
2141 (struct ieee80211_hw
*hw
)
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
);
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;
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)*/
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
;
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
);
2168 rtldm
->btxpower_trackinginit
= true;
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
));
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)
2184 /* 3. Initialize ThermalValues of RFCalibrateInfo*/
2186 if(rtlhal
->reloadtxpowerindex
)
2188 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2189 ("reload ofdm index for band switch\n"));
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;
2199 for(i
= 0; i
< AVG_THERMAL_NUM_8812A
; i
++)
2201 if(rtldm
->thermalvalue_avg
[i
])
2203 thermal_value_avg
+= rtldm
->thermalvalue_avg
[i
];
2204 thermal_value_avg_count
++;
2208 if(thermal_value_avg_count
) /*Calculate Average ThermalValue after average enough times*/
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
));
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
);
2228 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2229 ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
2230 delta
, delta_lck
, delta_iqk
));
2232 /* 6. If necessary, do LCK. */
2234 if (delta_lck
>= IQK_THRESHOLD
) /*Delta temperature is equal to or larger than 20 centigrade.*/
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
);
2243 /*7. If necessary, move the index of swing table to adjust Tx power.*/
2245 if (delta
> 0 && rtldm
->txpower_track_control
)
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
);
2252 if (delta
>= TXSCALE_TABLE_SIZE
)
2253 delta
= TXSCALE_TABLE_SIZE
- 1;
2255 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
2257 if(thermal_value
> rtlefuse
->eeprom_thermalmeter
) {
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
];
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*/
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
]));
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
]));
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
];
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
]));
2287 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8821A
; p
++)
2289 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2290 ("\n\n================================ [Path-%c] \
2291 Calculating PowerIndexOffset ================================\n",
2292 (p
== RF90_PATH_A
? 'A' : 'B')));
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;
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*/
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
]));
2309 rtldm
->ofdm_index
[p
] =
2310 rtldm
->bb_swing_idx_ofdm_base
[p
] + rtldm
->power_index_offset
[p
];
2312 rtldm
->bb_swing_idx_cck_base
+ rtldm
->power_index_offset
[p
];
2314 rtldm
->bb_swing_idx_cck
= rtldm
->cck_index
;
2315 rtldm
->bb_swing_idx_ofdm
[p
] = rtldm
->ofdm_index
[p
];
2317 /*************Print BB Swing Base and Index Offset*************/
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
]));
2331 /*7.1 Handle boundary conditions of index.*/
2334 if(rtldm
->ofdm_index
[p
] > TXSCALE_TABLE_SIZE
-1)
2336 rtldm
->ofdm_index
[p
] = TXSCALE_TABLE_SIZE
-1;
2338 else if (rtldm
->ofdm_index
[p
] < ofdm_min_index
)
2340 rtldm
->ofdm_index
[p
] = ofdm_min_index
;
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;
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
,
2356 rtldm
->thermalvalue
));
2358 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8821A
; p
++)
2359 rtldm
->power_index_offset
[p
] = 0;
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
++)
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
]));
2373 if ((rtldm
->power_index_offset
[RF90_PATH_A
] != 0 ||
2374 rtldm
->power_index_offset
[RF90_PATH_B
] != 0 ) &&
2375 rtldm
->txpower_track_control
)
2377 /*7.2 Configure the Swing Table to adjust Tx Power.*/
2378 /*Always TRUE after Tx Power is adjusted by power tracking.*/
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.
2383 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E.
2385 if (thermal_value
> rtldm
->thermalvalue
)
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
));
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
));
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
);
2414 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2415 ("Temperature(%d) lower than PG value(%d)\n",
2416 thermal_value
, rtlefuse
->eeprom_thermalmeter
));
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
);
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
];
2430 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2431 ("pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
2432 rtldm
->thermalvalue
, thermal_value
));
2434 rtldm
->thermalvalue
= thermal_value
; /*Record last Power Tracking Thermal Value*/
2437 /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
2438 if ((delta_iqk
>= IQK_THRESHOLD
)) {
2440 if ( !rtlphy
->b_iqk_in_progress
) {
2442 spin_lock(&rtlpriv
->locks
.iqk_lock
);
2443 rtlphy
->b_iqk_in_progress
= true;
2444 spin_unlock(&rtlpriv
->locks
.iqk_lock
);
2446 rtl8821ae_do_iqk(hw
, delta_iqk
, thermal_value
, 8);
2448 spin_lock(&rtlpriv
->locks
.iqk_lock
);
2449 rtlphy
->b_iqk_in_progress
= false;
2450 spin_unlock(&rtlpriv
->locks
.iqk_lock
);
2454 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2455 ("<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n"));
2459 void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw
*hw
)
2461 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2462 static u8 tm_trigger
= 0;
2464 //if (!rtlpriv->dm.btxpower_tracking)
2468 rtl_set_rfreg(hw
, RF90_PATH_A
, RF_T_METER_88E
, BIT(17)|BIT(16),
2470 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2471 ("Trigger 8821ae Thermal Meter!!\n"));
2475 RT_TRACE(COMP_POWER_TRACKING
, DBG_LOUD
,
2476 ("Schedule TxPowerTracking !!\n"));
2478 rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw
);
2484 void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw
*hw
)
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
;
2493 struct ieee80211_sta
*sta
= NULL
;
2495 if (is_hal_stop(rtlhal
)) {
2496 RT_TRACE(COMP_RATE
, DBG_LOUD
,
2497 ("driver is going to unload\n"));
2501 if (!rtlpriv
->dm
.b_useramask
) {
2502 RT_TRACE(COMP_RATE
, DBG_LOUD
,
2503 ("driver does not control rate adaptive mask\n"));
2507 if (mac
->link_state
== MAC80211_LINKED
&&
2508 mac
->opmode
== NL80211_IFTYPE_STATION
) {
2510 switch (p_ra
->pre_ratr_state
) {
2511 case DM_RATR_STA_MIDDLE
:
2512 high_rssithresh_for_ra
+= go_up_gap
;
2514 case DM_RATR_STA_LOW
:
2515 high_rssithresh_for_ra
+= go_up_gap
;
2516 low_rssithresh_for_ra
+= go_up_gap
;
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
;
2529 p_ra
->ratr_state
= DM_RATR_STA_LOW
;
2531 if (p_ra
->pre_ratr_state
!= p_ra
->ratr_state
) {
2532 RT_TRACE(COMP_RATE
, DBG_LOUD
,
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
));
2542 sta
= rtl_find_sta(hw
, mac
->bssid
);
2544 rtlpriv
->cfg
->ops
->update_rate_tbl(hw
, sta
, p_ra
->ratr_state
);
2547 p_ra
->pre_ratr_state
= p_ra
->ratr_state
;
2552 bool rtl8821ae_dm_is_edca_turbo_disable(struct ieee80211_hw
*hw
)
2554 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2556 if (rtlpriv
->btcoexist
.btc_ops
->btc_is_disable_edca_turbo(rtlpriv
))
2558 if (rtlpriv
->mac80211
.mode
== WIRELESS_MODE_B
)
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
)
2568 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
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 "));
2577 *pb_is_cur_rdl_state
= true;
2578 RT_TRACE(COMP_TURBO
, DBG_LOUD
,
2579 ("Balance Traffic\n"));
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"));
2587 *pb_is_cur_rdl_state
= false;
2588 RT_TRACE(COMP_TURBO
, DBG_LOUD
,
2589 ("Balance Traffic\n"));
2595 static void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw
*hw
)
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
));
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;
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;
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
)));
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
);
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
;
2628 rtldm
->last_tx_ok_cnt
= rtlpriv
->stats
.txbytesunicast
;
2629 rtldm
->last_rx_ok_cnt
= rtlpriv
->stats
.rxbytesunicast
;
2631 iot_peer
= rtlpriv
->mac80211
.vendor
;
2632 b_bias_on_rx
= (iot_peer
== PEER_RAL
|| iot_peer
== PEER_ATH
) ?
2634 b_edca_turbo_on
= ((!rtlpriv
->dm
.bis_any_nonbepkts
) &&
2635 (!rtlpriv
->dm
.b_disable_framebursting
)) ?
2638 /*if (rtl8821ae_dm_is_edca_turbo_disable(hw))
2639 goto dm_CheckEdcaTurbo_EXIT;*/
2641 if ((iot_peer
== PEER_CISCO
) && (mac
->mode
== WIRELESS_MODE_N_24G
))
2643 edca_be_dl
= edca_setting_dl
[iot_peer
];
2644 edca_be_ul
= edca_setting_ul
[iot_peer
];
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
));
2651 RT_TRACE(COMP_TURBO
, DBG_LOUD
,
2652 ("bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n",
2653 b_edca_turbo_on
, b_bias_on_rx
));
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
));
2661 rtl8821ae_dm_edca_choose_traffic_idx(hw
, cur_tx_ok_cnt
,
2662 cur_rx_ok_cnt
, true, pb_is_cur_rdl_state
);
2664 rtl8821ae_dm_edca_choose_traffic_idx(hw
, cur_tx_ok_cnt
,
2665 cur_rx_ok_cnt
, false, pb_is_cur_rdl_state
);
2667 edca_be
= ((*pb_is_cur_rdl_state
) == true) ? edca_be_dl
: edca_be_ul
;
2669 rtl_write_dword(rtlpriv
, DM_REG_EDCA_BE_11N
, edca_be
);
2671 RT_TRACE(COMP_TURBO
, DBG_LOUD
,
2672 ("EDCA Turbo on: EDCA_BE:0x%x\n", edca_be
));
2674 rtlpriv
->dm
.bcurrent_turbo_edca
= true;
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
));
2680 if (rtlpriv
->dm
.bcurrent_turbo_edca
) {
2682 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_AC_PARAM
,
2685 rtlpriv
->dm
.bcurrent_turbo_edca
= false;
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
;
2694 static void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw
*hw
)
2696 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2697 u8 cur_cck_cca_thresh
;
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;
2706 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
2707 cur_cck_cca_thresh
= 0x83;
2709 cur_cck_cca_thresh
= 0x40;
2713 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
2714 cur_cck_cca_thresh
= 0x83;
2716 cur_cck_cca_thresh
= 0x40;
2719 if (dm_digtable
.cur_cck_cca_thres
!= cur_cck_cca_thresh
) {
2720 rtl_set_bbreg(hw
, RCCK0_CCA
, MASKBYTE2
, cur_cck_cca_thresh
);
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
));
2730 void rtl8821ae_dm_dynamic_edcca(struct ieee80211_hw
*hw
)
2732 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2733 bool b_fw_current_in_ps_mode
= false;
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
)
2741 void rtl8812ae_dm_update_txpath(struct ieee80211_hw
*hw
, u8 path
)
2743 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
2744 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
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
) {
2751 rtl_set_bbreg(hw
, 0x80c, 0xFFF0, 0x111);
2752 /*Resp Tx by Txinfo*/
2753 rtl_set_bbreg(hw
, 0x6d8, BIT(7) | BIT(6), 1);
2756 rtl_set_bbreg(hw
, 0x80c, 0xFFF0, 0x222);
2757 /*Resp Tx by Txinfo*/
2758 rtl_set_bbreg(hw
, 0x6d8, BIT(7) |BIT(6), 2);
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"));
2767 void rtl8812ae_dm_path_diversity_init(struct ieee80211_hw
*hw
)
2769 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
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
);
2776 rtldm
->path_sel
= 1; /* TxInfo default at path-A*/
2779 void rtl812ae_dm_set_txpath_by_txinfo(struct ieee80211_hw
*hw
,
2782 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
2784 SET_TX_DESC_TX_ANT(pdesc
, rtldm
->path_sel
);
2787 void rtl8812ae_dm_path_statistics(struct ieee80211_hw
*hw
,
2788 u32 rssi_a
, u32 rssi_b
)
2790 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
2792 rtldm
->patha_sum
+= rssi_a
;
2793 rtldm
->patha_cnt
++;
2795 rtldm
->pathb_sum
+= rssi_b
;
2796 rtldm
->pathb_cnt
++;
2799 void rtl8812ae_dm_path_diversity(struct ieee80211_hw
*hw
)
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
));
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
;
2811 sta
= rtl_find_sta(hw
, mac
->bssid
);
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;
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
);
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
));
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
)
2836 min_rssi
= local_min_rssi
;
2837 tx_resp_path
= target_path
;
2841 if(target_path
== RF90_PATH_A
)
2842 rtldm
->path_sel
= 1;
2844 rtldm
->path_sel
= 2;
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", \
2854 rtldm
->patha_cnt
= 0;
2855 rtldm
->patha_sum
= 0;
2856 rtldm
->pathb_cnt
= 0;
2857 rtldm
->pathb_sum
= 0;
2860 void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw
*hw
)
2862 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2863 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
2866 int cfo_khz_a
,cfo_khz_b
,cfo_ave
= 0, adjust_xtal
= 0;
2869 if (rtlpriv
->mac80211
.link_state
< MAC80211_LINKED
){
2871 if (rtldm
->atc_status
== ATC_STATUS_OFF
)
2873 rtl_set_bbreg(hw
, RFC_AREA
, BIT(14), ATC_STATUS_ON
);
2874 rtldm
->atc_status
= ATC_STATUS_ON
;
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
));
2883 if (rtldm
->crystal_cap
!= rtlpriv
->efuse
.crystalcap
)
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)));
2891 RT_TRACE(COMP_DIG
, DBG_LOUD
, \
2892 ("rtl8821ae_dm_dynamic_atc_switch(): crystal_cap = 0x%x\n", \
2893 rtldm
->crystal_cap
));
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
;
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"));
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
));
2913 if (rtlpriv
->phy
.rf_type
== RF_1T1R
)
2914 cfo_ave
= cfo_khz_a
;
2916 cfo_ave
= (cfo_khz_a
+ cfo_khz_b
) >> 1;
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
));
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
);
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;
2935 rtldm
->large_cfo_hit
= 0;
2937 rtldm
->cfo_ave_pre
= cfo_ave
;
2939 /*CFO tracking by adjusting Xtal cap.*/
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;
2950 rtldm
->cfo_threshold
= CFO_THRESHOLD_XTAL
;
2952 RT_TRACE(COMP_DIG
, DBG_LOUD
, \
2953 ("rtl8821ae_dm_dynamic_atc_switch(): Dynamic threshold = %d\n", \
2954 rtldm
->cfo_threshold
));
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
));
2966 /*3.Adjust Crystal Cap.*/
2967 if (adjust_xtal
!= 0){
2968 rtldm
->is_freeze
= 0;
2969 rtldm
->crystal_cap
+= adjust_xtal
;
2971 if (rtldm
->crystal_cap
> 0x3f)
2972 rtldm
->crystal_cap
= 0x3f;
2973 else if (rtldm
->crystal_cap
< 0)
2974 rtldm
->crystal_cap
= 0;
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
));
2988 void rtl8821ae_dm_watchdog(struct ieee80211_hw
*hw
)
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;
2996 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FW_PSMODE_STATUS
,
2997 (u8
*) (&b_fw_current_inpsmode
));
2999 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FWLPS_RF_ON
,
3000 (u8
*) (&b_fw_ps_awake
));
3002 if(ppsc
->p2p_ps_info
.p2p_ps_mode
)
3003 b_fw_ps_awake
= false;
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
);
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
);
3027 rtlpriv
->dm
.dbginfo
.num_qry_beacon_pkt
= 0;
3030 void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw
*hw
,
3031 u8
*pdesc
, u32 mac_id
)
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
);
3038 if (rtlhal
->hw_type
!= HARDWARE_TYPE_RTL8812AE
)
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
]);