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