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