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