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