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