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