1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
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.
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
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
36 #include "../btcoexist/rtl_btc.h"
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 */
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 */
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 */
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 */
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 */
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 */
243 0x5ea630, /* 6 CISCO */
244 0x5ea42b, /* 7 MARVELL */
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 */
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};
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};
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};
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};
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};
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};
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};
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};
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};
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};
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},
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},
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},
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},
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};
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};
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};
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};
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};
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};
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};
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};
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},
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},
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},
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},
402 void rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw
*hw
,
403 u8 type
, u8
*pdirection
,
406 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
407 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
411 if (rtlpriv
->dm
.swing_idx_ofdm
[RF90_PATH_A
] <=
412 rtlpriv
->dm
.swing_idx_ofdm_base
[RF90_PATH_A
]) {
414 pwr_val
= rtldm
->swing_idx_ofdm_base
[RF90_PATH_A
] -
415 rtldm
->swing_idx_ofdm
[RF90_PATH_A
];
418 pwr_val
= rtldm
->swing_idx_ofdm
[RF90_PATH_A
] -
419 rtldm
->swing_idx_ofdm_base
[RF90_PATH_A
];
421 } else if (type
== 1) {
422 if (rtldm
->swing_idx_cck
<= rtldm
->swing_idx_cck_base
) {
424 pwr_val
= rtldm
->swing_idx_cck_base
-
425 rtldm
->swing_idx_cck
;
428 pwr_val
= rtldm
->swing_idx_cck
-
429 rtldm
->swing_idx_cck_base
;
433 if (pwr_val
>= TXPWRTRACK_MAX_IDX
&& (*pdirection
== 1))
434 pwr_val
= TXPWRTRACK_MAX_IDX
;
436 *poutwrite_val
= pwr_val
| (pwr_val
<< 8)|
441 void rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw
*hw
)
443 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
444 struct rtl_dm
*rtldm
= rtl_dm(rtlpriv
);
445 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtlpriv
);
448 rtldm
->swing_idx_cck_base
= rtldm
->default_cck_index
;
449 rtldm
->swing_idx_cck
= rtldm
->default_cck_index
;
450 rtldm
->cck_index
= 0;
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
;
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;
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
;
474 static u8
rtl8821ae_dm_get_swing_index(struct ieee80211_hw
*hw
)
476 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
480 bb_swing
= phy_get_tx_swing_8812A(hw
, rtlhal
->current_bandtype
,
483 for (i
= 0; i
< TXSCALE_TABLE_SIZE
; ++i
)
484 if (bb_swing
== rtl8821ae_txscaling_table
[i
])
490 void rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(
491 struct ieee80211_hw
*hw
)
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;
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
);
505 rtldm
->default_ofdm_index
=
506 (default_swing_index
== TXSCALE_TABLE_SIZE
) ?
507 24 : default_swing_index
;
508 rtldm
->default_cck_index
= 24;
510 rtldm
->swing_idx_cck_base
= rtldm
->default_cck_index
;
511 rtldm
->cck_index
= rtldm
->default_cck_index
;
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;
523 void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw
*hw
)
525 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
527 rtlpriv
->dm
.current_turbo_edca
= false;
528 rtlpriv
->dm
.is_any_nonbepkts
= false;
529 rtlpriv
->dm
.is_cur_rdlstate
= false;
532 void rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw
*hw
)
534 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
535 struct rate_adaptive
*p_ra
= &rtlpriv
->ra
;
537 p_ra
->ratr_state
= DM_RATR_STA_INIT
;
538 p_ra
->pre_ratr_state
= DM_RATR_STA_INIT
;
540 rtlpriv
->dm
.dm_type
= DM_TYPE_BYDRIVER
;
541 if (rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
)
542 rtlpriv
->dm
.useramask
= true;
544 rtlpriv
->dm
.useramask
= false;
546 p_ra
->high_rssi_thresh_for_ra
= 50;
547 p_ra
->low_rssi_thresh_for_ra40m
= 20;
550 static void rtl8821ae_dm_init_dynamic_atc_switch(struct ieee80211_hw
*hw
)
552 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
554 rtlpriv
->dm
.crystal_cap
= rtlpriv
->efuse
.crystalcap
;
556 rtlpriv
->dm
.atc_status
= rtl_get_bbreg(hw
, ROFDM1_CFOTRACKING
, BIT(11));
557 rtlpriv
->dm
.cfo_threshold
= CFO_THRESHOLD_XTAL
;
560 static void rtl8821ae_dm_common_info_self_init(struct ieee80211_hw
*hw
)
562 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
563 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
566 rtlphy
->cck_high_power
=
567 (bool)rtl_get_bbreg(hw
, ODM_REG_CCK_RPT_FORMAT_11AC
,
568 ODM_BIT_CCK_RPT_FORMAT_11AC
);
570 tmp
= (u8
)rtl_get_bbreg(hw
, ODM_REG_BB_RX_PATH_11AC
,
571 ODM_BIT_BB_RX_PATH_11AC
);
573 rtlpriv
->dm
.rfpath_rxenable
[0] = true;
575 rtlpriv
->dm
.rfpath_rxenable
[1] = true;
578 void rtl8821ae_dm_init(struct ieee80211_hw
*hw
)
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);
584 spin_lock(&rtlpriv
->locks
.iqk_lock
);
585 rtlphy
->lck_inprogress
= false;
586 spin_unlock(&rtlpriv
->locks
.iqk_lock
);
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
);
597 static void rtl8821ae_dm_find_minimum_rssi(struct ieee80211_hw
*hw
)
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
);
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");
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
);
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
);
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
);
632 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
633 "MinUndecoratedPWDBForDM =%d\n",
634 rtl_dm_dig
->min_undec_pwdb_for_dm
);
637 static void rtl8812ae_dm_rssi_dump_to_register(struct ieee80211_hw
*hw
)
639 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
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]);
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]);
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]));
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]);
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]);
671 static void rtl8821ae_dm_check_rssi_monitor(struct ieee80211_hw
*hw
)
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;
681 u64 cur_txokcnt
= 0, cur_rxokcnt
= 0;
682 static u64 last_txokcnt
= 0, last_rxokcnt
;
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;
691 h2c_parameter
[3] = 0x00;
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
<
702 drv_priv
->rssi_stat
.undec_sm_pwdb
;
703 if (drv_priv
->rssi_stat
.undec_sm_pwdb
>
706 drv_priv
->rssi_stat
.undec_sm_pwdb
;
708 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
710 /* If associated entry is found */
711 if (tmp_entry_max_pwdb
!= 0) {
712 rtlpriv
->dm
.entry_max_undec_sm_pwdb
=
714 RTPRINT(rtlpriv
, FDM
, DM_PWDB
,
715 "EntryMaxPWDB = 0x%lx(%ld)\n",
716 tmp_entry_max_pwdb
, tmp_entry_max_pwdb
);
718 rtlpriv
->dm
.entry_max_undec_sm_pwdb
= 0;
720 /* If associated entry is found */
721 if (tmp_entry_min_pwdb
!= 0xff) {
722 rtlpriv
->dm
.entry_min_undec_sm_pwdb
=
724 RTPRINT(rtlpriv
, FDM
, DM_PWDB
,
725 "EntryMinPWDB = 0x%lx(%ld)\n",
726 tmp_entry_min_pwdb
, tmp_entry_min_pwdb
);
728 rtlpriv
->dm
.entry_min_undec_sm_pwdb
= 0;
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;
740 stbc_tx
= (mac
->ht_cur_stbc
&
741 STBC_HT_ENABLE_TX
) ? 1 : 0;
742 h2c_parameter
[3] |= stbc_tx
<< 1;
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,
752 rtl8821ae_fill_h2c_cmd(hw
, H2C_RSSI_21AE_REPORT
, 3,
755 rtl_write_byte(rtlpriv
, 0x4fe, rtlpriv
->dm
.undec_sm_pwdb
);
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
;
763 void rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw
*hw
, u8 current_cca
)
765 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
766 struct dig_t
*dm_digtable
= &rtlpriv
->dm_digtable
;
768 if (dm_digtable
->cur_cck_cca_thres
!= current_cca
)
769 rtl_write_byte(rtlpriv
, DM_REG_CCK_CCA_11AC
, current_cca
);
771 dm_digtable
->pre_cck_cca_thres
= dm_digtable
->cur_cck_cca_thres
;
772 dm_digtable
->cur_cck_cca_thres
= current_cca
;
775 void rtl8821ae_dm_write_dig(struct ieee80211_hw
*hw
, u8 current_igi
)
777 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
778 struct dig_t
*dm_digtable
= &rtlpriv
->dm_digtable
;
780 if (dm_digtable
->stop_dig
)
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
);
790 dm_digtable
->cur_igvalue
= current_igi
;
793 static void rtl8821ae_dm_dig(struct ieee80211_hw
*hw
)
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
));
801 bool first_connect
, first_disconnect
;
802 u8 dm_dig_max
, dm_dig_min
, offset
;
803 u8 current_igi
= dm_digtable
->cur_igvalue
;
805 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
, "\n");
807 if (mac
->act_scanning
) {
808 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
809 "Return: In Scan Progress\n");
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
);
820 /*1 Boundary Decision*/
824 if (rtlhal
->hw_type
!= HARDWARE_TYPE_RTL8821AE
)
825 dm_dig_min
= DM_DIG_MIN
;
829 dig_max_of_min
= DM_DIG_MAX_AP
;
831 if (mac
->link_state
>= MAC80211_LINKED
) {
832 if (rtlhal
->hw_type
!= HARDWARE_TYPE_RTL8821AE
)
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
;
842 dm_digtable
->rx_gain_max
=
843 dm_digtable
->rssi_val_min
+ offset
;
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
) {
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
;
859 dm_digtable
->rssi_val_min
- offset
;
861 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
862 "bOneEntryOnly=TRUE, dig_min_0=0x%x\n",
865 dig_min_0
= dm_dig_min
;
868 dm_digtable
->rx_gain_max
= dm_dig_max
;
869 dig_min_0
= dm_dig_min
;
870 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
874 if (rtlpriv
->falsealm_cnt
.cnt_all
> 10000) {
875 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
876 "Abnormally false alarm case.\n");
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;
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
;
891 dm_digtable
->rx_gain_min
=
892 (dm_digtable
->forbidden_igi
+ 1);
893 dm_digtable
->recover_cnt
= 3600;
896 /*Recovery mechanism for IGI lower bound*/
897 if (dm_digtable
->recover_cnt
!= 0) {
898 dm_digtable
->recover_cnt
--;
900 if (dm_digtable
->large_fa_hit
< 3) {
901 if ((dm_digtable
->forbidden_igi
- 1) <
903 dm_digtable
->forbidden_igi
=
905 dm_digtable
->rx_gain_min
=
907 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
908 "Normal Case: At Lower Bound\n");
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");
917 dm_digtable
->large_fa_hit
= 0;
921 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
922 "pDM_DigTable->LargeFAHit=%d\n",
923 dm_digtable
->large_fa_hit
);
925 if (rtlpriv
->dm
.dbginfo
.num_qry_beacon_pkt
< 10)
926 dm_digtable
->rx_gain_min
= dm_dig_min
;
928 if (dm_digtable
->rx_gain_min
> dm_digtable
->rx_gain_max
)
929 dm_digtable
->rx_gain_min
= dm_digtable
->rx_gain_max
;
931 /*Adjust initial gain by false alarm*/
932 if (mac
->link_state
>= MAC80211_LINKED
) {
933 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
936 if (dm_digtable
->rssi_val_min
<= dig_max_of_min
)
937 current_igi
= dm_digtable
->rssi_val_min
;
939 current_igi
= dig_max_of_min
;
940 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
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;
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");
958 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
960 if (first_disconnect
) {
961 current_igi
= dm_digtable
->rx_gain_min
;
962 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
963 "First DisConnect\n");
965 /* 2012.03.30 LukeLee: enable DIG before
966 * link but with very high thresholds
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;
975 if (current_igi
>= 0x3e)
978 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
, "England DIG\n");
981 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
982 "DIG End Adjust IGI\n");
983 /* Check initial gain by upper/lower bound*/
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
;
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
);
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
;
1004 static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw
*hw
)
1006 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1008 struct rtl_sta_info
*drv_priv
;
1010 rtlpriv
->dm
.tx_rate
= 0xff;
1012 rtlpriv
->dm
.one_entry_only
= false;
1014 if (rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_STATION
&&
1015 rtlpriv
->mac80211
.link_state
>= MAC80211_LINKED
) {
1016 rtlpriv
->dm
.one_entry_only
= true;
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
)
1026 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
1029 rtlpriv
->dm
.one_entry_only
= true;
1033 static void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw
*hw
)
1035 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1036 struct false_alarm_statistics
*falsealm_cnt
= &rtlpriv
->falsealm_cnt
;
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
);
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
;
1050 falsealm_cnt
->cnt_all
= falsealm_cnt
->cnt_ofdm_fail
;
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);
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
);
1067 static void rtl8812ae_dm_check_txpower_tracking_thermalmeter(
1068 struct ieee80211_hw
*hw
)
1070 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1071 static u8 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");
1081 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1082 "Schedule TxPowerTracking direct call!!\n");
1083 rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw
);
1087 static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw
*hw
)
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
));
1093 if (mac
->link_state
>= MAC80211_LINKED
) {
1094 if (rtldm
->linked_interval
< 3)
1095 rtldm
->linked_interval
++;
1097 if (rtldm
->linked_interval
== 2) {
1098 if (rtlhal
->hw_type
== HARDWARE_TYPE_RTL8812AE
)
1099 rtl8812ae_phy_iq_calibrate(hw
, false);
1101 rtl8821ae_phy_iq_calibrate(hw
, false);
1104 rtldm
->linked_interval
= 0;
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
)
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
;
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
;
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
;
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];
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
;
1153 void rtl8821ae_dm_update_init_rate(struct ieee80211_hw
*hw
, u8 rate
)
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
));
1160 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1161 "Get C2H Command! Rate=0x%x\n", rate
);
1163 rtldm
->tx_rate
= rate
;
1165 if (rtlhal
->hw_type
== HARDWARE_TYPE_RTL8821AE
) {
1166 rtl8821ae_dm_txpwr_track_set_pwr(hw
, MIX_MODE
, RF90_PATH_A
, 0);
1168 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++)
1169 rtl8812ae_dm_txpwr_track_set_pwr(hw
, MIX_MODE
, p
, 0);
1173 u8
rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw
*hw
, u8 rate
)
1175 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1176 u8 ret_rate
= MGN_1M
;
1186 ret_rate
= MGN_5_5M
;
1216 ret_rate
= MGN_MCS0
;
1219 ret_rate
= MGN_MCS1
;
1222 ret_rate
= MGN_MCS2
;
1225 ret_rate
= MGN_MCS3
;
1228 ret_rate
= MGN_MCS4
;
1231 ret_rate
= MGN_MCS5
;
1234 ret_rate
= MGN_MCS6
;
1237 ret_rate
= MGN_MCS7
;
1240 ret_rate
= MGN_MCS8
;
1243 ret_rate
= MGN_MCS9
;
1245 case DESC_RATEMCS10
:
1246 ret_rate
= MGN_MCS10
;
1248 case DESC_RATEMCS11
:
1249 ret_rate
= MGN_MCS11
;
1251 case DESC_RATEMCS12
:
1252 ret_rate
= MGN_MCS12
;
1254 case DESC_RATEMCS13
:
1255 ret_rate
= MGN_MCS13
;
1257 case DESC_RATEMCS14
:
1258 ret_rate
= MGN_MCS14
;
1260 case DESC_RATEMCS15
:
1261 ret_rate
= MGN_MCS15
;
1263 case DESC_RATEVHT1SS_MCS0
:
1264 ret_rate
= MGN_VHT1SS_MCS0
;
1266 case DESC_RATEVHT1SS_MCS1
:
1267 ret_rate
= MGN_VHT1SS_MCS1
;
1269 case DESC_RATEVHT1SS_MCS2
:
1270 ret_rate
= MGN_VHT1SS_MCS2
;
1272 case DESC_RATEVHT1SS_MCS3
:
1273 ret_rate
= MGN_VHT1SS_MCS3
;
1275 case DESC_RATEVHT1SS_MCS4
:
1276 ret_rate
= MGN_VHT1SS_MCS4
;
1278 case DESC_RATEVHT1SS_MCS5
:
1279 ret_rate
= MGN_VHT1SS_MCS5
;
1281 case DESC_RATEVHT1SS_MCS6
:
1282 ret_rate
= MGN_VHT1SS_MCS6
;
1284 case DESC_RATEVHT1SS_MCS7
:
1285 ret_rate
= MGN_VHT1SS_MCS7
;
1287 case DESC_RATEVHT1SS_MCS8
:
1288 ret_rate
= MGN_VHT1SS_MCS8
;
1290 case DESC_RATEVHT1SS_MCS9
:
1291 ret_rate
= MGN_VHT1SS_MCS9
;
1293 case DESC_RATEVHT2SS_MCS0
:
1294 ret_rate
= MGN_VHT2SS_MCS0
;
1296 case DESC_RATEVHT2SS_MCS1
:
1297 ret_rate
= MGN_VHT2SS_MCS1
;
1299 case DESC_RATEVHT2SS_MCS2
:
1300 ret_rate
= MGN_VHT2SS_MCS2
;
1302 case DESC_RATEVHT2SS_MCS3
:
1303 ret_rate
= MGN_VHT2SS_MCS3
;
1305 case DESC_RATEVHT2SS_MCS4
:
1306 ret_rate
= MGN_VHT2SS_MCS4
;
1308 case DESC_RATEVHT2SS_MCS5
:
1309 ret_rate
= MGN_VHT2SS_MCS5
;
1311 case DESC_RATEVHT2SS_MCS6
:
1312 ret_rate
= MGN_VHT2SS_MCS6
;
1314 case DESC_RATEVHT2SS_MCS7
:
1315 ret_rate
= MGN_VHT2SS_MCS7
;
1317 case DESC_RATEVHT2SS_MCS8
:
1318 ret_rate
= MGN_VHT2SS_MCS8
;
1320 case DESC_RATEVHT2SS_MCS9
:
1321 ret_rate
= MGN_VHT2SS_MCS9
;
1324 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1325 "HwRateToMRate8812(): Non supported Rate [%x]!!!\n",
1332 /*-----------------------------------------------------------------------------
1333 * Function: odm_TxPwrTrackSetPwr88E()
1335 * Overview: 88E change all channel tx power accordign to flag.
1336 * OFDM & CCK are all different.
1346 * 04/23/2012 MHC Create Version 0.
1348 *---------------------------------------------------------------------------
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
)
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*/
1360 char final_ofdm_swing_index
= 0;
1362 if (rtldm
->tx_rate
!= 0xFF)
1364 rtl8821ae_hw_rate_to_mrate(hw
, rtldm
->tx_rate
);
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) {
1371 if ((tx_rate
>= MGN_1M
) && (tx_rate
<= MGN_11M
))
1372 pwr_tracking_limit
= 32; /*+4dB*/
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*/
1380 else if ((tx_rate
>= MGN_MCS0
) && (tx_rate
<= MGN_MCS2
))
1381 pwr_tracking_limit
= 34; /*+5dB*/
1383 else if ((tx_rate
>= MGN_MCS3
) && (tx_rate
<= MGN_MCS4
))
1384 pwr_tracking_limit
= 30; /*+3dB*/
1386 else if ((tx_rate
>= MGN_MCS5
) && (tx_rate
<= MGN_MCS7
))
1387 pwr_tracking_limit
= 28; /*+2dB*/
1389 else if ((tx_rate
>= MGN_MCS8
) && (tx_rate
<= MGN_MCS10
))
1390 pwr_tracking_limit
= 34; /*+5dB*/
1392 else if ((tx_rate
>= MGN_MCS11
) && (tx_rate
<= MGN_MCS12
))
1393 pwr_tracking_limit
= 30; /*+3dB*/
1395 else if ((tx_rate
>= MGN_MCS13
) && (tx_rate
<= MGN_MCS15
))
1396 pwr_tracking_limit
= 28; /*+2dB*/
1400 else if ((tx_rate
>= MGN_VHT1SS_MCS0
) &&
1401 (tx_rate
<= MGN_VHT1SS_MCS2
))
1402 pwr_tracking_limit
= 34; /*+5dB*/
1404 else if ((tx_rate
>= MGN_VHT1SS_MCS3
) &&
1405 (tx_rate
<= MGN_VHT1SS_MCS4
))
1406 pwr_tracking_limit
= 30; /*+3dB*/
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*/
1418 else if ((tx_rate
>= MGN_VHT2SS_MCS0
) &&
1419 (tx_rate
<= MGN_VHT2SS_MCS2
))
1420 pwr_tracking_limit
= 34; /*+5dB*/
1422 else if ((tx_rate
>= MGN_VHT2SS_MCS3
) &&
1423 (tx_rate
<= MGN_VHT2SS_MCS4
))
1424 pwr_tracking_limit
= 30; /*+3dB*/
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*/
1436 pwr_tracking_limit
= 24;
1438 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1439 "TxRate=0x%x, PwrTrackingLimit=%d\n",
1440 tx_rate
, pwr_tracking_limit
);
1442 if (method
== BBSWING
) {
1443 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1444 "===>rtl8812ae_dm_txpwr_track_set_pwr\n");
1446 if (rf_path
== RF90_PATH_A
) {
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
]);
1460 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
1461 txscaling_tbl
[tmp
]);
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
]);
1476 rtl_set_bbreg(hw
, RB_TXSCALE
, 0xFFE00000,
1477 txscaling_tbl
[tmp
]);
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
],
1486 final_ofdm_swing_index
= rtldm
->default_ofdm_index
+
1487 rtldm
->absolute_ofdm_swing_idx
[rf_path
];
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
-
1495 /* CCK Follow the same compensation value
1498 rtldm
->remnant_ofdm_swing_idx
[rf_path
] =
1499 final_ofdm_swing_index
-
1502 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
1503 txscaling_tbl
[pwr_tracking_limit
]);
1505 rtldm
->modify_txagc_flag_path_a
= true;
1507 /*Set TxAGC Page C{};*/
1508 rtl8821ae_phy_set_txpower_level_by_path(hw
,
1509 rtlphy
->current_channel
,
1512 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1513 "******Path_A Over BBSwing Limit ,PwrTrackingLimit = %d ,Remnant TxAGC Value = %d\n",
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
;
1522 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
1525 rtldm
->modify_txagc_flag_path_a
= true;
1527 /*Set TxAGC Page C{};*/
1528 rtl8821ae_phy_set_txpower_level_by_path(hw
,
1529 rtlphy
->current_channel
, RF90_PATH_A
);
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
]);
1535 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
1536 txscaling_tbl
[(u8
)final_ofdm_swing_index
]);
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;
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;
1551 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
,
1553 "******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
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
-
1564 rtl_set_bbreg(hw
, RB_TXSCALE
,
1566 txscaling_tbl
[pwr_tracking_limit
]);
1568 rtldm
->modify_txagc_flag_path_b
= true;
1570 /*Set TxAGC Page E{};*/
1571 rtl8821ae_phy_set_txpower_level_by_path(hw
,
1572 rtlphy
->current_channel
, RF90_PATH_B
);
1574 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1575 "******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
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
;
1582 rtl_set_bbreg(hw
, RB_TXSCALE
, 0xFFE00000,
1585 rtldm
->modify_txagc_flag_path_b
= true;
1587 /*Set TxAGC Page E{};*/
1588 rtl8821ae_phy_set_txpower_level_by_path(hw
,
1589 rtlphy
->current_channel
, RF90_PATH_B
);
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
]);
1595 rtl_set_bbreg(hw
, RB_TXSCALE
, 0xFFE00000,
1596 txscaling_tbl
[(u8
)final_ofdm_swing_index
]);
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;
1605 /*Set TxAGC Page E{};*/
1606 rtl8821ae_phy_set_txpower_level_by_path(hw
,
1607 rtlphy
->current_channel
, RF90_PATH_B
);
1609 rtldm
->modify_txagc_flag_path_b
=
1612 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1613 "******Path_B pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
1622 void rtl8812ae_dm_txpower_tracking_callback_thermalmeter(
1623 struct ieee80211_hw
*hw
)
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.
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
;
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
);
1651 rtldm
->txpower_trackinginit
= true;
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
);
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)
1670 /* 3. Initialize ThermalValues of RFCalibrateInfo*/
1672 if (rtlhal
->reloadtxpowerindex
)
1673 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1674 "reload ofdm index for band switch\n");
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;
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
++;
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
);
1698 /*5. Calculate delta, delta_LCK, delta_IQK.
1699 *"delta" here is used to determine whether
1700 *thermal value changes or not.
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
);
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
);
1716 /* 6. If necessary, do LCK.
1717 * Delta temperature is equal to or larger than 20 centigrade.
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
);
1727 /*7. If necessary, move the index of swing table to adjust Tx power.*/
1729 if (delta
> 0 && rtldm
->txpower_track_control
) {
1730 /* "delta" here is used to record the
1731 * absolute value of differrence.
1733 delta
= thermal_value
> rtlefuse
->eeprom_thermalmeter
?
1734 (thermal_value
- rtlefuse
->eeprom_thermalmeter
) :
1735 (rtlefuse
->eeprom_thermalmeter
- thermal_value
);
1737 if (delta
>= TXPWR_TRACK_TABLE_SIZE
)
1738 delta
= TXPWR_TRACK_TABLE_SIZE
- 1;
1740 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
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
];
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*/
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
]);
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
];
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*/
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
]);
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
]);
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
];
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
]);
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
]);
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
];
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*/
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
]);
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'));
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;
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
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
]);
1833 rtldm
->ofdm_index
[p
] =
1834 rtldm
->swing_idx_ofdm_base
[p
] +
1835 rtldm
->power_index_offset
[p
];
1837 rtldm
->swing_idx_cck_base
+
1838 rtldm
->power_index_offset
[p
];
1840 rtldm
->swing_idx_cck
= rtldm
->cck_index
;
1841 rtldm
->swing_idx_ofdm
[p
] = rtldm
->ofdm_index
[p
];
1843 /****Print BB Swing Base and Index Offset */
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
]);
1857 /*7.1 Handle boundary conditions of index.*/
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
;
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;
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
,
1875 rtldm
->thermalvalue
);
1877 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++)
1878 rtldm
->power_index_offset
[p
] = 0;
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
]);
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.
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.
1902 *2012/04/25 MH Add for tx power tracking to set
1903 *tx power in tx agc for 88E.
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
);
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
);
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
);
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
);
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
,
1946 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1947 "Temperature(%d) lower than PG value(%d)\n",
1948 thermal_value
, rtlefuse
->eeprom_thermalmeter
);
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
);
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
];
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
;
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);
1973 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1974 "<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n");
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
)
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
;
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
;
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
;
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];
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
;
2022 /*-----------------------------------------------------------------------------
2023 * Function: odm_TxPwrTrackSetPwr88E()
2025 * Overview: 88E change all channel tx power accordign to flag.
2026 * OFDM & CCK are all different.
2036 * 04/23/2012 MHC Create Version 0.
2038 *---------------------------------------------------------------------------
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
)
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*/
2050 char final_ofdm_swing_index
= 0;
2052 if (rtldm
->tx_rate
!= 0xFF)
2053 tx_rate
= rtl8821ae_hw_rate_to_mrate(hw
, rtldm
->tx_rate
);
2055 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
, "===>%s\n", __func__
);
2057 if (tx_rate
!= 0xFF) { /* Mimic Modify High Rate BBSwing Limit.*/
2059 if ((tx_rate
>= MGN_1M
) && (tx_rate
<= MGN_11M
))
2060 pwr_tracking_limit
= 32; /*+4dB*/
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*/
2068 else if ((tx_rate
>= MGN_MCS0
) && (tx_rate
<= MGN_MCS2
))
2069 pwr_tracking_limit
= 34; /*+5dB*/
2071 else if ((tx_rate
>= MGN_MCS3
) && (tx_rate
<= MGN_MCS4
))
2072 pwr_tracking_limit
= 30; /*+3dB*/
2074 else if ((tx_rate
>= MGN_MCS5
) && (tx_rate
<= MGN_MCS7
))
2075 pwr_tracking_limit
= 28; /*+2dB*/
2078 else if ((tx_rate
>= MGN_VHT1SS_MCS0
) &&
2079 (tx_rate
<= MGN_VHT1SS_MCS2
))
2080 pwr_tracking_limit
= 34; /*+5dB*/
2082 else if ((tx_rate
>= MGN_VHT1SS_MCS3
) &&
2083 (tx_rate
<= MGN_VHT1SS_MCS4
))
2084 pwr_tracking_limit
= 30; /*+3dB*/
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*/
2096 pwr_tracking_limit
= 24;
2098 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2099 "TxRate=0x%x, PwrTrackingLimit=%d\n",
2100 tx_rate
, pwr_tracking_limit
);
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
]);
2116 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
2117 txscaling_tbl
[final_swing_idx
[RF90_PATH_A
]]);
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
],
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
-
2135 /* CCK Follow the same compensate value as Path A*/
2136 rtldm
->remnant_ofdm_swing_idx
[rf_path
] =
2137 final_ofdm_swing_index
-
2140 rtl_set_bbreg(hw
, RA_TXSCALE
,
2142 txscaling_tbl
[pwr_tracking_limit
]);
2144 rtldm
->modify_txagc_flag_path_a
= true;
2146 /*Set TxAGC Page C{};*/
2147 rtl8821ae_phy_set_txpower_level_by_path(hw
,
2148 rtlphy
->current_channel
,
2151 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2152 " ******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
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
;
2161 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
2164 rtldm
->modify_txagc_flag_path_a
= true;
2166 /*Set TxAGC Page C{};*/
2167 rtl8821ae_phy_set_txpower_level_by_path(hw
,
2168 rtlphy
->current_channel
, RF90_PATH_A
);
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
]);
2174 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
2175 txscaling_tbl
[(u8
)final_ofdm_swing_index
]);
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;
2185 /*Set TxAGC Page C{};*/
2186 rtl8821ae_phy_set_txpower_level_by_path(hw
,
2187 rtlphy
->current_channel
, RF90_PATH_A
);
2189 rtldm
->modify_txagc_flag_path_a
= false;
2191 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
,
2193 "******Path_A pDM_Odm->Modify_TxAGC_Flag= FALSE\n");
2202 void rtl8821ae_dm_txpower_tracking_callback_thermalmeter(
2203 struct ieee80211_hw
*hw
)
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
;
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;
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;
2219 /* 1. The following TWO tables decide the final
2220 * index of OFDM/CCK swing table.
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
;
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
);
2233 rtldm
->txpower_trackinginit
= true;
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",
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)
2249 /* 3. Initialize ThermalValues of RFCalibrateInfo*/
2251 if (rtlhal
->reloadtxpowerindex
) {
2252 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2253 "reload ofdm index for band switch\n");
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;
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
++;
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
);
2278 /*5. Calculate delta, delta_LCK, delta_IQK.
2279 *"delta" here is used to determine whether
2280 * thermal value changes or not.
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
);
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
);
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
);
2306 /*7. If necessary, move the index of swing table to adjust Tx power.*/
2308 if (delta
> 0 && rtldm
->txpower_track_control
) {
2309 /*"delta" here is used to record the
2310 * absolute value of differrence.
2312 delta
= thermal_value
> rtlefuse
->eeprom_thermalmeter
?
2313 (thermal_value
- rtlefuse
->eeprom_thermalmeter
) :
2314 (rtlefuse
->eeprom_thermalmeter
- thermal_value
);
2316 if (delta
>= TXSCALE_TABLE_SIZE
)
2317 delta
= TXSCALE_TABLE_SIZE
- 1;
2319 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
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
];
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*/
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
]);
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
]);
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
];
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
]);
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
2362 if (rtldm
->delta_power_index
[p
] ==
2363 rtldm
->delta_power_index_last
[p
])
2365 rtldm
->power_index_offset
[p
] = 0;
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*/
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
]);
2379 rtldm
->ofdm_index
[p
] =
2380 rtldm
->swing_idx_ofdm_base
[p
] +
2381 rtldm
->power_index_offset
[p
];
2383 rtldm
->swing_idx_cck_base
+
2384 rtldm
->power_index_offset
[p
];
2386 rtldm
->swing_idx_cck
= rtldm
->cck_index
;
2387 rtldm
->swing_idx_ofdm
[p
] = rtldm
->ofdm_index
[p
];
2389 /*********Print BB Swing Base and Index Offset********/
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
]);
2403 /*7.1 Handle boundary conditions of index.*/
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
;
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;
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
,
2421 rtldm
->thermalvalue
);
2423 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8821A
; p
++)
2424 rtldm
->power_index_offset
[p
] = 0;
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
]);
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.*/
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.
2448 * 2012/04/25 MH Add for tx power tracking to
2449 * set tx power in tx agc for 88E.
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
);
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
);
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
);
2478 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2479 "Temperature(%d) lower than PG value(%d)\n",
2480 thermal_value
, rtlefuse
->eeprom_thermalmeter
);
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
);
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
];
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
;
2499 /* Delta temperature is equal to or larger than
2500 * 20 centigrade (When threshold is 8).
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
);
2508 rtl8821ae_do_iqk(hw
, delta_iqk
, thermal_value
, 8);
2510 spin_lock(&rtlpriv
->locks
.iqk_lock
);
2511 rtlphy
->lck_inprogress
= false;
2512 spin_unlock(&rtlpriv
->locks
.iqk_lock
);
2516 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
, "<===%s\n", __func__
);
2519 void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw
*hw
)
2521 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2522 static u8 tm_trigger
;
2525 rtl_set_rfreg(hw
, RF90_PATH_A
, RF_T_METER_88E
, BIT(17)|BIT(16),
2527 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2528 "Trigger 8821ae Thermal Meter!!\n");
2532 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2533 "Schedule TxPowerTracking !!\n");
2535 rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw
);
2540 static void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw
*hw
)
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
;
2549 struct ieee80211_sta
*sta
= NULL
;
2551 if (is_hal_stop(rtlhal
)) {
2552 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
2553 "driver is going to unload\n");
2557 if (!rtlpriv
->dm
.useramask
) {
2558 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
2559 "driver does not control rate adaptive mask\n");
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
;
2569 case DM_RATR_STA_LOW
:
2570 high_rssithresh_for_ra
+= go_up_gap
;
2571 low_rssithresh_for_ra
+= go_up_gap
;
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
;
2584 p_ra
->ratr_state
= DM_RATR_STA_LOW
;
2586 if (p_ra
->pre_ratr_state
!= p_ra
->ratr_state
) {
2587 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
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
);
2597 sta
= rtl_find_sta(hw
, mac
->bssid
);
2599 rtlpriv
->cfg
->ops
->update_rate_tbl(hw
,
2600 sta
, p_ra
->ratr_state
);
2603 p_ra
->pre_ratr_state
= p_ra
->ratr_state
;
2608 static void rtl8821ae_dm_refresh_basic_rate_mask(struct ieee80211_hw
*hw
)
2610 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2611 struct dig_t
*dm_digtable
= &rtlpriv
->dm_digtable
;
2612 struct rtl_mac
*mac
= &rtlpriv
->mac80211
;
2615 u16 basic_rate
= RRSR_1M
| RRSR_2M
| RRSR_5_5M
| RRSR_11M
| RRSR_6M
;
2617 if (mac
->link_state
< MAC80211_LINKED
)
2619 else if (dm_digtable
->rssi_val_min
< 25)
2621 else if (dm_digtable
->rssi_val_min
> 30)
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
);
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
)
2644 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
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 ");
2652 *pb_is_cur_rdl_state
= true;
2653 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2654 "Balance Traffic\n");
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");
2662 *pb_is_cur_rdl_state
= false;
2663 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2664 "Balance Traffic\n");
2670 static void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw
*hw
)
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
));
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;
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;
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
));
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;
2698 /*===============================
2699 * list paramter for different platform
2700 *===============================
2702 b_last_is_cur_rdl_state
= rtlpriv
->dm
.is_cur_rdlstate
;
2703 pb_is_cur_rdl_state
= &rtlpriv
->dm
.is_cur_rdlstate
;
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
;
2708 rtldm
->last_tx_ok_cnt
= rtlpriv
->stats
.txbytesunicast
;
2709 rtldm
->last_rx_ok_cnt
= rtlpriv
->stats
.rxbytesunicast
;
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
)) ?
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
];
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
);
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
);
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
);
2740 rtl8821ae_dm_edca_choose_traffic_idx(hw
, cur_tx_ok_cnt
,
2741 cur_rx_ok_cnt
, true, pb_is_cur_rdl_state
);
2743 rtl8821ae_dm_edca_choose_traffic_idx(hw
, cur_tx_ok_cnt
,
2744 cur_rx_ok_cnt
, false, pb_is_cur_rdl_state
);
2746 edca_be
= (*pb_is_cur_rdl_state
) ? edca_be_dl
: edca_be_ul
;
2748 rtl_write_dword(rtlpriv
, DM_REG_EDCA_BE_11N
, edca_be
);
2750 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2751 "EDCA Turbo on: EDCA_BE:0x%x\n", edca_be
);
2753 rtlpriv
->dm
.current_turbo_edca
= true;
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
);
2759 if (rtlpriv
->dm
.current_turbo_edca
) {
2761 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_AC_PARAM
,
2764 rtlpriv
->dm
.current_turbo_edca
= false;
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
;
2772 static void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw
*hw
)
2774 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2775 struct dig_t
*dm_digtable
= &rtlpriv
->dm_digtable
;
2776 u8 cur_cck_cca_thresh
;
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;
2785 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
2786 cur_cck_cca_thresh
= 0x83;
2788 cur_cck_cca_thresh
= 0x40;
2791 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
2792 cur_cck_cca_thresh
= 0x83;
2794 cur_cck_cca_thresh
= 0x40;
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
);
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
);
2807 static void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw
*hw
)
2809 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2810 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
2813 int cfo_khz_a
, cfo_khz_b
, cfo_ave
= 0, adjust_xtal
= 0;
2816 if (rtlpriv
->mac80211
.link_state
< MAC80211_LINKED
) {
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
;
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
);
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)));
2836 rtl_set_bbreg(hw
, REG_MAC_PHY_CTRL
,
2837 0xfff000, (crystal_cap
|
2838 (crystal_cap
<< 6)));
2840 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
, "crystal_cap = 0x%x\n",
2841 rtldm
->crystal_cap
);
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
;
2849 if (packet_count
== rtldm
->packet_count_pre
) {
2850 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
2851 "packet counter doesn't change\n");
2855 rtldm
->packet_count_pre
= packet_count
;
2856 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
2857 "packet counter = %d\n",
2858 rtldm
->packet_count
);
2861 if (rtlpriv
->phy
.rf_type
== RF_1T1R
)
2862 cfo_ave
= cfo_khz_a
;
2864 cfo_ave
= (cfo_khz_a
+ cfo_khz_b
) >> 1;
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
);
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
);
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;
2881 rtldm
->large_cfo_hit
= 0;
2883 rtldm
->cfo_ave_pre
= cfo_ave
;
2885 /*CFO tracking by adjusting Xtal cap.*/
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;
2895 rtldm
->cfo_threshold
= CFO_THRESHOLD_XTAL
;
2898 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
2899 "Dynamic threshold = %d\n",
2900 rtldm
->cfo_threshold
);
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
);
2912 /*3.Adjudt Crystal Cap.*/
2913 if (adjust_xtal
!= 0) {
2914 rtldm
->is_freeze
= 0;
2915 rtldm
->crystal_cap
+= adjust_xtal
;
2917 if (rtldm
->crystal_cap
> 0x3f)
2918 rtldm
->crystal_cap
= 0x3f;
2919 else if (rtldm
->crystal_cap
< 0)
2920 rtldm
->crystal_cap
= 0;
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)));
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
);
2939 void rtl8821ae_dm_watchdog(struct ieee80211_hw
*hw
)
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;
2947 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FW_PSMODE_STATUS
,
2948 (u8
*)(&fw_current_inpsmode
));
2950 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FWLPS_RF_ON
,
2951 (u8
*)(&fw_ps_awake
));
2953 if (ppsc
->p2p_ps_info
.p2p_ps_mode
)
2954 fw_ps_awake
= false;
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
);
2971 rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw
);
2972 rtl8821ae_dm_iq_calibrate(hw
);
2975 rtlpriv
->dm
.dbginfo
.num_qry_beacon_pkt
= 0;
2976 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_DMESG
, "\n");
2979 void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw
*hw
,
2980 u8
*pdesc
, u32 mac_id
)
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
;
2987 if (rtlhal
->hw_type
!= HARDWARE_TYPE_RTL8812AE
)
2990 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
2991 SET_TX_DESC_TX_ANT(pdesc
, pfat_table
->antsel_a
[mac_id
]);