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