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 disconnect 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
);
1072 if (!rtlpriv
->dm
.tm_trigger
) {
1073 rtl_set_rfreg(hw
, RF90_PATH_A
, RF_T_METER_88E
,
1074 BIT(17) | BIT(16), 0x03);
1075 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1076 "Trigger 8812 Thermal Meter!!\n");
1077 rtlpriv
->dm
.tm_trigger
= 1;
1080 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1081 "Schedule TxPowerTracking direct call!!\n");
1082 rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw
);
1085 static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw
*hw
)
1087 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
1088 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1089 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
1091 if (mac
->link_state
>= MAC80211_LINKED
) {
1092 if (rtldm
->linked_interval
< 3)
1093 rtldm
->linked_interval
++;
1095 if (rtldm
->linked_interval
== 2) {
1096 if (rtlhal
->hw_type
== HARDWARE_TYPE_RTL8812AE
)
1097 rtl8812ae_phy_iq_calibrate(hw
, false);
1099 rtl8821ae_phy_iq_calibrate(hw
, false);
1102 rtldm
->linked_interval
= 0;
1106 static void rtl8812ae_get_delta_swing_table(struct ieee80211_hw
*hw
,
1107 u8
**up_a
, u8
**down_a
,
1108 u8
**up_b
, u8
**down_b
)
1110 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1111 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
1112 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1113 u8 channel
= rtlphy
->current_channel
;
1114 u8 rate
= rtldm
->tx_rate
;
1116 if (1 <= channel
&& channel
<= 14) {
1117 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate
)) {
1118 *up_a
= rtl8812ae_delta_swing_table_idx_24gccka_p
;
1119 *down_a
= rtl8812ae_delta_swing_table_idx_24gccka_n
;
1120 *up_b
= rtl8812ae_delta_swing_table_idx_24gcckb_p
;
1121 *down_b
= rtl8812ae_delta_swing_table_idx_24gcckb_n
;
1123 *up_a
= rtl8812ae_delta_swing_table_idx_24ga_p
;
1124 *down_a
= rtl8812ae_delta_swing_table_idx_24ga_n
;
1125 *up_b
= rtl8812ae_delta_swing_table_idx_24gb_p
;
1126 *down_b
= rtl8812ae_delta_swing_table_idx_24gb_n
;
1128 } else if (36 <= channel
&& channel
<= 64) {
1129 *up_a
= rtl8812ae_delta_swing_table_idx_5ga_p
[0];
1130 *down_a
= rtl8812ae_delta_swing_table_idx_5ga_n
[0];
1131 *up_b
= rtl8812ae_delta_swing_table_idx_5gb_p
[0];
1132 *down_b
= rtl8812ae_delta_swing_table_idx_5gb_n
[0];
1133 } else if (100 <= channel
&& channel
<= 140) {
1134 *up_a
= rtl8812ae_delta_swing_table_idx_5ga_p
[1];
1135 *down_a
= rtl8812ae_delta_swing_table_idx_5ga_n
[1];
1136 *up_b
= rtl8812ae_delta_swing_table_idx_5gb_p
[1];
1137 *down_b
= rtl8812ae_delta_swing_table_idx_5gb_n
[1];
1138 } else if (149 <= channel
&& channel
<= 173) {
1139 *up_a
= rtl8812ae_delta_swing_table_idx_5ga_p
[2];
1140 *down_a
= rtl8812ae_delta_swing_table_idx_5ga_n
[2];
1141 *up_b
= rtl8812ae_delta_swing_table_idx_5gb_p
[2];
1142 *down_b
= rtl8812ae_delta_swing_table_idx_5gb_n
[2];
1144 *up_a
= (u8
*)rtl8818e_delta_swing_table_idx_24gb_p
;
1145 *down_a
= (u8
*)rtl8818e_delta_swing_table_idx_24gb_n
;
1146 *up_b
= (u8
*)rtl8818e_delta_swing_table_idx_24gb_p
;
1147 *down_b
= (u8
*)rtl8818e_delta_swing_table_idx_24gb_n
;
1151 void rtl8821ae_dm_update_init_rate(struct ieee80211_hw
*hw
, u8 rate
)
1153 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1154 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1155 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
1158 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1159 "Get C2H Command! Rate=0x%x\n", rate
);
1161 rtldm
->tx_rate
= rate
;
1163 if (rtlhal
->hw_type
== HARDWARE_TYPE_RTL8821AE
) {
1164 rtl8821ae_dm_txpwr_track_set_pwr(hw
, MIX_MODE
, RF90_PATH_A
, 0);
1166 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++)
1167 rtl8812ae_dm_txpwr_track_set_pwr(hw
, MIX_MODE
, p
, 0);
1171 u8
rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw
*hw
, u8 rate
)
1173 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1174 u8 ret_rate
= MGN_1M
;
1184 ret_rate
= MGN_5_5M
;
1214 ret_rate
= MGN_MCS0
;
1217 ret_rate
= MGN_MCS1
;
1220 ret_rate
= MGN_MCS2
;
1223 ret_rate
= MGN_MCS3
;
1226 ret_rate
= MGN_MCS4
;
1229 ret_rate
= MGN_MCS5
;
1232 ret_rate
= MGN_MCS6
;
1235 ret_rate
= MGN_MCS7
;
1238 ret_rate
= MGN_MCS8
;
1241 ret_rate
= MGN_MCS9
;
1243 case DESC_RATEMCS10
:
1244 ret_rate
= MGN_MCS10
;
1246 case DESC_RATEMCS11
:
1247 ret_rate
= MGN_MCS11
;
1249 case DESC_RATEMCS12
:
1250 ret_rate
= MGN_MCS12
;
1252 case DESC_RATEMCS13
:
1253 ret_rate
= MGN_MCS13
;
1255 case DESC_RATEMCS14
:
1256 ret_rate
= MGN_MCS14
;
1258 case DESC_RATEMCS15
:
1259 ret_rate
= MGN_MCS15
;
1261 case DESC_RATEVHT1SS_MCS0
:
1262 ret_rate
= MGN_VHT1SS_MCS0
;
1264 case DESC_RATEVHT1SS_MCS1
:
1265 ret_rate
= MGN_VHT1SS_MCS1
;
1267 case DESC_RATEVHT1SS_MCS2
:
1268 ret_rate
= MGN_VHT1SS_MCS2
;
1270 case DESC_RATEVHT1SS_MCS3
:
1271 ret_rate
= MGN_VHT1SS_MCS3
;
1273 case DESC_RATEVHT1SS_MCS4
:
1274 ret_rate
= MGN_VHT1SS_MCS4
;
1276 case DESC_RATEVHT1SS_MCS5
:
1277 ret_rate
= MGN_VHT1SS_MCS5
;
1279 case DESC_RATEVHT1SS_MCS6
:
1280 ret_rate
= MGN_VHT1SS_MCS6
;
1282 case DESC_RATEVHT1SS_MCS7
:
1283 ret_rate
= MGN_VHT1SS_MCS7
;
1285 case DESC_RATEVHT1SS_MCS8
:
1286 ret_rate
= MGN_VHT1SS_MCS8
;
1288 case DESC_RATEVHT1SS_MCS9
:
1289 ret_rate
= MGN_VHT1SS_MCS9
;
1291 case DESC_RATEVHT2SS_MCS0
:
1292 ret_rate
= MGN_VHT2SS_MCS0
;
1294 case DESC_RATEVHT2SS_MCS1
:
1295 ret_rate
= MGN_VHT2SS_MCS1
;
1297 case DESC_RATEVHT2SS_MCS2
:
1298 ret_rate
= MGN_VHT2SS_MCS2
;
1300 case DESC_RATEVHT2SS_MCS3
:
1301 ret_rate
= MGN_VHT2SS_MCS3
;
1303 case DESC_RATEVHT2SS_MCS4
:
1304 ret_rate
= MGN_VHT2SS_MCS4
;
1306 case DESC_RATEVHT2SS_MCS5
:
1307 ret_rate
= MGN_VHT2SS_MCS5
;
1309 case DESC_RATEVHT2SS_MCS6
:
1310 ret_rate
= MGN_VHT2SS_MCS6
;
1312 case DESC_RATEVHT2SS_MCS7
:
1313 ret_rate
= MGN_VHT2SS_MCS7
;
1315 case DESC_RATEVHT2SS_MCS8
:
1316 ret_rate
= MGN_VHT2SS_MCS8
;
1318 case DESC_RATEVHT2SS_MCS9
:
1319 ret_rate
= MGN_VHT2SS_MCS9
;
1322 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1323 "HwRateToMRate8812(): Non supported Rate [%x]!!!\n",
1330 /*-----------------------------------------------------------------------------
1331 * Function: odm_TxPwrTrackSetPwr88E()
1333 * Overview: 88E change all channel tx power accordign to flag.
1334 * OFDM & CCK are all different.
1344 * 04/23/2012 MHC Create Version 0.
1346 *---------------------------------------------------------------------------
1348 void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw
*hw
,
1349 enum pwr_track_control_method method
,
1350 u8 rf_path
, u8 channel_mapped_index
)
1352 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1353 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1354 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
1355 u32 final_swing_idx
[2];
1356 u8 pwr_tracking_limit
= 26; /*+1.0dB*/
1358 char final_ofdm_swing_index
= 0;
1360 if (rtldm
->tx_rate
!= 0xFF)
1362 rtl8821ae_hw_rate_to_mrate(hw
, rtldm
->tx_rate
);
1364 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1365 "===>rtl8812ae_dm_txpwr_track_set_pwr\n");
1366 /*20130429 Mimic Modify High Rate BBSwing Limit.*/
1367 if (tx_rate
!= 0xFF) {
1369 if ((tx_rate
>= MGN_1M
) && (tx_rate
<= MGN_11M
))
1370 pwr_tracking_limit
= 32; /*+4dB*/
1372 else if ((tx_rate
>= MGN_6M
) && (tx_rate
<= MGN_48M
))
1373 pwr_tracking_limit
= 30; /*+3dB*/
1374 else if (tx_rate
== MGN_54M
)
1375 pwr_tracking_limit
= 28; /*+2dB*/
1378 else if ((tx_rate
>= MGN_MCS0
) && (tx_rate
<= MGN_MCS2
))
1379 pwr_tracking_limit
= 34; /*+5dB*/
1381 else if ((tx_rate
>= MGN_MCS3
) && (tx_rate
<= MGN_MCS4
))
1382 pwr_tracking_limit
= 30; /*+3dB*/
1384 else if ((tx_rate
>= MGN_MCS5
) && (tx_rate
<= MGN_MCS7
))
1385 pwr_tracking_limit
= 28; /*+2dB*/
1387 else if ((tx_rate
>= MGN_MCS8
) && (tx_rate
<= MGN_MCS10
))
1388 pwr_tracking_limit
= 34; /*+5dB*/
1390 else if ((tx_rate
>= MGN_MCS11
) && (tx_rate
<= MGN_MCS12
))
1391 pwr_tracking_limit
= 30; /*+3dB*/
1393 else if ((tx_rate
>= MGN_MCS13
) && (tx_rate
<= MGN_MCS15
))
1394 pwr_tracking_limit
= 28; /*+2dB*/
1398 else if ((tx_rate
>= MGN_VHT1SS_MCS0
) &&
1399 (tx_rate
<= MGN_VHT1SS_MCS2
))
1400 pwr_tracking_limit
= 34; /*+5dB*/
1402 else if ((tx_rate
>= MGN_VHT1SS_MCS3
) &&
1403 (tx_rate
<= MGN_VHT1SS_MCS4
))
1404 pwr_tracking_limit
= 30; /*+3dB*/
1406 else if ((tx_rate
>= MGN_VHT1SS_MCS5
) &&
1407 (tx_rate
<= MGN_VHT1SS_MCS6
))
1408 pwr_tracking_limit
= 28; /*+2dB*/
1409 else if (tx_rate
== MGN_VHT1SS_MCS7
) /*64QAM*/
1410 pwr_tracking_limit
= 26; /*+1dB*/
1411 else if (tx_rate
== MGN_VHT1SS_MCS8
) /*256QAM*/
1412 pwr_tracking_limit
= 24; /*+0dB*/
1413 else if (tx_rate
== MGN_VHT1SS_MCS9
) /*256QAM*/
1414 pwr_tracking_limit
= 22; /*-1dB*/
1416 else if ((tx_rate
>= MGN_VHT2SS_MCS0
) &&
1417 (tx_rate
<= MGN_VHT2SS_MCS2
))
1418 pwr_tracking_limit
= 34; /*+5dB*/
1420 else if ((tx_rate
>= MGN_VHT2SS_MCS3
) &&
1421 (tx_rate
<= MGN_VHT2SS_MCS4
))
1422 pwr_tracking_limit
= 30; /*+3dB*/
1424 else if ((tx_rate
>= MGN_VHT2SS_MCS5
) &&
1425 (tx_rate
<= MGN_VHT2SS_MCS6
))
1426 pwr_tracking_limit
= 28; /*+2dB*/
1427 else if (tx_rate
== MGN_VHT2SS_MCS7
) /*64QAM*/
1428 pwr_tracking_limit
= 26; /*+1dB*/
1429 else if (tx_rate
== MGN_VHT2SS_MCS8
) /*256QAM*/
1430 pwr_tracking_limit
= 24; /*+0dB*/
1431 else if (tx_rate
== MGN_VHT2SS_MCS9
) /*256QAM*/
1432 pwr_tracking_limit
= 22; /*-1dB*/
1434 pwr_tracking_limit
= 24;
1436 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1437 "TxRate=0x%x, PwrTrackingLimit=%d\n",
1438 tx_rate
, pwr_tracking_limit
);
1440 if (method
== BBSWING
) {
1441 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1442 "===>rtl8812ae_dm_txpwr_track_set_pwr\n");
1444 if (rf_path
== RF90_PATH_A
) {
1447 final_swing_idx
[RF90_PATH_A
] =
1448 (rtldm
->ofdm_index
[RF90_PATH_A
] >
1449 pwr_tracking_limit
) ?
1450 pwr_tracking_limit
:
1451 rtldm
->ofdm_index
[RF90_PATH_A
];
1452 tmp
= final_swing_idx
[RF90_PATH_A
];
1453 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1454 "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
1455 rtldm
->ofdm_index
[RF90_PATH_A
],
1456 final_swing_idx
[RF90_PATH_A
]);
1458 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
1459 txscaling_tbl
[tmp
]);
1463 final_swing_idx
[RF90_PATH_B
] =
1464 rtldm
->ofdm_index
[RF90_PATH_B
] >
1465 pwr_tracking_limit
?
1466 pwr_tracking_limit
:
1467 rtldm
->ofdm_index
[RF90_PATH_B
];
1468 tmp
= final_swing_idx
[RF90_PATH_B
];
1469 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1470 "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_B]=%d, pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_B]=%d\n",
1471 rtldm
->ofdm_index
[RF90_PATH_B
],
1472 final_swing_idx
[RF90_PATH_B
]);
1474 rtl_set_bbreg(hw
, RB_TXSCALE
, 0xFFE00000,
1475 txscaling_tbl
[tmp
]);
1477 } else if (method
== MIX_MODE
) {
1478 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1479 "pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->Aboslute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
1480 rtldm
->default_ofdm_index
,
1481 rtldm
->absolute_ofdm_swing_idx
[rf_path
],
1484 final_ofdm_swing_index
= rtldm
->default_ofdm_index
+
1485 rtldm
->absolute_ofdm_swing_idx
[rf_path
];
1487 if (rf_path
== RF90_PATH_A
) {
1488 /*BBSwing higher then Limit*/
1489 if (final_ofdm_swing_index
> pwr_tracking_limit
) {
1490 rtldm
->remnant_cck_idx
=
1491 final_ofdm_swing_index
-
1493 /* CCK Follow the same compensation value
1496 rtldm
->remnant_ofdm_swing_idx
[rf_path
] =
1497 final_ofdm_swing_index
-
1500 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
1501 txscaling_tbl
[pwr_tracking_limit
]);
1503 rtldm
->modify_txagc_flag_path_a
= true;
1505 /*Set TxAGC Page C{};*/
1506 rtl8821ae_phy_set_txpower_level_by_path(hw
,
1507 rtlphy
->current_channel
,
1510 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1511 "******Path_A Over BBSwing Limit ,PwrTrackingLimit = %d ,Remnant TxAGC Value = %d\n",
1513 rtldm
->remnant_ofdm_swing_idx
[rf_path
]);
1514 } else if (final_ofdm_swing_index
< 0) {
1515 rtldm
->remnant_cck_idx
= final_ofdm_swing_index
;
1516 /* CCK Follow the same compensate value as Path A*/
1517 rtldm
->remnant_ofdm_swing_idx
[rf_path
] =
1518 final_ofdm_swing_index
;
1520 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
1523 rtldm
->modify_txagc_flag_path_a
= true;
1525 /*Set TxAGC Page C{};*/
1526 rtl8821ae_phy_set_txpower_level_by_path(hw
,
1527 rtlphy
->current_channel
, RF90_PATH_A
);
1529 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1530 "******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n",
1531 rtldm
->remnant_ofdm_swing_idx
[rf_path
]);
1533 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
1534 txscaling_tbl
[(u8
)final_ofdm_swing_index
]);
1536 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1537 "******Path_A Compensate with BBSwing, Final_OFDM_Swing_Index = %d\n",
1538 final_ofdm_swing_index
);
1539 /*If TxAGC has changed, reset TxAGC again*/
1540 if (rtldm
->modify_txagc_flag_path_a
) {
1541 rtldm
->remnant_cck_idx
= 0;
1542 rtldm
->remnant_ofdm_swing_idx
[rf_path
] = 0;
1544 /*Set TxAGC Page C{};*/
1545 rtl8821ae_phy_set_txpower_level_by_path(hw
,
1546 rtlphy
->current_channel
, RF90_PATH_A
);
1547 rtldm
->modify_txagc_flag_path_a
= false;
1549 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
,
1551 "******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
1555 /*BBSwing higher then Limit*/
1556 if (rf_path
== RF90_PATH_B
) {
1557 if (final_ofdm_swing_index
> pwr_tracking_limit
) {
1558 rtldm
->remnant_ofdm_swing_idx
[rf_path
] =
1559 final_ofdm_swing_index
-
1562 rtl_set_bbreg(hw
, RB_TXSCALE
,
1564 txscaling_tbl
[pwr_tracking_limit
]);
1566 rtldm
->modify_txagc_flag_path_b
= true;
1568 /*Set TxAGC Page E{};*/
1569 rtl8821ae_phy_set_txpower_level_by_path(hw
,
1570 rtlphy
->current_channel
, RF90_PATH_B
);
1572 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1573 "******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
1575 rtldm
->remnant_ofdm_swing_idx
[rf_path
]);
1576 } else if (final_ofdm_swing_index
< 0) {
1577 rtldm
->remnant_ofdm_swing_idx
[rf_path
] =
1578 final_ofdm_swing_index
;
1580 rtl_set_bbreg(hw
, RB_TXSCALE
, 0xFFE00000,
1583 rtldm
->modify_txagc_flag_path_b
= true;
1585 /*Set TxAGC Page E{};*/
1586 rtl8821ae_phy_set_txpower_level_by_path(hw
,
1587 rtlphy
->current_channel
, RF90_PATH_B
);
1589 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1590 "******Path_B Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n",
1591 rtldm
->remnant_ofdm_swing_idx
[rf_path
]);
1593 rtl_set_bbreg(hw
, RB_TXSCALE
, 0xFFE00000,
1594 txscaling_tbl
[(u8
)final_ofdm_swing_index
]);
1596 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1597 "******Path_B Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n",
1598 final_ofdm_swing_index
);
1599 /*If TxAGC has changed, reset TxAGC again*/
1600 if (rtldm
->modify_txagc_flag_path_b
) {
1601 rtldm
->remnant_ofdm_swing_idx
[rf_path
] = 0;
1603 /*Set TxAGC Page E{};*/
1604 rtl8821ae_phy_set_txpower_level_by_path(hw
,
1605 rtlphy
->current_channel
, RF90_PATH_B
);
1607 rtldm
->modify_txagc_flag_path_b
=
1610 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1611 "******Path_B pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
1620 void rtl8812ae_dm_txpower_tracking_callback_thermalmeter(
1621 struct ieee80211_hw
*hw
)
1623 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1624 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1625 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1626 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
1627 u8 thermal_value
= 0, delta
, delta_lck
, delta_iqk
, p
= 0, i
= 0;
1628 u8 thermal_value_avg_count
= 0;
1629 u32 thermal_value_avg
= 0;
1630 /* OFDM BB Swing should be less than +3.0dB, */
1631 u8 ofdm_min_index
= 6;
1632 /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
1633 u8 index_for_channel
= 0;
1634 /* 1. The following TWO tables decide
1635 * the final index of OFDM/CCK swing table.
1637 u8
*delta_swing_table_idx_tup_a
;
1638 u8
*delta_swing_table_idx_tdown_a
;
1639 u8
*delta_swing_table_idx_tup_b
;
1640 u8
*delta_swing_table_idx_tdown_b
;
1642 /*2. Initilization ( 7 steps in total )*/
1643 rtl8812ae_get_delta_swing_table(hw
,
1644 (u8
**)&delta_swing_table_idx_tup_a
,
1645 (u8
**)&delta_swing_table_idx_tdown_a
,
1646 (u8
**)&delta_swing_table_idx_tup_b
,
1647 (u8
**)&delta_swing_table_idx_tdown_b
);
1649 rtldm
->txpower_trackinginit
= true;
1651 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1652 "pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n",
1653 rtldm
->swing_idx_cck_base
,
1654 rtldm
->swing_idx_ofdm_base
[RF90_PATH_A
],
1655 rtldm
->default_ofdm_index
);
1657 thermal_value
= (u8
)rtl_get_rfreg(hw
, RF90_PATH_A
,
1658 /*0x42: RF Reg[15:10] 88E*/
1659 RF_T_METER_8812A
, 0xfc00);
1660 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1661 "Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
1662 thermal_value
, rtlefuse
->eeprom_thermalmeter
);
1663 if (!rtldm
->txpower_track_control
||
1664 rtlefuse
->eeprom_thermalmeter
== 0 ||
1665 rtlefuse
->eeprom_thermalmeter
== 0xFF)
1668 /* 3. Initialize ThermalValues of RFCalibrateInfo*/
1670 if (rtlhal
->reloadtxpowerindex
)
1671 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1672 "reload ofdm index for band switch\n");
1674 /*4. Calculate average thermal meter*/
1675 rtldm
->thermalvalue_avg
[rtldm
->thermalvalue_avg_index
] = thermal_value
;
1676 rtldm
->thermalvalue_avg_index
++;
1677 if (rtldm
->thermalvalue_avg_index
== AVG_THERMAL_NUM_8812A
)
1678 /*Average times = c.AverageThermalNum*/
1679 rtldm
->thermalvalue_avg_index
= 0;
1681 for (i
= 0; i
< AVG_THERMAL_NUM_8812A
; i
++) {
1682 if (rtldm
->thermalvalue_avg
[i
]) {
1683 thermal_value_avg
+= rtldm
->thermalvalue_avg
[i
];
1684 thermal_value_avg_count
++;
1687 /*Calculate Average ThermalValue after average enough times*/
1688 if (thermal_value_avg_count
) {
1689 thermal_value
= (u8
)(thermal_value_avg
/
1690 thermal_value_avg_count
);
1691 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1692 "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
1693 thermal_value
, rtlefuse
->eeprom_thermalmeter
);
1696 /*5. Calculate delta, delta_LCK, delta_IQK.
1697 *"delta" here is used to determine whether
1698 *thermal value changes or not.
1700 delta
= (thermal_value
> rtldm
->thermalvalue
) ?
1701 (thermal_value
- rtldm
->thermalvalue
) :
1702 (rtldm
->thermalvalue
- thermal_value
);
1703 delta_lck
= (thermal_value
> rtldm
->thermalvalue_lck
) ?
1704 (thermal_value
- rtldm
->thermalvalue_lck
) :
1705 (rtldm
->thermalvalue_lck
- thermal_value
);
1706 delta_iqk
= (thermal_value
> rtldm
->thermalvalue_iqk
) ?
1707 (thermal_value
- rtldm
->thermalvalue_iqk
) :
1708 (rtldm
->thermalvalue_iqk
- thermal_value
);
1710 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1711 "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
1712 delta
, delta_lck
, delta_iqk
);
1714 /* 6. If necessary, do LCK.
1715 * Delta temperature is equal to or larger than 20 centigrade.
1717 if (delta_lck
>= IQK_THRESHOLD
) {
1718 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1719 "delta_LCK(%d) >= Threshold_IQK(%d)\n",
1720 delta_lck
, IQK_THRESHOLD
);
1721 rtldm
->thermalvalue_lck
= thermal_value
;
1722 rtl8821ae_phy_lc_calibrate(hw
);
1725 /*7. If necessary, move the index of swing table to adjust Tx power.*/
1727 if (delta
> 0 && rtldm
->txpower_track_control
) {
1728 /* "delta" here is used to record the
1729 * absolute value of differrence.
1731 delta
= thermal_value
> rtlefuse
->eeprom_thermalmeter
?
1732 (thermal_value
- rtlefuse
->eeprom_thermalmeter
) :
1733 (rtlefuse
->eeprom_thermalmeter
- thermal_value
);
1735 if (delta
>= TXPWR_TRACK_TABLE_SIZE
)
1736 delta
= TXPWR_TRACK_TABLE_SIZE
- 1;
1738 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
1740 if (thermal_value
> rtlefuse
->eeprom_thermalmeter
) {
1741 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1742 "delta_swing_table_idx_tup_a[%d] = %d\n",
1743 delta
, delta_swing_table_idx_tup_a
[delta
]);
1744 rtldm
->delta_power_index_last
[RF90_PATH_A
] =
1745 rtldm
->delta_power_index
[RF90_PATH_A
];
1746 rtldm
->delta_power_index
[RF90_PATH_A
] =
1747 delta_swing_table_idx_tup_a
[delta
];
1749 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_A
] =
1750 delta_swing_table_idx_tup_a
[delta
];
1751 /*Record delta swing for mix mode power tracking*/
1753 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1754 "******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
1755 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_A
]);
1757 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1758 "delta_swing_table_idx_tup_b[%d] = %d\n",
1759 delta
, delta_swing_table_idx_tup_b
[delta
]);
1760 rtldm
->delta_power_index_last
[RF90_PATH_B
] =
1761 rtldm
->delta_power_index
[RF90_PATH_B
];
1762 rtldm
->delta_power_index
[RF90_PATH_B
] =
1763 delta_swing_table_idx_tup_b
[delta
];
1765 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_B
] =
1766 delta_swing_table_idx_tup_b
[delta
];
1767 /*Record delta swing for mix mode power tracking*/
1769 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1770 "******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
1771 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_B
]);
1773 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1774 "delta_swing_table_idx_tdown_a[%d] = %d\n",
1775 delta
, delta_swing_table_idx_tdown_a
[delta
]);
1777 rtldm
->delta_power_index_last
[RF90_PATH_A
] =
1778 rtldm
->delta_power_index
[RF90_PATH_A
];
1779 rtldm
->delta_power_index
[RF90_PATH_A
] =
1780 -1 * delta_swing_table_idx_tdown_a
[delta
];
1782 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_A
] =
1783 -1 * delta_swing_table_idx_tdown_a
[delta
];
1784 /* Record delta swing for mix mode power tracking*/
1785 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1786 "******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
1787 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_A
]);
1789 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1790 "deltaSwingTableIdx_TDOWN_B[%d] = %d\n",
1791 delta
, delta_swing_table_idx_tdown_b
[delta
]);
1793 rtldm
->delta_power_index_last
[RF90_PATH_B
] =
1794 rtldm
->delta_power_index
[RF90_PATH_B
];
1795 rtldm
->delta_power_index
[RF90_PATH_B
] =
1796 -1 * delta_swing_table_idx_tdown_b
[delta
];
1798 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_B
] =
1799 -1 * delta_swing_table_idx_tdown_b
[delta
];
1800 /*Record delta swing for mix mode power tracking*/
1802 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1803 "******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
1804 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_B
]);
1807 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++) {
1808 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1809 "============================= [Path-%c]Calculating PowerIndexOffset =============================\n",
1810 (p
== RF90_PATH_A
? 'A' : 'B'));
1812 if (rtldm
->delta_power_index
[p
] ==
1813 rtldm
->delta_power_index_last
[p
])
1814 /*If Thermal value changes but lookup
1815 table value still the same*/
1816 rtldm
->power_index_offset
[p
] = 0;
1818 rtldm
->power_index_offset
[p
] =
1819 rtldm
->delta_power_index
[p
] -
1820 rtldm
->delta_power_index_last
[p
];
1821 /* Power Index Diff between 2
1822 * times Power Tracking
1824 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1825 "[Path-%c] PowerIndexOffset(%d) =DeltaPowerIndex(%d) -DeltaPowerIndexLast(%d)\n",
1826 (p
== RF90_PATH_A
? 'A' : 'B'),
1827 rtldm
->power_index_offset
[p
],
1828 rtldm
->delta_power_index
[p
] ,
1829 rtldm
->delta_power_index_last
[p
]);
1831 rtldm
->ofdm_index
[p
] =
1832 rtldm
->swing_idx_ofdm_base
[p
] +
1833 rtldm
->power_index_offset
[p
];
1835 rtldm
->swing_idx_cck_base
+
1836 rtldm
->power_index_offset
[p
];
1838 rtldm
->swing_idx_cck
= rtldm
->cck_index
;
1839 rtldm
->swing_idx_ofdm
[p
] = rtldm
->ofdm_index
[p
];
1841 /****Print BB Swing Base and Index Offset */
1843 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1844 "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
1845 rtldm
->swing_idx_cck
,
1846 rtldm
->swing_idx_cck_base
,
1847 rtldm
->power_index_offset
[p
]);
1848 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1849 "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
1850 rtldm
->swing_idx_ofdm
[p
],
1851 (p
== RF90_PATH_A
? 'A' : 'B'),
1852 rtldm
->swing_idx_ofdm_base
[p
],
1853 rtldm
->power_index_offset
[p
]);
1855 /*7.1 Handle boundary conditions of index.*/
1857 if (rtldm
->ofdm_index
[p
] > TXSCALE_TABLE_SIZE
- 1)
1858 rtldm
->ofdm_index
[p
] = TXSCALE_TABLE_SIZE
- 1;
1859 else if (rtldm
->ofdm_index
[p
] < ofdm_min_index
)
1860 rtldm
->ofdm_index
[p
] = ofdm_min_index
;
1862 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1863 "\n\n====================================================================================\n");
1864 if (rtldm
->cck_index
> TXSCALE_TABLE_SIZE
- 1)
1865 rtldm
->cck_index
= TXSCALE_TABLE_SIZE
- 1;
1866 else if (rtldm
->cck_index
< 0)
1867 rtldm
->cck_index
= 0;
1869 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1870 "The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
1871 rtldm
->txpower_track_control
,
1873 rtldm
->thermalvalue
);
1875 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++)
1876 rtldm
->power_index_offset
[p
] = 0;
1878 /*Print Swing base & current*/
1879 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1880 "TxPowerTracking: [CCK] Swing Current Index: %d,Swing Base Index: %d\n",
1881 rtldm
->cck_index
, rtldm
->swing_idx_cck_base
);
1882 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++) {
1883 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1884 "TxPowerTracking: [OFDM] Swing Current Index: %d,Swing Base Index[%c]: %d\n",
1885 rtldm
->ofdm_index
[p
],
1886 (p
== RF90_PATH_A
? 'A' : 'B'),
1887 rtldm
->swing_idx_ofdm_base
[p
]);
1890 if ((rtldm
->power_index_offset
[RF90_PATH_A
] != 0 ||
1891 rtldm
->power_index_offset
[RF90_PATH_B
] != 0) &&
1892 rtldm
->txpower_track_control
) {
1893 /*7.2 Configure the Swing Table to adjust Tx Power.
1894 *Always TRUE after Tx Power is adjusted by power tracking.
1896 *2012/04/23 MH According to Luke's suggestion,
1897 *we can not write BB digital
1898 *to increase TX power. Otherwise, EVM will be bad.
1900 *2012/04/25 MH Add for tx power tracking to set
1901 *tx power in tx agc for 88E.
1903 if (thermal_value
> rtldm
->thermalvalue
) {
1904 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1905 "Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d,EFUSE_t: %d, Last_t: %d\n",
1906 rtldm
->power_index_offset
[RF90_PATH_A
],
1907 delta
, thermal_value
,
1908 rtlefuse
->eeprom_thermalmeter
,
1909 rtldm
->thermalvalue
);
1911 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1912 "Temperature Increasing(B): delta_pi: %d ,delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1913 rtldm
->power_index_offset
[RF90_PATH_B
],
1914 delta
, thermal_value
,
1915 rtlefuse
->eeprom_thermalmeter
,
1916 rtldm
->thermalvalue
);
1917 } else if (thermal_value
< rtldm
->thermalvalue
) { /*Low temperature*/
1918 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1919 "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1920 rtldm
->power_index_offset
[RF90_PATH_A
],
1921 delta
, thermal_value
,
1922 rtlefuse
->eeprom_thermalmeter
,
1923 rtldm
->thermalvalue
);
1925 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1926 "Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1927 rtldm
->power_index_offset
[RF90_PATH_B
],
1928 delta
, thermal_value
,
1929 rtlefuse
->eeprom_thermalmeter
,
1930 rtldm
->thermalvalue
);
1933 if (thermal_value
> rtlefuse
->eeprom_thermalmeter
) {
1934 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1935 "Temperature(%d) higher than PG value(%d)\n",
1936 thermal_value
, rtlefuse
->eeprom_thermalmeter
);
1938 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1939 "**********Enter POWER Tracking MIX_MODE**********\n");
1940 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++)
1941 rtl8812ae_dm_txpwr_track_set_pwr(hw
, MIX_MODE
,
1944 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1945 "Temperature(%d) lower than PG value(%d)\n",
1946 thermal_value
, rtlefuse
->eeprom_thermalmeter
);
1948 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1949 "**********Enter POWER Tracking MIX_MODE**********\n");
1950 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++)
1951 rtl8812ae_dm_txpwr_track_set_pwr(hw
, MIX_MODE
,
1952 p
, index_for_channel
);
1954 /*Record last time Power Tracking result as base.*/
1955 rtldm
->swing_idx_cck_base
= rtldm
->swing_idx_cck
;
1956 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8812A
; p
++)
1957 rtldm
->swing_idx_ofdm_base
[p
] =
1958 rtldm
->swing_idx_ofdm
[p
];
1960 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1961 "pDM_Odm->RFCalibrateInfo.ThermalValue =%d ThermalValue= %d\n",
1962 rtldm
->thermalvalue
, thermal_value
);
1963 /*Record last Power Tracking Thermal Value*/
1964 rtldm
->thermalvalue
= thermal_value
;
1966 /*Delta temperature is equal to or larger than
1967 20 centigrade (When threshold is 8).*/
1968 if (delta_iqk
>= IQK_THRESHOLD
)
1969 rtl8812ae_do_iqk(hw
, delta_iqk
, thermal_value
, 8);
1971 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1972 "<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n");
1975 static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw
*hw
, u8
**up_a
,
1976 u8
**down_a
, u8
**up_b
, u8
**down_b
)
1978 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1979 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
1980 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1981 u8 channel
= rtlphy
->current_channel
;
1982 u8 rate
= rtldm
->tx_rate
;
1984 if (1 <= channel
&& channel
<= 14) {
1985 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate
)) {
1986 *up_a
= rtl8821ae_delta_swing_table_idx_24gccka_p
;
1987 *down_a
= rtl8821ae_delta_swing_table_idx_24gccka_n
;
1988 *up_b
= rtl8821ae_delta_swing_table_idx_24gcckb_p
;
1989 *down_b
= rtl8821ae_delta_swing_table_idx_24gcckb_n
;
1991 *up_a
= rtl8821ae_delta_swing_table_idx_24ga_p
;
1992 *down_a
= rtl8821ae_delta_swing_table_idx_24ga_n
;
1993 *up_b
= rtl8821ae_delta_swing_table_idx_24gb_p
;
1994 *down_b
= rtl8821ae_delta_swing_table_idx_24gb_n
;
1996 } else if (36 <= channel
&& channel
<= 64) {
1997 *up_a
= rtl8821ae_delta_swing_table_idx_5ga_p
[0];
1998 *down_a
= rtl8821ae_delta_swing_table_idx_5ga_n
[0];
1999 *up_b
= rtl8821ae_delta_swing_table_idx_5gb_p
[0];
2000 *down_b
= rtl8821ae_delta_swing_table_idx_5gb_n
[0];
2001 } else if (100 <= channel
&& channel
<= 140) {
2002 *up_a
= rtl8821ae_delta_swing_table_idx_5ga_p
[1];
2003 *down_a
= rtl8821ae_delta_swing_table_idx_5ga_n
[1];
2004 *up_b
= rtl8821ae_delta_swing_table_idx_5gb_p
[1];
2005 *down_b
= rtl8821ae_delta_swing_table_idx_5gb_n
[1];
2006 } else if (149 <= channel
&& channel
<= 173) {
2007 *up_a
= rtl8821ae_delta_swing_table_idx_5ga_p
[2];
2008 *down_a
= rtl8821ae_delta_swing_table_idx_5ga_n
[2];
2009 *up_b
= rtl8821ae_delta_swing_table_idx_5gb_p
[2];
2010 *down_b
= rtl8821ae_delta_swing_table_idx_5gb_n
[2];
2012 *up_a
= (u8
*)rtl8818e_delta_swing_table_idx_24gb_p
;
2013 *down_a
= (u8
*)rtl8818e_delta_swing_table_idx_24gb_n
;
2014 *up_b
= (u8
*)rtl8818e_delta_swing_table_idx_24gb_p
;
2015 *down_b
= (u8
*)rtl8818e_delta_swing_table_idx_24gb_n
;
2020 /*-----------------------------------------------------------------------------
2021 * Function: odm_TxPwrTrackSetPwr88E()
2023 * Overview: 88E change all channel tx power accordign to flag.
2024 * OFDM & CCK are all different.
2034 * 04/23/2012 MHC Create Version 0.
2036 *---------------------------------------------------------------------------
2038 void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw
*hw
,
2039 enum pwr_track_control_method method
,
2040 u8 rf_path
, u8 channel_mapped_index
)
2042 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2043 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
2044 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
2045 u32 final_swing_idx
[1];
2046 u8 pwr_tracking_limit
= 26; /*+1.0dB*/
2048 char final_ofdm_swing_index
= 0;
2050 if (rtldm
->tx_rate
!= 0xFF)
2051 tx_rate
= rtl8821ae_hw_rate_to_mrate(hw
, rtldm
->tx_rate
);
2053 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
, "===>%s\n", __func__
);
2055 if (tx_rate
!= 0xFF) { /* Mimic Modify High Rate BBSwing Limit.*/
2057 if ((tx_rate
>= MGN_1M
) && (tx_rate
<= MGN_11M
))
2058 pwr_tracking_limit
= 32; /*+4dB*/
2060 else if ((tx_rate
>= MGN_6M
) && (tx_rate
<= MGN_48M
))
2061 pwr_tracking_limit
= 30; /*+3dB*/
2062 else if (tx_rate
== MGN_54M
)
2063 pwr_tracking_limit
= 28; /*+2dB*/
2066 else if ((tx_rate
>= MGN_MCS0
) && (tx_rate
<= MGN_MCS2
))
2067 pwr_tracking_limit
= 34; /*+5dB*/
2069 else if ((tx_rate
>= MGN_MCS3
) && (tx_rate
<= MGN_MCS4
))
2070 pwr_tracking_limit
= 30; /*+3dB*/
2072 else if ((tx_rate
>= MGN_MCS5
) && (tx_rate
<= MGN_MCS7
))
2073 pwr_tracking_limit
= 28; /*+2dB*/
2076 else if ((tx_rate
>= MGN_VHT1SS_MCS0
) &&
2077 (tx_rate
<= MGN_VHT1SS_MCS2
))
2078 pwr_tracking_limit
= 34; /*+5dB*/
2080 else if ((tx_rate
>= MGN_VHT1SS_MCS3
) &&
2081 (tx_rate
<= MGN_VHT1SS_MCS4
))
2082 pwr_tracking_limit
= 30; /*+3dB*/
2084 else if ((tx_rate
>= MGN_VHT1SS_MCS5
) &&
2085 (tx_rate
<= MGN_VHT1SS_MCS6
))
2086 pwr_tracking_limit
= 28; /*+2dB*/
2087 else if (tx_rate
== MGN_VHT1SS_MCS7
) /*64QAM*/
2088 pwr_tracking_limit
= 26; /*+1dB*/
2089 else if (tx_rate
== MGN_VHT1SS_MCS8
) /*256QAM*/
2090 pwr_tracking_limit
= 24; /*+0dB*/
2091 else if (tx_rate
== MGN_VHT1SS_MCS9
) /*256QAM*/
2092 pwr_tracking_limit
= 22; /*-1dB*/
2094 pwr_tracking_limit
= 24;
2096 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2097 "TxRate=0x%x, PwrTrackingLimit=%d\n",
2098 tx_rate
, pwr_tracking_limit
);
2100 if (method
== BBSWING
) {
2101 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2102 "===>%s\n", __func__
);
2103 if (rf_path
== RF90_PATH_A
) {
2104 final_swing_idx
[RF90_PATH_A
] =
2105 (rtldm
->ofdm_index
[RF90_PATH_A
] >
2106 pwr_tracking_limit
) ?
2107 pwr_tracking_limit
:
2108 rtldm
->ofdm_index
[RF90_PATH_A
];
2109 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2110 "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
2111 rtldm
->ofdm_index
[RF90_PATH_A
],
2112 final_swing_idx
[RF90_PATH_A
]);
2114 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
2115 txscaling_tbl
[final_swing_idx
[RF90_PATH_A
]]);
2117 } else if (method
== MIX_MODE
) {
2118 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2119 "pDM_Odm->DefaultOfdmIndex=%d,pDM_Odm->Aboslute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
2120 rtldm
->default_ofdm_index
,
2121 rtldm
->absolute_ofdm_swing_idx
[rf_path
],
2124 final_ofdm_swing_index
=
2125 rtldm
->default_ofdm_index
+
2126 rtldm
->absolute_ofdm_swing_idx
[rf_path
];
2127 /*BBSwing higher then Limit*/
2128 if (rf_path
== RF90_PATH_A
) {
2129 if (final_ofdm_swing_index
> pwr_tracking_limit
) {
2130 rtldm
->remnant_cck_idx
=
2131 final_ofdm_swing_index
-
2133 /* CCK Follow the same compensate value as Path A*/
2134 rtldm
->remnant_ofdm_swing_idx
[rf_path
] =
2135 final_ofdm_swing_index
-
2138 rtl_set_bbreg(hw
, RA_TXSCALE
,
2140 txscaling_tbl
[pwr_tracking_limit
]);
2142 rtldm
->modify_txagc_flag_path_a
= true;
2144 /*Set TxAGC Page C{};*/
2145 rtl8821ae_phy_set_txpower_level_by_path(hw
,
2146 rtlphy
->current_channel
,
2149 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2150 " ******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
2152 rtldm
->remnant_ofdm_swing_idx
[rf_path
]);
2153 } else if (final_ofdm_swing_index
< 0) {
2154 rtldm
->remnant_cck_idx
= final_ofdm_swing_index
;
2155 /* CCK Follow the same compensate value as Path A*/
2156 rtldm
->remnant_ofdm_swing_idx
[rf_path
] =
2157 final_ofdm_swing_index
;
2159 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
2162 rtldm
->modify_txagc_flag_path_a
= true;
2164 /*Set TxAGC Page C{};*/
2165 rtl8821ae_phy_set_txpower_level_by_path(hw
,
2166 rtlphy
->current_channel
, RF90_PATH_A
);
2168 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2169 "******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n",
2170 rtldm
->remnant_ofdm_swing_idx
[rf_path
]);
2172 rtl_set_bbreg(hw
, RA_TXSCALE
, 0xFFE00000,
2173 txscaling_tbl
[(u8
)final_ofdm_swing_index
]);
2175 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2176 "******Path_A Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n",
2177 final_ofdm_swing_index
);
2178 /*If TxAGC has changed, reset TxAGC again*/
2179 if (rtldm
->modify_txagc_flag_path_a
) {
2180 rtldm
->remnant_cck_idx
= 0;
2181 rtldm
->remnant_ofdm_swing_idx
[rf_path
] = 0;
2183 /*Set TxAGC Page C{};*/
2184 rtl8821ae_phy_set_txpower_level_by_path(hw
,
2185 rtlphy
->current_channel
, RF90_PATH_A
);
2187 rtldm
->modify_txagc_flag_path_a
= false;
2189 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
,
2191 "******Path_A pDM_Odm->Modify_TxAGC_Flag= FALSE\n");
2200 void rtl8821ae_dm_txpower_tracking_callback_thermalmeter(
2201 struct ieee80211_hw
*hw
)
2203 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2204 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
2205 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
2206 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
2207 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
2209 u8 thermal_value
= 0, delta
, delta_lck
, delta_iqk
, p
= 0, i
= 0;
2210 u8 thermal_value_avg_count
= 0;
2211 u32 thermal_value_avg
= 0;
2213 u8 ofdm_min_index
= 6; /*OFDM BB Swing should be less than +3.0dB */
2214 /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
2215 u8 index_for_channel
= 0;
2217 /* 1. The following TWO tables decide the final
2218 * index of OFDM/CCK swing table.
2220 u8
*delta_swing_table_idx_tup_a
;
2221 u8
*delta_swing_table_idx_tdown_a
;
2222 u8
*delta_swing_table_idx_tup_b
;
2223 u8
*delta_swing_table_idx_tdown_b
;
2225 /*2. Initilization ( 7 steps in total )*/
2226 rtl8821ae_get_delta_swing_table(hw
, (u8
**)&delta_swing_table_idx_tup_a
,
2227 (u8
**)&delta_swing_table_idx_tdown_a
,
2228 (u8
**)&delta_swing_table_idx_tup_b
,
2229 (u8
**)&delta_swing_table_idx_tdown_b
);
2231 rtldm
->txpower_trackinginit
= true;
2233 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2234 "===>%s,\n pDM_Odm->BbSwingIdxCckBase: %d,pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n",
2236 rtldm
->swing_idx_cck_base
,
2237 rtldm
->swing_idx_ofdm_base
[RF90_PATH_A
],
2238 rtldm
->default_ofdm_index
);
2239 /*0x42: RF Reg[15:10] 88E*/
2240 thermal_value
= (u8
)rtl_get_rfreg(hw
,
2241 RF90_PATH_A
, RF_T_METER_8812A
, 0xfc00);
2242 if (!rtldm
->txpower_track_control
||
2243 rtlefuse
->eeprom_thermalmeter
== 0 ||
2244 rtlefuse
->eeprom_thermalmeter
== 0xFF)
2247 /* 3. Initialize ThermalValues of RFCalibrateInfo*/
2249 if (rtlhal
->reloadtxpowerindex
) {
2250 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2251 "reload ofdm index for band switch\n");
2254 /*4. Calculate average thermal meter*/
2255 rtldm
->thermalvalue_avg
[rtldm
->thermalvalue_avg_index
] = thermal_value
;
2256 rtldm
->thermalvalue_avg_index
++;
2257 if (rtldm
->thermalvalue_avg_index
== AVG_THERMAL_NUM_8812A
)
2258 /*Average times = c.AverageThermalNum*/
2259 rtldm
->thermalvalue_avg_index
= 0;
2261 for (i
= 0; i
< AVG_THERMAL_NUM_8812A
; i
++) {
2262 if (rtldm
->thermalvalue_avg
[i
]) {
2263 thermal_value_avg
+= rtldm
->thermalvalue_avg
[i
];
2264 thermal_value_avg_count
++;
2267 /*Calculate Average ThermalValue after average enough times*/
2268 if (thermal_value_avg_count
) {
2269 thermal_value
= (u8
)(thermal_value_avg
/
2270 thermal_value_avg_count
);
2271 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2272 "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
2273 thermal_value
, rtlefuse
->eeprom_thermalmeter
);
2276 /*5. Calculate delta, delta_LCK, delta_IQK.
2277 *"delta" here is used to determine whether
2278 * thermal value changes or not.
2280 delta
= (thermal_value
> rtldm
->thermalvalue
) ?
2281 (thermal_value
- rtldm
->thermalvalue
) :
2282 (rtldm
->thermalvalue
- thermal_value
);
2283 delta_lck
= (thermal_value
> rtldm
->thermalvalue_lck
) ?
2284 (thermal_value
- rtldm
->thermalvalue_lck
) :
2285 (rtldm
->thermalvalue_lck
- thermal_value
);
2286 delta_iqk
= (thermal_value
> rtldm
->thermalvalue_iqk
) ?
2287 (thermal_value
- rtldm
->thermalvalue_iqk
) :
2288 (rtldm
->thermalvalue_iqk
- thermal_value
);
2290 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2291 "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
2292 delta
, delta_lck
, delta_iqk
);
2294 /* 6. If necessary, do LCK. */
2295 /*Delta temperature is equal to or larger than 20 centigrade.*/
2296 if (delta_lck
>= IQK_THRESHOLD
) {
2297 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2298 "delta_LCK(%d) >= Threshold_IQK(%d)\n",
2299 delta_lck
, IQK_THRESHOLD
);
2300 rtldm
->thermalvalue_lck
= thermal_value
;
2301 rtl8821ae_phy_lc_calibrate(hw
);
2304 /*7. If necessary, move the index of swing table to adjust Tx power.*/
2306 if (delta
> 0 && rtldm
->txpower_track_control
) {
2307 /*"delta" here is used to record the
2308 * absolute value of differrence.
2310 delta
= thermal_value
> rtlefuse
->eeprom_thermalmeter
?
2311 (thermal_value
- rtlefuse
->eeprom_thermalmeter
) :
2312 (rtlefuse
->eeprom_thermalmeter
- thermal_value
);
2314 if (delta
>= TXSCALE_TABLE_SIZE
)
2315 delta
= TXSCALE_TABLE_SIZE
- 1;
2317 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
2319 if (thermal_value
> rtlefuse
->eeprom_thermalmeter
) {
2320 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2321 "delta_swing_table_idx_tup_a[%d] = %d\n",
2322 delta
, delta_swing_table_idx_tup_a
[delta
]);
2323 rtldm
->delta_power_index_last
[RF90_PATH_A
] =
2324 rtldm
->delta_power_index
[RF90_PATH_A
];
2325 rtldm
->delta_power_index
[RF90_PATH_A
] =
2326 delta_swing_table_idx_tup_a
[delta
];
2328 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_A
] =
2329 delta_swing_table_idx_tup_a
[delta
];
2330 /*Record delta swing for mix mode power tracking*/
2332 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2333 "******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
2334 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_A
]);
2336 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2337 "delta_swing_table_idx_tdown_a[%d] = %d\n",
2338 delta
, delta_swing_table_idx_tdown_a
[delta
]);
2340 rtldm
->delta_power_index_last
[RF90_PATH_A
] =
2341 rtldm
->delta_power_index
[RF90_PATH_A
];
2342 rtldm
->delta_power_index
[RF90_PATH_A
] =
2343 -1 * delta_swing_table_idx_tdown_a
[delta
];
2345 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_A
] =
2346 -1 * delta_swing_table_idx_tdown_a
[delta
];
2347 /* Record delta swing for mix mode power tracking*/
2348 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2349 "******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
2350 rtldm
->absolute_ofdm_swing_idx
[RF90_PATH_A
]);
2353 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8821A
; p
++) {
2354 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2355 "\n\n================================ [Path-%c]Calculating PowerIndexOffset ================================\n",
2356 (p
== RF90_PATH_A
? 'A' : 'B'));
2357 /*If Thermal value changes but lookup table value
2360 if (rtldm
->delta_power_index
[p
] ==
2361 rtldm
->delta_power_index_last
[p
])
2363 rtldm
->power_index_offset
[p
] = 0;
2365 rtldm
->power_index_offset
[p
] =
2366 rtldm
->delta_power_index
[p
] -
2367 rtldm
->delta_power_index_last
[p
];
2368 /*Power Index Diff between 2 times Power Tracking*/
2370 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2371 "[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n",
2372 (p
== RF90_PATH_A
? 'A' : 'B'),
2373 rtldm
->power_index_offset
[p
],
2374 rtldm
->delta_power_index
[p
] ,
2375 rtldm
->delta_power_index_last
[p
]);
2377 rtldm
->ofdm_index
[p
] =
2378 rtldm
->swing_idx_ofdm_base
[p
] +
2379 rtldm
->power_index_offset
[p
];
2381 rtldm
->swing_idx_cck_base
+
2382 rtldm
->power_index_offset
[p
];
2384 rtldm
->swing_idx_cck
= rtldm
->cck_index
;
2385 rtldm
->swing_idx_ofdm
[p
] = rtldm
->ofdm_index
[p
];
2387 /*********Print BB Swing Base and Index Offset********/
2389 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2390 "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
2391 rtldm
->swing_idx_cck
,
2392 rtldm
->swing_idx_cck_base
,
2393 rtldm
->power_index_offset
[p
]);
2394 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2395 "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
2396 rtldm
->swing_idx_ofdm
[p
],
2397 (p
== RF90_PATH_A
? 'A' : 'B'),
2398 rtldm
->swing_idx_ofdm_base
[p
],
2399 rtldm
->power_index_offset
[p
]);
2401 /*7.1 Handle boundary conditions of index.*/
2403 if (rtldm
->ofdm_index
[p
] > TXSCALE_TABLE_SIZE
- 1)
2404 rtldm
->ofdm_index
[p
] = TXSCALE_TABLE_SIZE
- 1;
2405 else if (rtldm
->ofdm_index
[p
] < ofdm_min_index
)
2406 rtldm
->ofdm_index
[p
] = ofdm_min_index
;
2408 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2409 "\n\n========================================================================================================\n");
2410 if (rtldm
->cck_index
> TXSCALE_TABLE_SIZE
- 1)
2411 rtldm
->cck_index
= TXSCALE_TABLE_SIZE
- 1;
2412 else if (rtldm
->cck_index
< 0)
2413 rtldm
->cck_index
= 0;
2415 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2416 "The thermal meter is unchanged or TxPowerTracking OFF(%d):ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
2417 rtldm
->txpower_track_control
,
2419 rtldm
->thermalvalue
);
2421 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8821A
; p
++)
2422 rtldm
->power_index_offset
[p
] = 0;
2424 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2425 "TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
2426 /*Print Swing base & current*/
2427 rtldm
->cck_index
, rtldm
->swing_idx_cck_base
);
2428 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8821A
; p
++) {
2429 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2430 "TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n",
2431 rtldm
->ofdm_index
[p
],
2432 (p
== RF90_PATH_A
? 'A' : 'B'),
2433 rtldm
->swing_idx_ofdm_base
[p
]);
2436 if ((rtldm
->power_index_offset
[RF90_PATH_A
] != 0 ||
2437 rtldm
->power_index_offset
[RF90_PATH_B
] != 0) &&
2438 rtldm
->txpower_track_control
) {
2439 /*7.2 Configure the Swing Table to adjust Tx Power.*/
2440 /*Always TRUE after Tx Power is adjusted by power tracking.*/
2442 * 2012/04/23 MH According to Luke's suggestion,
2443 * we can not write BB digital
2444 * to increase TX power. Otherwise, EVM will be bad.
2446 * 2012/04/25 MH Add for tx power tracking to
2447 * set tx power in tx agc for 88E.
2449 if (thermal_value
> rtldm
->thermalvalue
) {
2450 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2451 "Temperature Increasing(A): delta_pi: %d , delta_t: %d,Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
2452 rtldm
->power_index_offset
[RF90_PATH_A
],
2453 delta
, thermal_value
,
2454 rtlefuse
->eeprom_thermalmeter
,
2455 rtldm
->thermalvalue
);
2456 } else if (thermal_value
< rtldm
->thermalvalue
) { /*Low temperature*/
2457 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2458 "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
2459 rtldm
->power_index_offset
[RF90_PATH_A
],
2460 delta
, thermal_value
,
2461 rtlefuse
->eeprom_thermalmeter
,
2462 rtldm
->thermalvalue
);
2465 if (thermal_value
> rtlefuse
->eeprom_thermalmeter
) {
2466 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2467 "Temperature(%d) higher than PG value(%d)\n",
2468 thermal_value
, rtlefuse
->eeprom_thermalmeter
);
2470 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2471 "****Enter POWER Tracking MIX_MODE****\n");
2472 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8821A
; p
++)
2473 rtl8821ae_dm_txpwr_track_set_pwr(hw
,
2474 MIX_MODE
, p
, index_for_channel
);
2476 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2477 "Temperature(%d) lower than PG value(%d)\n",
2478 thermal_value
, rtlefuse
->eeprom_thermalmeter
);
2480 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2481 "*****Enter POWER Tracking MIX_MODE*****\n");
2482 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8821A
; p
++)
2483 rtl8812ae_dm_txpwr_track_set_pwr(hw
,
2484 MIX_MODE
, p
, index_for_channel
);
2486 /*Record last time Power Tracking result as base.*/
2487 rtldm
->swing_idx_cck_base
= rtldm
->swing_idx_cck
;
2488 for (p
= RF90_PATH_A
; p
< MAX_PATH_NUM_8821A
; p
++)
2489 rtldm
->swing_idx_ofdm_base
[p
] = rtldm
->swing_idx_ofdm
[p
];
2491 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2492 "pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
2493 rtldm
->thermalvalue
, thermal_value
);
2494 /*Record last Power Tracking Thermal Value*/
2495 rtldm
->thermalvalue
= thermal_value
;
2497 /* Delta temperature is equal to or larger than
2498 * 20 centigrade (When threshold is 8).
2500 if (delta_iqk
>= IQK_THRESHOLD
) {
2501 if (!rtlphy
->lck_inprogress
) {
2502 spin_lock(&rtlpriv
->locks
.iqk_lock
);
2503 rtlphy
->lck_inprogress
= true;
2504 spin_unlock(&rtlpriv
->locks
.iqk_lock
);
2506 rtl8821ae_do_iqk(hw
, delta_iqk
, thermal_value
, 8);
2508 spin_lock(&rtlpriv
->locks
.iqk_lock
);
2509 rtlphy
->lck_inprogress
= false;
2510 spin_unlock(&rtlpriv
->locks
.iqk_lock
);
2514 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
, "<===%s\n", __func__
);
2517 void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw
*hw
)
2519 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2520 if (!rtlpriv
->dm
.tm_trigger
) {
2521 rtl_set_rfreg(hw
, RF90_PATH_A
, RF_T_METER_88E
, BIT(17)|BIT(16),
2523 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2524 "Trigger 8821ae Thermal Meter!!\n");
2525 rtlpriv
->dm
.tm_trigger
= 1;
2528 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
2529 "Schedule TxPowerTracking !!\n");
2531 rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw
);
2532 rtlpriv
->dm
.tm_trigger
= 0;
2536 static void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw
*hw
)
2538 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2539 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
2540 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
2541 struct rate_adaptive
*p_ra
= &rtlpriv
->ra
;
2542 u32 low_rssithresh_for_ra
= p_ra
->low2high_rssi_thresh_for_ra40m
;
2543 u32 high_rssithresh_for_ra
= p_ra
->high_rssi_thresh_for_ra
;
2545 struct ieee80211_sta
*sta
= NULL
;
2547 if (is_hal_stop(rtlhal
)) {
2548 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
2549 "driver is going to unload\n");
2553 if (!rtlpriv
->dm
.useramask
) {
2554 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
2555 "driver does not control rate adaptive mask\n");
2559 if (mac
->link_state
== MAC80211_LINKED
&&
2560 mac
->opmode
== NL80211_IFTYPE_STATION
) {
2561 switch (p_ra
->pre_ratr_state
) {
2562 case DM_RATR_STA_MIDDLE
:
2563 high_rssithresh_for_ra
+= go_up_gap
;
2565 case DM_RATR_STA_LOW
:
2566 high_rssithresh_for_ra
+= go_up_gap
;
2567 low_rssithresh_for_ra
+= go_up_gap
;
2573 if (rtlpriv
->dm
.undec_sm_pwdb
>
2574 (long)high_rssithresh_for_ra
)
2575 p_ra
->ratr_state
= DM_RATR_STA_HIGH
;
2576 else if (rtlpriv
->dm
.undec_sm_pwdb
>
2577 (long)low_rssithresh_for_ra
)
2578 p_ra
->ratr_state
= DM_RATR_STA_MIDDLE
;
2580 p_ra
->ratr_state
= DM_RATR_STA_LOW
;
2582 if (p_ra
->pre_ratr_state
!= p_ra
->ratr_state
) {
2583 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
2585 rtlpriv
->dm
.undec_sm_pwdb
);
2586 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
2587 "RSSI_LEVEL = %d\n", p_ra
->ratr_state
);
2588 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
2589 "PreState = %d, CurState = %d\n",
2590 p_ra
->pre_ratr_state
, p_ra
->ratr_state
);
2593 sta
= rtl_find_sta(hw
, mac
->bssid
);
2595 rtlpriv
->cfg
->ops
->update_rate_tbl(hw
,
2596 sta
, p_ra
->ratr_state
);
2599 p_ra
->pre_ratr_state
= p_ra
->ratr_state
;
2604 static void rtl8821ae_dm_refresh_basic_rate_mask(struct ieee80211_hw
*hw
)
2606 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2607 struct dig_t
*dm_digtable
= &rtlpriv
->dm_digtable
;
2608 struct rtl_mac
*mac
= &rtlpriv
->mac80211
;
2611 u16 basic_rate
= RRSR_1M
| RRSR_2M
| RRSR_5_5M
| RRSR_11M
| RRSR_6M
;
2613 if (mac
->link_state
< MAC80211_LINKED
)
2615 else if (dm_digtable
->rssi_val_min
< 25)
2617 else if (dm_digtable
->rssi_val_min
> 30)
2622 if (cur_stage
!= stage
) {
2623 if (cur_stage
== 1) {
2624 basic_rate
&= (!(basic_rate
^ mac
->basic_rates
));
2625 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
2626 HW_VAR_BASIC_RATE
, (u8
*)&basic_rate
);
2627 } else if (cur_stage
== 3 && (stage
== 1 || stage
== 2)) {
2628 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
2629 HW_VAR_BASIC_RATE
, (u8
*)&mac
->basic_rates
);
2635 static void rtl8821ae_dm_edca_choose_traffic_idx(
2636 struct ieee80211_hw
*hw
, u64 cur_tx_bytes
,
2637 u64 cur_rx_bytes
, bool b_bias_on_rx
,
2638 bool *pb_is_cur_rdl_state
)
2640 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2643 if (cur_tx_bytes
> (cur_rx_bytes
*4)) {
2644 *pb_is_cur_rdl_state
= false;
2645 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2646 "Uplink Traffic\n ");
2648 *pb_is_cur_rdl_state
= true;
2649 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2650 "Balance Traffic\n");
2653 if (cur_rx_bytes
> (cur_tx_bytes
*4)) {
2654 *pb_is_cur_rdl_state
= true;
2655 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2656 "Downlink Traffic\n");
2658 *pb_is_cur_rdl_state
= false;
2659 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2660 "Balance Traffic\n");
2666 static void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw
*hw
)
2668 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2669 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
2670 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
2672 /*Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.*/
2673 u64 cur_tx_ok_cnt
= 0;
2674 u64 cur_rx_ok_cnt
= 0;
2675 u32 edca_be_ul
= 0x5ea42b;
2676 u32 edca_be_dl
= 0x5ea42b;
2677 u32 edca_be
= 0x5ea42b;
2679 bool *pb_is_cur_rdl_state
= NULL
;
2680 bool b_last_is_cur_rdl_state
= false;
2681 bool b_bias_on_rx
= false;
2682 bool b_edca_turbo_on
= false;
2684 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2685 "rtl8821ae_dm_check_edca_turbo=====>");
2686 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2687 "Orginial BE PARAM: 0x%x\n",
2688 rtl_read_dword(rtlpriv
, DM_REG_EDCA_BE_11N
));
2690 if (rtlpriv
->dm
.dbginfo
.num_non_be_pkt
> 0x100)
2691 rtlpriv
->dm
.is_any_nonbepkts
= true;
2692 rtlpriv
->dm
.dbginfo
.num_non_be_pkt
= 0;
2694 /*===============================
2695 * list paramter for different platform
2696 *===============================
2698 b_last_is_cur_rdl_state
= rtlpriv
->dm
.is_cur_rdlstate
;
2699 pb_is_cur_rdl_state
= &rtlpriv
->dm
.is_cur_rdlstate
;
2701 cur_tx_ok_cnt
= rtlpriv
->stats
.txbytesunicast
- rtldm
->last_tx_ok_cnt
;
2702 cur_rx_ok_cnt
= rtlpriv
->stats
.rxbytesunicast
- rtldm
->last_rx_ok_cnt
;
2704 rtldm
->last_tx_ok_cnt
= rtlpriv
->stats
.txbytesunicast
;
2705 rtldm
->last_rx_ok_cnt
= rtlpriv
->stats
.rxbytesunicast
;
2707 iot_peer
= rtlpriv
->mac80211
.vendor
;
2708 b_bias_on_rx
= false;
2709 b_edca_turbo_on
= ((!rtlpriv
->dm
.is_any_nonbepkts
) &&
2710 (!rtlpriv
->dm
.disable_framebursting
)) ?
2713 if (rtlpriv
->rtlhal
.hw_type
!= HARDWARE_TYPE_RTL8812AE
) {
2714 if ((iot_peer
== PEER_CISCO
) &&
2715 (mac
->mode
== WIRELESS_MODE_N_24G
)) {
2716 edca_be_dl
= edca_setting_dl
[iot_peer
];
2717 edca_be_ul
= edca_setting_ul
[iot_peer
];
2721 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2722 "bIsAnyNonBEPkts : 0x%x bDisableFrameBursting : 0x%x\n",
2723 rtlpriv
->dm
.is_any_nonbepkts
,
2724 rtlpriv
->dm
.disable_framebursting
);
2726 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2727 "bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n",
2728 b_edca_turbo_on
, b_bias_on_rx
);
2730 if (b_edca_turbo_on
) {
2731 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2732 "curTxOkCnt : 0x%llx\n", cur_tx_ok_cnt
);
2733 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2734 "curRxOkCnt : 0x%llx\n", cur_rx_ok_cnt
);
2736 rtl8821ae_dm_edca_choose_traffic_idx(hw
, cur_tx_ok_cnt
,
2737 cur_rx_ok_cnt
, true, pb_is_cur_rdl_state
);
2739 rtl8821ae_dm_edca_choose_traffic_idx(hw
, cur_tx_ok_cnt
,
2740 cur_rx_ok_cnt
, false, pb_is_cur_rdl_state
);
2742 edca_be
= (*pb_is_cur_rdl_state
) ? edca_be_dl
: edca_be_ul
;
2744 rtl_write_dword(rtlpriv
, DM_REG_EDCA_BE_11N
, edca_be
);
2746 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2747 "EDCA Turbo on: EDCA_BE:0x%x\n", edca_be
);
2749 rtlpriv
->dm
.current_turbo_edca
= true;
2751 RT_TRACE(rtlpriv
, COMP_TURBO
, DBG_LOUD
,
2752 "EDCA_BE_DL : 0x%x EDCA_BE_UL : 0x%x EDCA_BE : 0x%x\n",
2753 edca_be_dl
, edca_be_ul
, edca_be
);
2755 if (rtlpriv
->dm
.current_turbo_edca
) {
2757 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_AC_PARAM
,
2760 rtlpriv
->dm
.current_turbo_edca
= false;
2763 rtlpriv
->dm
.is_any_nonbepkts
= false;
2764 rtldm
->last_tx_ok_cnt
= rtlpriv
->stats
.txbytesunicast
;
2765 rtldm
->last_rx_ok_cnt
= rtlpriv
->stats
.rxbytesunicast
;
2768 static void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw
*hw
)
2770 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2771 struct dig_t
*dm_digtable
= &rtlpriv
->dm_digtable
;
2772 u8 cur_cck_cca_thresh
;
2774 if (rtlpriv
->mac80211
.link_state
>= MAC80211_LINKED
) {
2775 if (dm_digtable
->rssi_val_min
> 25) {
2776 cur_cck_cca_thresh
= 0xcd;
2777 } else if ((dm_digtable
->rssi_val_min
<= 25) &&
2778 (dm_digtable
->rssi_val_min
> 10)) {
2779 cur_cck_cca_thresh
= 0x83;
2781 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
2782 cur_cck_cca_thresh
= 0x83;
2784 cur_cck_cca_thresh
= 0x40;
2787 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
2788 cur_cck_cca_thresh
= 0x83;
2790 cur_cck_cca_thresh
= 0x40;
2793 if (dm_digtable
->cur_cck_cca_thres
!= cur_cck_cca_thresh
)
2794 rtl_write_byte(rtlpriv
, ODM_REG_CCK_CCA_11AC
,
2795 cur_cck_cca_thresh
);
2797 dm_digtable
->pre_cck_cca_thres
= dm_digtable
->cur_cck_cca_thres
;
2798 dm_digtable
->cur_cck_cca_thres
= cur_cck_cca_thresh
;
2799 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_TRACE
,
2800 "CCK cca thresh hold =%x\n", dm_digtable
->cur_cck_cca_thres
);
2803 static void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw
*hw
)
2805 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2806 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
2809 int cfo_khz_a
, cfo_khz_b
, cfo_ave
= 0, adjust_xtal
= 0;
2812 if (rtlpriv
->mac80211
.link_state
< MAC80211_LINKED
) {
2814 if (rtldm
->atc_status
== ATC_STATUS_OFF
) {
2815 rtl_set_bbreg(hw
, RFC_AREA
, BIT(14), ATC_STATUS_ON
);
2816 rtldm
->atc_status
= ATC_STATUS_ON
;
2819 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
, "No link!!\n");
2820 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
2821 "atc_status = %d\n", rtldm
->atc_status
);
2823 if (rtldm
->crystal_cap
!= rtlpriv
->efuse
.crystalcap
) {
2824 rtldm
->crystal_cap
= rtlpriv
->efuse
.crystalcap
;
2825 crystal_cap
= rtldm
->crystal_cap
& 0x3f;
2826 crystal_cap
= crystal_cap
& 0x3f;
2827 if (rtlpriv
->rtlhal
.hw_type
== HARDWARE_TYPE_RTL8812AE
)
2828 rtl_set_bbreg(hw
, REG_MAC_PHY_CTRL
,
2829 0x7ff80000, (crystal_cap
|
2830 (crystal_cap
<< 6)));
2832 rtl_set_bbreg(hw
, REG_MAC_PHY_CTRL
,
2833 0xfff000, (crystal_cap
|
2834 (crystal_cap
<< 6)));
2836 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
, "crystal_cap = 0x%x\n",
2837 rtldm
->crystal_cap
);
2839 /*1. Calculate CFO for path-A & path-B*/
2840 cfo_khz_a
= (int)(rtldm
->cfo_tail
[0] * 3125) / 1280;
2841 cfo_khz_b
= (int)(rtldm
->cfo_tail
[1] * 3125) / 1280;
2842 packet_count
= rtldm
->packet_count
;
2845 if (packet_count
== rtldm
->packet_count_pre
) {
2846 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
2847 "packet counter doesn't change\n");
2851 rtldm
->packet_count_pre
= packet_count
;
2852 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
2853 "packet counter = %d\n",
2854 rtldm
->packet_count
);
2857 if (rtlpriv
->phy
.rf_type
== RF_1T1R
)
2858 cfo_ave
= cfo_khz_a
;
2860 cfo_ave
= (cfo_khz_a
+ cfo_khz_b
) >> 1;
2862 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
2863 "cfo_khz_a = %dkHz, cfo_khz_b = %dkHz, cfo_ave = %dkHz\n",
2864 cfo_khz_a
, cfo_khz_b
, cfo_ave
);
2866 /*4.Avoid abnormal large CFO*/
2867 cfo_ave_diff
= (rtldm
->cfo_ave_pre
>= cfo_ave
) ?
2868 (rtldm
->cfo_ave_pre
- cfo_ave
) :
2869 (cfo_ave
- rtldm
->cfo_ave_pre
);
2871 if (cfo_ave_diff
> 20 && rtldm
->large_cfo_hit
== 0) {
2872 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
2873 "first large CFO hit\n");
2874 rtldm
->large_cfo_hit
= 1;
2877 rtldm
->large_cfo_hit
= 0;
2879 rtldm
->cfo_ave_pre
= cfo_ave
;
2881 /*CFO tracking by adjusting Xtal cap.*/
2883 /*1.Dynamic Xtal threshold*/
2884 if (cfo_ave
>= -rtldm
->cfo_threshold
&&
2885 cfo_ave
<= rtldm
->cfo_threshold
&&
2886 rtldm
->is_freeze
== 0) {
2887 if (rtldm
->cfo_threshold
== CFO_THRESHOLD_XTAL
) {
2888 rtldm
->cfo_threshold
= CFO_THRESHOLD_XTAL
+ 10;
2889 rtldm
->is_freeze
= 1;
2891 rtldm
->cfo_threshold
= CFO_THRESHOLD_XTAL
;
2894 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
2895 "Dynamic threshold = %d\n",
2896 rtldm
->cfo_threshold
);
2898 /* 2.Calculate Xtal offset*/
2899 if (cfo_ave
> rtldm
->cfo_threshold
&& rtldm
->crystal_cap
< 0x3f)
2900 adjust_xtal
= ((cfo_ave
- CFO_THRESHOLD_XTAL
) >> 2) + 1;
2901 else if ((cfo_ave
< -rtlpriv
->dm
.cfo_threshold
) &&
2902 rtlpriv
->dm
.crystal_cap
> 0)
2903 adjust_xtal
= ((cfo_ave
+ CFO_THRESHOLD_XTAL
) >> 2) - 1;
2904 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
2905 "Crystal cap = 0x%x, Crystal cap offset = %d\n",
2906 rtldm
->crystal_cap
, adjust_xtal
);
2908 /*3.Adjudt Crystal Cap.*/
2909 if (adjust_xtal
!= 0) {
2910 rtldm
->is_freeze
= 0;
2911 rtldm
->crystal_cap
+= adjust_xtal
;
2913 if (rtldm
->crystal_cap
> 0x3f)
2914 rtldm
->crystal_cap
= 0x3f;
2915 else if (rtldm
->crystal_cap
< 0)
2916 rtldm
->crystal_cap
= 0;
2918 crystal_cap
= rtldm
->crystal_cap
& 0x3f;
2919 crystal_cap
= crystal_cap
& 0x3f;
2920 if (rtlpriv
->rtlhal
.hw_type
== HARDWARE_TYPE_RTL8812AE
)
2921 rtl_set_bbreg(hw
, REG_MAC_PHY_CTRL
,
2922 0x7ff80000, (crystal_cap
|
2923 (crystal_cap
<< 6)));
2925 rtl_set_bbreg(hw
, REG_MAC_PHY_CTRL
,
2926 0xfff000, (crystal_cap
|
2927 (crystal_cap
<< 6)));
2928 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
2929 "New crystal cap = 0x%x\n",
2930 rtldm
->crystal_cap
);
2935 void rtl8821ae_dm_watchdog(struct ieee80211_hw
*hw
)
2937 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
2938 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
2939 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
2940 bool fw_current_inpsmode
= false;
2941 bool fw_ps_awake
= true;
2943 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FW_PSMODE_STATUS
,
2944 (u8
*)(&fw_current_inpsmode
));
2946 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FWLPS_RF_ON
,
2947 (u8
*)(&fw_ps_awake
));
2949 if (ppsc
->p2p_ps_info
.p2p_ps_mode
)
2950 fw_ps_awake
= false;
2952 if ((ppsc
->rfpwr_state
== ERFON
) &&
2953 ((!fw_current_inpsmode
) && fw_ps_awake
) &&
2954 (!ppsc
->rfchange_inprogress
)) {
2955 rtl8821ae_dm_common_info_self_update(hw
);
2956 rtl8821ae_dm_false_alarm_counter_statistics(hw
);
2957 rtl8821ae_dm_check_rssi_monitor(hw
);
2958 rtl8821ae_dm_dig(hw
);
2959 rtl8821ae_dm_cck_packet_detection_thresh(hw
);
2960 rtl8821ae_dm_refresh_rate_adaptive_mask(hw
);
2961 rtl8821ae_dm_refresh_basic_rate_mask(hw
);
2962 rtl8821ae_dm_check_edca_turbo(hw
);
2963 rtl8821ae_dm_dynamic_atc_switch(hw
);
2964 if (rtlhal
->hw_type
== HARDWARE_TYPE_RTL8812AE
)
2965 rtl8812ae_dm_check_txpower_tracking_thermalmeter(hw
);
2967 rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw
);
2968 rtl8821ae_dm_iq_calibrate(hw
);
2971 rtlpriv
->dm
.dbginfo
.num_qry_beacon_pkt
= 0;
2972 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_DMESG
, "\n");
2975 void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw
*hw
,
2976 u8
*pdesc
, u32 mac_id
)
2978 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
2979 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
2980 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
2981 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
2983 if (rtlhal
->hw_type
!= HARDWARE_TYPE_RTL8812AE
)
2986 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
2987 SET_TX_DESC_TX_ANT(pdesc
, pfat_table
->antsel_a
[mac_id
]);