1ffa188a65c9f21b2441338cdff1d1f595d3ea4a
[linux-2.6-microblaze.git] / drivers / net / wireless / realtek / rtlwifi / rtl8188ee / dm.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2013  Realtek Corporation.*/
3
4 #include "../wifi.h"
5 #include "../base.h"
6 #include "../pci.h"
7 #include "../core.h"
8 #include "reg.h"
9 #include "def.h"
10 #include "phy.h"
11 #include "dm.h"
12 #include "fw.h"
13 #include "trx.h"
14
15 static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
16         0x7f8001fe,             /* 0, +6.0dB */
17         0x788001e2,             /* 1, +5.5dB */
18         0x71c001c7,             /* 2, +5.0dB */
19         0x6b8001ae,             /* 3, +4.5dB */
20         0x65400195,             /* 4, +4.0dB */
21         0x5fc0017f,             /* 5, +3.5dB */
22         0x5a400169,             /* 6, +3.0dB */
23         0x55400155,             /* 7, +2.5dB */
24         0x50800142,             /* 8, +2.0dB */
25         0x4c000130,             /* 9, +1.5dB */
26         0x47c0011f,             /* 10, +1.0dB */
27         0x43c0010f,             /* 11, +0.5dB */
28         0x40000100,             /* 12, +0dB */
29         0x3c8000f2,             /* 13, -0.5dB */
30         0x390000e4,             /* 14, -1.0dB */
31         0x35c000d7,             /* 15, -1.5dB */
32         0x32c000cb,             /* 16, -2.0dB */
33         0x300000c0,             /* 17, -2.5dB */
34         0x2d4000b5,             /* 18, -3.0dB */
35         0x2ac000ab,             /* 19, -3.5dB */
36         0x288000a2,             /* 20, -4.0dB */
37         0x26000098,             /* 21, -4.5dB */
38         0x24000090,             /* 22, -5.0dB */
39         0x22000088,             /* 23, -5.5dB */
40         0x20000080,             /* 24, -6.0dB */
41         0x1e400079,             /* 25, -6.5dB */
42         0x1c800072,             /* 26, -7.0dB */
43         0x1b00006c,             /* 27. -7.5dB */
44         0x19800066,             /* 28, -8.0dB */
45         0x18000060,             /* 29, -8.5dB */
46         0x16c0005b,             /* 30, -9.0dB */
47         0x15800056,             /* 31, -9.5dB */
48         0x14400051,             /* 32, -10.0dB */
49         0x1300004c,             /* 33, -10.5dB */
50         0x12000048,             /* 34, -11.0dB */
51         0x11000044,             /* 35, -11.5dB */
52         0x10000040,             /* 36, -12.0dB */
53         0x0f00003c,             /* 37, -12.5dB */
54         0x0e400039,             /* 38, -13.0dB */
55         0x0d800036,             /* 39, -13.5dB */
56         0x0cc00033,             /* 40, -14.0dB */
57         0x0c000030,             /* 41, -14.5dB */
58         0x0b40002d,             /* 42, -15.0dB */
59 };
60
61 static const u8 cck_tbl_ch1_13[CCK_TABLE_SIZE][8] = {
62         {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},       /* 0, +0dB */
63         {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},       /* 1, -0.5dB */
64         {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},       /* 2, -1.0dB */
65         {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},       /* 3, -1.5dB */
66         {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},       /* 4, -2.0dB */
67         {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},       /* 5, -2.5dB */
68         {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},       /* 6, -3.0dB */
69         {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},       /* 7, -3.5dB */
70         {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},       /* 8, -4.0dB */
71         {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},       /* 9, -4.5dB */
72         {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},       /* 10, -5.0dB */
73         {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},       /* 11, -5.5dB */
74         {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},       /* 12, -6.0dB */
75         {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},       /* 13, -6.5dB */
76         {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},       /* 14, -7.0dB */
77         {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},       /* 15, -7.5dB */
78         {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},       /* 16, -8.0dB */
79         {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},       /* 17, -8.5dB */
80         {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},       /* 18, -9.0dB */
81         {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},       /* 19, -9.5dB */
82         {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},       /* 20, -10.0dB*/
83         {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},       /* 21, -10.5dB*/
84         {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},       /* 22, -11.0dB*/
85         {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},       /* 23, -11.5dB*/
86         {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},       /* 24, -12.0dB*/
87         {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},       /* 25, -12.5dB*/
88         {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},       /* 26, -13.0dB*/
89         {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},       /* 27, -13.5dB*/
90         {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},       /* 28, -14.0dB*/
91         {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},       /* 29, -14.5dB*/
92         {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},       /* 30, -15.0dB*/
93         {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},       /* 31, -15.5dB*/
94         {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}        /* 32, -16.0dB*/
95 };
96
97 static const u8 cck_tbl_ch14[CCK_TABLE_SIZE][8] = {
98         {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},       /* 0, +0dB */
99         {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},       /* 1, -0.5dB */
100         {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},       /* 2, -1.0dB */
101         {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},       /* 3, -1.5dB */
102         {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},       /* 4, -2.0dB */
103         {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},       /* 5, -2.5dB */
104         {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},       /* 6, -3.0dB */
105         {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},       /* 7, -3.5dB */
106         {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},       /* 8, -4.0dB */
107         {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},       /* 9, -4.5dB */
108         {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},       /* 10, -5.0dB */
109         {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},       /* 11, -5.5dB */
110         {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},       /* 12, -6.0dB */
111         {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},       /* 13, -6.5dB */
112         {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},       /* 14, -7.0dB */
113         {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},       /* 15, -7.5dB */
114         {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},       /* 16, -8.0dB */
115         {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},       /* 17, -8.5dB */
116         {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},       /* 18, -9.0dB */
117         {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},       /* 19, -9.5dB */
118         {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},       /* 20, -10.0dB*/
119         {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},       /* 21, -10.5dB*/
120         {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},       /* 22, -11.0dB*/
121         {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},       /* 23, -11.5dB*/
122         {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},       /* 24, -12.0dB*/
123         {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},       /* 25, -12.5dB*/
124         {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},       /* 26, -13.0dB*/
125         {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},       /* 27, -13.5dB*/
126         {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},       /* 28, -14.0dB*/
127         {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},       /* 29, -14.5dB*/
128         {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},       /* 30, -15.0dB*/
129         {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},       /* 31, -15.5dB*/
130         {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}        /* 32, -16.0dB*/
131 };
132
133 #define CAL_SWING_OFF(_off, _dir, _size, _del)                          \
134         do {                                                            \
135                 for (_off = 0; _off < _size; _off++) {                  \
136                         if (_del < thermal_threshold[_dir][_off]) {     \
137                                 if (_off != 0)                          \
138                                         _off--;                         \
139                                 break;                                  \
140                         }                                               \
141                 }                                                       \
142                 if (_off >= _size)                                      \
143                         _off = _size - 1;                               \
144         } while (0)
145
146 static void rtl88e_set_iqk_matrix(struct ieee80211_hw *hw,
147                                   u8 ofdm_index, u8 rfpath,
148                                   long iqk_result_x, long iqk_result_y)
149 {
150         long ele_a = 0, ele_d, ele_c = 0, value32;
151
152         ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000)>>22;
153
154         if (iqk_result_x != 0) {
155                 if ((iqk_result_x & 0x00000200) != 0)
156                         iqk_result_x = iqk_result_x | 0xFFFFFC00;
157                 ele_a = ((iqk_result_x * ele_d)>>8)&0x000003FF;
158
159                 if ((iqk_result_y & 0x00000200) != 0)
160                         iqk_result_y = iqk_result_y | 0xFFFFFC00;
161                 ele_c = ((iqk_result_y * ele_d)>>8)&0x000003FF;
162
163                 switch (rfpath) {
164                 case RF90_PATH_A:
165                         value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;
166                         rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
167                                       MASKDWORD, value32);
168                         value32 = (ele_c & 0x000003C0) >> 6;
169                         rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
170                                       value32);
171                         value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
172                         rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
173                                       value32);
174                         break;
175                 case RF90_PATH_B:
176                         value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;
177                         rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD,
178                                       value32);
179                         value32 = (ele_c & 0x000003C0) >> 6;
180                         rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, value32);
181                         value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
182                         rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28),
183                                       value32);
184                         break;
185                 default:
186                         break;
187                 }
188         } else {
189                 switch (rfpath) {
190                 case RF90_PATH_A:
191                         rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
192                                       MASKDWORD, ofdmswing_table[ofdm_index]);
193                         rtl_set_bbreg(hw, ROFDM0_XCTXAFE,
194                                       MASKH4BITS, 0x00);
195                         rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
196                                       BIT(24), 0x00);
197                         break;
198                 case RF90_PATH_B:
199                         rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
200                                       MASKDWORD, ofdmswing_table[ofdm_index]);
201                         rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
202                                       MASKH4BITS, 0x00);
203                         rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
204                                       BIT(28), 0x00);
205                         break;
206                 default:
207                         break;
208                 }
209         }
210 }
211
212 void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw,
213         u8 type, u8 *pdirection, u32 *poutwrite_val)
214 {
215         struct rtl_priv *rtlpriv = rtl_priv(hw);
216         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
217         u8 pwr_val = 0;
218         u8 cck_base = rtldm->swing_idx_cck_base;
219         u8 cck_val = rtldm->swing_idx_cck;
220         u8 ofdm_base = rtldm->swing_idx_ofdm_base[0];
221         u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];
222
223         if (type == 0) {
224                 if (ofdm_val <= ofdm_base) {
225                         *pdirection = 1;
226                         pwr_val = ofdm_base - ofdm_val;
227                 } else {
228                         *pdirection = 2;
229                         pwr_val = ofdm_base - ofdm_val;
230                 }
231         } else if (type == 1) {
232                 if (cck_val <= cck_base) {
233                         *pdirection = 1;
234                         pwr_val = cck_base - cck_val;
235                 } else {
236                         *pdirection = 2;
237                         pwr_val = cck_val - cck_base;
238                 }
239         }
240
241         if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
242                 pwr_val = TXPWRTRACK_MAX_IDX;
243
244         *poutwrite_val = pwr_val | (pwr_val << 8) | (pwr_val << 16) |
245                          (pwr_val << 24);
246 }
247
248 static void dm_tx_pwr_track_set_pwr(struct ieee80211_hw *hw,
249                                     enum pwr_track_control_method method,
250                                     u8 rfpath, u8 channel_mapped_index)
251 {
252         struct rtl_priv *rtlpriv = rtl_priv(hw);
253         struct rtl_phy *rtlphy = &rtlpriv->phy;
254         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
255
256         if (method == TXAGC) {
257                 if (rtldm->swing_flag_ofdm ||
258                     rtldm->swing_flag_cck) {
259                         rtl88e_phy_set_txpower_level(hw,
260                                                      rtlphy->current_channel);
261                         rtldm->swing_flag_ofdm = false;
262                         rtldm->swing_flag_cck = false;
263                 }
264         } else if (method == BBSWING) {
265                 if (!rtldm->cck_inch14) {
266                         rtl_write_byte(rtlpriv, 0xa22,
267                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][0]);
268                         rtl_write_byte(rtlpriv, 0xa23,
269                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][1]);
270                         rtl_write_byte(rtlpriv, 0xa24,
271                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][2]);
272                         rtl_write_byte(rtlpriv, 0xa25,
273                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][3]);
274                         rtl_write_byte(rtlpriv, 0xa26,
275                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][4]);
276                         rtl_write_byte(rtlpriv, 0xa27,
277                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][5]);
278                         rtl_write_byte(rtlpriv, 0xa28,
279                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][6]);
280                         rtl_write_byte(rtlpriv, 0xa29,
281                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][7]);
282                 } else {
283                         rtl_write_byte(rtlpriv, 0xa22,
284                                        cck_tbl_ch14[rtldm->swing_idx_cck][0]);
285                         rtl_write_byte(rtlpriv, 0xa23,
286                                        cck_tbl_ch14[rtldm->swing_idx_cck][1]);
287                         rtl_write_byte(rtlpriv, 0xa24,
288                                        cck_tbl_ch14[rtldm->swing_idx_cck][2]);
289                         rtl_write_byte(rtlpriv, 0xa25,
290                                        cck_tbl_ch14[rtldm->swing_idx_cck][3]);
291                         rtl_write_byte(rtlpriv, 0xa26,
292                                        cck_tbl_ch14[rtldm->swing_idx_cck][4]);
293                         rtl_write_byte(rtlpriv, 0xa27,
294                                        cck_tbl_ch14[rtldm->swing_idx_cck][5]);
295                         rtl_write_byte(rtlpriv, 0xa28,
296                                        cck_tbl_ch14[rtldm->swing_idx_cck][6]);
297                         rtl_write_byte(rtlpriv, 0xa29,
298                                        cck_tbl_ch14[rtldm->swing_idx_cck][7]);
299                 }
300
301                 if (rfpath == RF90_PATH_A) {
302                         rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath],
303                                               rfpath, rtlphy->iqk_matrix
304                                               [channel_mapped_index].
305                                               value[0][0],
306                                               rtlphy->iqk_matrix
307                                               [channel_mapped_index].
308                                               value[0][1]);
309                 } else if (rfpath == RF90_PATH_B) {
310                         rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath],
311                                               rfpath, rtlphy->iqk_matrix
312                                               [channel_mapped_index].
313                                               value[0][4],
314                                               rtlphy->iqk_matrix
315                                               [channel_mapped_index].
316                                               value[0][5]);
317                 }
318         } else {
319                 return;
320         }
321 }
322
323 static u8 rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
324 {
325         struct rtl_priv *rtlpriv = rtl_priv(hw);
326         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
327         long rssi_val_min = 0;
328
329         if ((dm_dig->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
330             (dm_dig->cur_sta_cstate == DIG_STA_CONNECT)) {
331                 if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
332                         rssi_val_min =
333                             (rtlpriv->dm.entry_min_undec_sm_pwdb >
334                              rtlpriv->dm.undec_sm_pwdb) ?
335                             rtlpriv->dm.undec_sm_pwdb :
336                             rtlpriv->dm.entry_min_undec_sm_pwdb;
337                 else
338                         rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
339         } else if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT ||
340                    dm_dig->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) {
341                 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
342         } else if (dm_dig->curmultista_cstate ==
343                 DIG_MULTISTA_CONNECT) {
344                 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
345         }
346
347         return (u8)rssi_val_min;
348 }
349
350 static void rtl88e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
351 {
352         u32 ret_value;
353         struct rtl_priv *rtlpriv = rtl_priv(hw);
354         struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
355
356         rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1);
357         rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1);
358
359         ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
360         falsealm_cnt->cnt_fast_fsync_fail = (ret_value&0xffff);
361         falsealm_cnt->cnt_sb_search_fail = ((ret_value&0xffff0000)>>16);
362
363         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
364         falsealm_cnt->cnt_ofdm_cca = (ret_value&0xffff);
365         falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
366
367         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
368         falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
369         falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
370
371         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
372         falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
373         falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
374                 falsealm_cnt->cnt_rate_illegal +
375                 falsealm_cnt->cnt_crc8_fail +
376                 falsealm_cnt->cnt_mcs_fail +
377                 falsealm_cnt->cnt_fast_fsync_fail +
378                 falsealm_cnt->cnt_sb_search_fail;
379
380         ret_value = rtl_get_bbreg(hw, REG_SC_CNT, MASKDWORD);
381         falsealm_cnt->cnt_bw_lsc = (ret_value & 0xffff);
382         falsealm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16);
383
384         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(12), 1);
385         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
386
387         ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
388         falsealm_cnt->cnt_cck_fail = ret_value;
389
390         ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
391         falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
392
393         ret_value = rtl_get_bbreg(hw, RCCK0_CCA_CNT, MASKDWORD);
394         falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
395                 ((ret_value&0xFF00)>>8);
396
397         falsealm_cnt->cnt_all = (falsealm_cnt->cnt_fast_fsync_fail +
398                                 falsealm_cnt->cnt_sb_search_fail +
399                                 falsealm_cnt->cnt_parity_fail +
400                                 falsealm_cnt->cnt_rate_illegal +
401                                 falsealm_cnt->cnt_crc8_fail +
402                                 falsealm_cnt->cnt_mcs_fail +
403                                 falsealm_cnt->cnt_cck_fail);
404         falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
405                 falsealm_cnt->cnt_cck_cca;
406
407         rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 1);
408         rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 0);
409         rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 1);
410         rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 0);
411         rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0);
412         rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0);
413         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 0);
414         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 2);
415         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 0);
416         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 2);
417
418         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
419                  "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
420                  falsealm_cnt->cnt_parity_fail,
421                  falsealm_cnt->cnt_rate_illegal,
422                  falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
423
424         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
425                  "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
426                  falsealm_cnt->cnt_ofdm_fail,
427                  falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
428 }
429
430 static void rtl88e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
431 {
432         struct rtl_priv *rtlpriv = rtl_priv(hw);
433         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
434         u8 cur_cck_cca_thresh;
435
436         if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) {
437                 dm_dig->rssi_val_min = rtl88e_dm_initial_gain_min_pwdb(hw);
438                 if (dm_dig->rssi_val_min > 25) {
439                         cur_cck_cca_thresh = 0xcd;
440                 } else if ((dm_dig->rssi_val_min <= 25) &&
441                            (dm_dig->rssi_val_min > 10)) {
442                         cur_cck_cca_thresh = 0x83;
443                 } else {
444                         if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
445                                 cur_cck_cca_thresh = 0x83;
446                         else
447                                 cur_cck_cca_thresh = 0x40;
448                 }
449
450         } else {
451                 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
452                         cur_cck_cca_thresh = 0x83;
453                 else
454                         cur_cck_cca_thresh = 0x40;
455         }
456
457         if (dm_dig->cur_cck_cca_thres != cur_cck_cca_thresh)
458                 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
459
460         dm_dig->cur_cck_cca_thres = cur_cck_cca_thresh;
461         dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres;
462         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
463                  "CCK cca thresh hold =%x\n", dm_dig->cur_cck_cca_thres);
464 }
465
466 static void rtl88e_dm_dig(struct ieee80211_hw *hw)
467 {
468         struct rtl_priv *rtlpriv = rtl_priv(hw);
469         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
470         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
471         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
472         u8 dig_dynamic_min, dig_maxofmin;
473         bool bfirstconnect;
474         u8 dm_dig_max, dm_dig_min;
475         u8 current_igi = dm_dig->cur_igvalue;
476
477         if (rtlpriv->dm.dm_initialgain_enable == false)
478                 return;
479         if (dm_dig->dig_enable_flag == false)
480                 return;
481         if (mac->act_scanning == true)
482                 return;
483
484         if (mac->link_state >= MAC80211_LINKED)
485                 dm_dig->cur_sta_cstate = DIG_STA_CONNECT;
486         else
487                 dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT;
488         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
489             rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
490                 dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT;
491
492         dm_dig_max = DM_DIG_MAX;
493         dm_dig_min = DM_DIG_MIN;
494         dig_maxofmin = DM_DIG_MAX_AP;
495         dig_dynamic_min = dm_dig->dig_min_0;
496         bfirstconnect = ((mac->link_state >= MAC80211_LINKED) ? true : false) &&
497                          !dm_dig->media_connect_0;
498
499         dm_dig->rssi_val_min =
500                 rtl88e_dm_initial_gain_min_pwdb(hw);
501
502         if (mac->link_state >= MAC80211_LINKED) {
503                 if ((dm_dig->rssi_val_min + 20) > dm_dig_max)
504                         dm_dig->rx_gain_max = dm_dig_max;
505                 else if ((dm_dig->rssi_val_min + 20) < dm_dig_min)
506                         dm_dig->rx_gain_max = dm_dig_min;
507                 else
508                         dm_dig->rx_gain_max = dm_dig->rssi_val_min + 20;
509
510                 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
511                         dig_dynamic_min  = dm_dig->antdiv_rssi_max;
512                 } else {
513                         if (dm_dig->rssi_val_min < dm_dig_min)
514                                 dig_dynamic_min = dm_dig_min;
515                         else if (dm_dig->rssi_val_min < dig_maxofmin)
516                                 dig_dynamic_min = dig_maxofmin;
517                         else
518                                 dig_dynamic_min = dm_dig->rssi_val_min;
519                 }
520         } else {
521                 dm_dig->rx_gain_max = dm_dig_max;
522                 dig_dynamic_min = dm_dig_min;
523                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
524         }
525
526         if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
527                 dm_dig->large_fa_hit++;
528                 if (dm_dig->forbidden_igi < current_igi) {
529                         dm_dig->forbidden_igi = current_igi;
530                         dm_dig->large_fa_hit = 1;
531                 }
532
533                 if (dm_dig->large_fa_hit >= 3) {
534                         if ((dm_dig->forbidden_igi + 1) >
535                                 dm_dig->rx_gain_max)
536                                 dm_dig->rx_gain_min =
537                                         dm_dig->rx_gain_max;
538                         else
539                                 dm_dig->rx_gain_min =
540                                         dm_dig->forbidden_igi + 1;
541                         dm_dig->recover_cnt = 3600;
542                 }
543         } else {
544                 if (dm_dig->recover_cnt != 0) {
545                         dm_dig->recover_cnt--;
546                 } else {
547                         if (dm_dig->large_fa_hit == 0) {
548                                 if ((dm_dig->forbidden_igi - 1) <
549                                     dig_dynamic_min) {
550                                         dm_dig->forbidden_igi = dig_dynamic_min;
551                                         dm_dig->rx_gain_min = dig_dynamic_min;
552                                 } else {
553                                         dm_dig->forbidden_igi--;
554                                         dm_dig->rx_gain_min =
555                                                 dm_dig->forbidden_igi + 1;
556                                 }
557                         } else if (dm_dig->large_fa_hit == 3) {
558                                 dm_dig->large_fa_hit = 0;
559                         }
560                 }
561         }
562
563         if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) {
564                 if (bfirstconnect) {
565                         current_igi = dm_dig->rssi_val_min;
566                 } else {
567                         if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
568                                 current_igi += 2;
569                         else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
570                                 current_igi++;
571                         else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
572                                 current_igi--;
573                 }
574         } else {
575                 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
576                         current_igi += 2;
577                 else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
578                         current_igi++;
579                 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
580                         current_igi--;
581         }
582
583         if (current_igi > DM_DIG_FA_UPPER)
584                 current_igi = DM_DIG_FA_UPPER;
585         else if (current_igi < DM_DIG_FA_LOWER)
586                 current_igi = DM_DIG_FA_LOWER;
587
588         if (rtlpriv->falsealm_cnt.cnt_all > 10000)
589                 current_igi = DM_DIG_FA_UPPER;
590
591         dm_dig->cur_igvalue = current_igi;
592         rtl88e_dm_write_dig(hw);
593         dm_dig->media_connect_0 =
594                 ((mac->link_state >= MAC80211_LINKED) ? true : false);
595         dm_dig->dig_min_0 = dig_dynamic_min;
596
597         rtl88e_dm_cck_packet_detection_thresh(hw);
598 }
599
600 static void rtl88e_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
601 {
602         struct rtl_priv *rtlpriv = rtl_priv(hw);
603
604         rtlpriv->dm.dynamic_txpower_enable = false;
605
606         rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
607         rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
608 }
609
610 static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
611 {
612         struct rtl_priv *rtlpriv = rtl_priv(hw);
613         struct rtl_phy *rtlphy = &rtlpriv->phy;
614         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
615         long undec_sm_pwdb;
616
617         if (!rtlpriv->dm.dynamic_txpower_enable)
618                 return;
619
620         if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
621                 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
622                 return;
623         }
624
625         if ((mac->link_state < MAC80211_LINKED) &&
626             (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
627                 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
628                          "Not connected to any\n");
629
630                 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
631
632                 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
633                 return;
634         }
635
636         if (mac->link_state >= MAC80211_LINKED) {
637                 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
638                         undec_sm_pwdb =
639                             rtlpriv->dm.entry_min_undec_sm_pwdb;
640                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
641                                  "AP Client PWDB = 0x%lx\n",
642                                   undec_sm_pwdb);
643                 } else {
644                         undec_sm_pwdb =
645                             rtlpriv->dm.undec_sm_pwdb;
646                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
647                                  "STA Default Port PWDB = 0x%lx\n",
648                                   undec_sm_pwdb);
649                 }
650         } else {
651                 undec_sm_pwdb =
652                     rtlpriv->dm.entry_min_undec_sm_pwdb;
653
654                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
655                          "AP Ext Port PWDB = 0x%lx\n",
656                           undec_sm_pwdb);
657         }
658
659         if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
660                 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
661                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
662                          "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x0)\n");
663         } else if ((undec_sm_pwdb <
664                     (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
665                    (undec_sm_pwdb >=
666                     TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
667                 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
668                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
669                          "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x10)\n");
670         } else if (undec_sm_pwdb <
671                    (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
672                 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
673                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
674                          "TXHIGHPWRLEVEL_NORMAL\n");
675         }
676
677         if ((rtlpriv->dm.dynamic_txhighpower_lvl !=
678                 rtlpriv->dm.last_dtp_lvl)) {
679                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
680                          "PHY_SetTxPowerLevel8192S() Channel = %d\n",
681                           rtlphy->current_channel);
682                 rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel);
683         }
684
685         rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
686 }
687
688 void rtl88e_dm_write_dig(struct ieee80211_hw *hw)
689 {
690         struct rtl_priv *rtlpriv = rtl_priv(hw);
691         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
692
693         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
694                  "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n",
695                  dm_dig->cur_igvalue, dm_dig->pre_igvalue,
696                  dm_dig->back_val);
697
698         if (dm_dig->cur_igvalue > 0x3f)
699                 dm_dig->cur_igvalue = 0x3f;
700         if (dm_dig->pre_igvalue != dm_dig->cur_igvalue) {
701                 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
702                               dm_dig->cur_igvalue);
703
704                 dm_dig->pre_igvalue = dm_dig->cur_igvalue;
705         }
706 }
707
708 static void rtl88e_dm_pwdb_monitor(struct ieee80211_hw *hw)
709 {
710         struct rtl_priv *rtlpriv = rtl_priv(hw);
711         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
712         struct rtl_sta_info *drv_priv;
713         static u64 last_record_txok_cnt;
714         static u64 last_record_rxok_cnt;
715         long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
716
717         if (rtlhal->oem_id == RT_CID_819X_HP) {
718                 u64 cur_txok_cnt = 0;
719                 u64 cur_rxok_cnt = 0;
720                 cur_txok_cnt = rtlpriv->stats.txbytesunicast -
721                         last_record_txok_cnt;
722                 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast -
723                         last_record_rxok_cnt;
724                 last_record_txok_cnt = cur_txok_cnt;
725                 last_record_rxok_cnt = cur_rxok_cnt;
726
727                 if (cur_rxok_cnt > (cur_txok_cnt * 6))
728                         rtl_write_dword(rtlpriv, REG_ARFR0, 0x8f015);
729                 else
730                         rtl_write_dword(rtlpriv, REG_ARFR0, 0xff015);
731         }
732
733         /* AP & ADHOC & MESH */
734         spin_lock_bh(&rtlpriv->locks.entry_list_lock);
735         list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
736                 if (drv_priv->rssi_stat.undec_sm_pwdb <
737                         tmp_entry_min_pwdb)
738                         tmp_entry_min_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
739                 if (drv_priv->rssi_stat.undec_sm_pwdb >
740                         tmp_entry_max_pwdb)
741                         tmp_entry_max_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
742         }
743         spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
744
745         /* If associated entry is found */
746         if (tmp_entry_max_pwdb != 0) {
747                 rtlpriv->dm.entry_max_undec_sm_pwdb = tmp_entry_max_pwdb;
748                 RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMaxPWDB = 0x%lx(%ld)\n",
749                         tmp_entry_max_pwdb, tmp_entry_max_pwdb);
750         } else {
751                 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
752         }
753         /* If associated entry is found */
754         if (tmp_entry_min_pwdb != 0xff) {
755                 rtlpriv->dm.entry_min_undec_sm_pwdb = tmp_entry_min_pwdb;
756                 RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMinPWDB = 0x%lx(%ld)\n",
757                                         tmp_entry_min_pwdb, tmp_entry_min_pwdb);
758         } else {
759                 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
760         }
761         /* Indicate Rx signal strength to FW. */
762         if (!rtlpriv->dm.useramask)
763                 rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb);
764 }
765
766 void rtl88e_dm_init_edca_turbo(struct ieee80211_hw *hw)
767 {
768         struct rtl_priv *rtlpriv = rtl_priv(hw);
769
770         rtlpriv->dm.current_turbo_edca = false;
771         rtlpriv->dm.is_any_nonbepkts = false;
772         rtlpriv->dm.is_cur_rdlstate = false;
773 }
774
775 static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)
776 {
777         struct rtl_priv *rtlpriv = rtl_priv(hw);
778         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
779         static u64 last_txok_cnt;
780         static u64 last_rxok_cnt;
781         static u32 last_bt_edca_ul;
782         static u32 last_bt_edca_dl;
783         u64 cur_txok_cnt = 0;
784         u64 cur_rxok_cnt = 0;
785         u32 edca_be_ul = 0x5ea42b;
786         u32 edca_be_dl = 0x5ea42b;
787         bool bt_change_edca = false;
788
789         if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) ||
790             (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) {
791                 rtlpriv->dm.current_turbo_edca = false;
792                 last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul;
793                 last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl;
794         }
795
796         if (rtlpriv->btcoexist.bt_edca_ul != 0) {
797                 edca_be_ul = rtlpriv->btcoexist.bt_edca_ul;
798                 bt_change_edca = true;
799         }
800
801         if (rtlpriv->btcoexist.bt_edca_dl != 0) {
802                 edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
803                 bt_change_edca = true;
804         }
805
806         if (mac->link_state != MAC80211_LINKED) {
807                 rtlpriv->dm.current_turbo_edca = false;
808                 return;
809         }
810         if ((bt_change_edca) ||
811             ((!rtlpriv->dm.is_any_nonbepkts) &&
812              (!rtlpriv->dm.disable_framebursting))) {
813
814                 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
815                 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
816
817                 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
818                         if (!rtlpriv->dm.is_cur_rdlstate ||
819                             !rtlpriv->dm.current_turbo_edca) {
820                                 rtl_write_dword(rtlpriv,
821                                                 REG_EDCA_BE_PARAM,
822                                                 edca_be_dl);
823                                 rtlpriv->dm.is_cur_rdlstate = true;
824                         }
825                 } else {
826                         if (rtlpriv->dm.is_cur_rdlstate ||
827                             !rtlpriv->dm.current_turbo_edca) {
828                                 rtl_write_dword(rtlpriv,
829                                                 REG_EDCA_BE_PARAM,
830                                                 edca_be_ul);
831                                 rtlpriv->dm.is_cur_rdlstate = false;
832                         }
833                 }
834                 rtlpriv->dm.current_turbo_edca = true;
835         } else {
836                 if (rtlpriv->dm.current_turbo_edca) {
837                         u8 tmp = AC0_BE;
838
839                         rtlpriv->cfg->ops->set_hw_reg(hw,
840                                                       HW_VAR_AC_PARAM,
841                                                       &tmp);
842                         rtlpriv->dm.current_turbo_edca = false;
843                 }
844         }
845
846         rtlpriv->dm.is_any_nonbepkts = false;
847         last_txok_cnt = rtlpriv->stats.txbytesunicast;
848         last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
849 }
850
851 static void dm_txpower_track_cb_therm(struct ieee80211_hw *hw)
852 {
853         struct rtl_priv *rtlpriv = rtl_priv(hw);
854         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
855         struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
856         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
857         u8 thermalvalue = 0, delta, delta_lck, delta_iqk, offset;
858         u8 thermalvalue_avg_count = 0;
859         u32 thermalvalue_avg = 0;
860         long  ele_d, temp_cck;
861         s8 ofdm_index[2], cck_index = 0,
862                 ofdm_index_old[2] = {0, 0}, cck_index_old = 0;
863         int i = 0;
864         /*bool is2t = false;*/
865
866         u8 ofdm_min_index = 6, rf = 1;
867         /*u8 index_for_channel;*/
868         enum _power_dec_inc {power_dec, power_inc};
869
870         /*0.1 the following TWO tables decide the
871          *final index of OFDM/CCK swing table
872          */
873         static const s8 delta_swing_table_idx[2][15]  = {
874                 {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
875                 {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}
876         };
877         static const u8 thermal_threshold[2][15] = {
878                 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
879                 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
880         };
881
882         /*Initilization (7 steps in total) */
883         rtlpriv->dm.txpower_trackinginit = true;
884         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
885                  "dm_txpower_track_cb_therm\n");
886
887         thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER,
888                                          0xfc00);
889         if (!thermalvalue)
890                 return;
891         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
892                  "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
893                  thermalvalue, rtlpriv->dm.thermalvalue,
894                  rtlefuse->eeprom_thermalmeter);
895
896         /*1. Query OFDM Default Setting: Path A*/
897         ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD) &
898                               MASKOFDM_D;
899         for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
900                 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
901                         ofdm_index_old[0] = (u8)i;
902                         rtldm->swing_idx_ofdm_base[RF90_PATH_A] = (u8)i;
903                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
904                                  "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",
905                                  ROFDM0_XATXIQIMBALANCE,
906                                  ele_d, ofdm_index_old[0]);
907                         break;
908                 }
909         }
910
911         /*2.Query CCK default setting From 0xa24*/
912         temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;
913         for (i = 0; i < CCK_TABLE_LENGTH; i++) {
914                 if (rtlpriv->dm.cck_inch14) {
915                         if (memcmp(&temp_cck, &cck_tbl_ch14[i][2], 4) == 0) {
916                                 cck_index_old = (u8)i;
917                                 rtldm->swing_idx_cck_base = (u8)i;
918                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
919                                          DBG_LOUD,
920                                          "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch 14 %d\n",
921                                          RCCK0_TXFILTER2, temp_cck,
922                                          cck_index_old,
923                                          rtlpriv->dm.cck_inch14);
924                                 break;
925                         }
926                 } else {
927                         if (memcmp(&temp_cck, &cck_tbl_ch1_13[i][2], 4) == 0) {
928                                 cck_index_old = (u8)i;
929                                 rtldm->swing_idx_cck_base = (u8)i;
930                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
931                                          DBG_LOUD,
932                                          "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
933                                          RCCK0_TXFILTER2, temp_cck,
934                                          cck_index_old,
935                                          rtlpriv->dm.cck_inch14);
936                                 break;
937                         }
938                 }
939         }
940
941         /*3 Initialize ThermalValues of RFCalibrateInfo*/
942         if (!rtldm->thermalvalue) {
943                 rtlpriv->dm.thermalvalue = rtlefuse->eeprom_thermalmeter;
944                 rtlpriv->dm.thermalvalue_lck = thermalvalue;
945                 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
946                 for (i = 0; i < rf; i++)
947                         rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
948                 rtlpriv->dm.cck_index = cck_index_old;
949         }
950
951         /*4 Calculate average thermal meter*/
952         rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;
953         rtldm->thermalvalue_avg_index++;
954         if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_88E)
955                 rtldm->thermalvalue_avg_index = 0;
956
957         for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
958                 if (rtldm->thermalvalue_avg[i]) {
959                         thermalvalue_avg += rtldm->thermalvalue_avg[i];
960                         thermalvalue_avg_count++;
961                 }
962         }
963
964         if (thermalvalue_avg_count)
965                 thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
966
967         /* 5 Calculate delta, delta_LCK, delta_IQK.*/
968         if (rtlhal->reloadtxpowerindex) {
969                 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
970                     (thermalvalue - rtlefuse->eeprom_thermalmeter) :
971                     (rtlefuse->eeprom_thermalmeter - thermalvalue);
972                 rtlhal->reloadtxpowerindex = false;
973                 rtlpriv->dm.done_txpower = false;
974         } else if (rtlpriv->dm.done_txpower) {
975                 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
976                     (thermalvalue - rtlpriv->dm.thermalvalue) :
977                     (rtlpriv->dm.thermalvalue - thermalvalue);
978         } else {
979                 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
980                     (thermalvalue - rtlefuse->eeprom_thermalmeter) :
981                     (rtlefuse->eeprom_thermalmeter - thermalvalue);
982         }
983         delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
984             (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
985             (rtlpriv->dm.thermalvalue_lck - thermalvalue);
986         delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
987             (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
988             (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
989
990         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
991                  "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n",
992                  thermalvalue, rtlpriv->dm.thermalvalue,
993                  rtlefuse->eeprom_thermalmeter, delta, delta_lck,
994                  delta_iqk);
995         /* 6 If necessary, do LCK.*/
996         if (delta_lck >= 8) {
997                 rtlpriv->dm.thermalvalue_lck = thermalvalue;
998                 rtl88e_phy_lc_calibrate(hw);
999         }
1000
1001         /* 7 If necessary, move the index of
1002          * swing table to adjust Tx power.
1003          */
1004         if (delta > 0 && rtlpriv->dm.txpower_track_control) {
1005                 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
1006                     (thermalvalue - rtlefuse->eeprom_thermalmeter) :
1007                     (rtlefuse->eeprom_thermalmeter - thermalvalue);
1008
1009                 /* 7.1 Get the final CCK_index and OFDM_index for each
1010                  * swing table.
1011                  */
1012                 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
1013                         CAL_SWING_OFF(offset, power_inc, INDEX_MAPPING_NUM,
1014                                       delta);
1015                         for (i = 0; i < rf; i++)
1016                                 ofdm_index[i] =
1017                                   rtldm->ofdm_index[i] +
1018                                   delta_swing_table_idx[power_inc][offset];
1019                         cck_index = rtldm->cck_index +
1020                                 delta_swing_table_idx[power_inc][offset];
1021                 } else {
1022                         CAL_SWING_OFF(offset, power_dec, INDEX_MAPPING_NUM,
1023                                       delta);
1024                         for (i = 0; i < rf; i++)
1025                                 ofdm_index[i] =
1026                                   rtldm->ofdm_index[i] +
1027                                   delta_swing_table_idx[power_dec][offset];
1028                         cck_index = rtldm->cck_index +
1029                                 delta_swing_table_idx[power_dec][offset];
1030                 }
1031
1032                 /* 7.2 Handle boundary conditions of index.*/
1033                 for (i = 0; i < rf; i++) {
1034                         if (ofdm_index[i] > OFDM_TABLE_SIZE-1)
1035                                 ofdm_index[i] = OFDM_TABLE_SIZE-1;
1036                         else if (rtldm->ofdm_index[i] < ofdm_min_index)
1037                                 ofdm_index[i] = ofdm_min_index;
1038                 }
1039
1040                 if (cck_index > CCK_TABLE_SIZE-1)
1041                         cck_index = CCK_TABLE_SIZE-1;
1042                 else if (cck_index < 0)
1043                         cck_index = 0;
1044
1045                 /*7.3Configure the Swing Table to adjust Tx Power.*/
1046                 if (rtlpriv->dm.txpower_track_control) {
1047                         rtldm->done_txpower = true;
1048                         rtldm->swing_idx_ofdm[RF90_PATH_A] =
1049                                 (u8)ofdm_index[RF90_PATH_A];
1050                         rtldm->swing_idx_cck = cck_index;
1051                         if (rtldm->swing_idx_ofdm_cur !=
1052                             rtldm->swing_idx_ofdm[0]) {
1053                                 rtldm->swing_idx_ofdm_cur =
1054                                          rtldm->swing_idx_ofdm[0];
1055                                 rtldm->swing_flag_ofdm = true;
1056                         }
1057
1058                         if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) {
1059                                 rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck;
1060                                 rtldm->swing_flag_cck = true;
1061                         }
1062
1063                         dm_tx_pwr_track_set_pwr(hw, TXAGC, 0, 0);
1064                 }
1065         }
1066
1067         if (delta_iqk >= 8) {
1068                 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
1069                 rtl88e_phy_iq_calibrate(hw, false);
1070         }
1071
1072         if (rtldm->txpower_track_control)
1073                 rtldm->thermalvalue = thermalvalue;
1074         rtldm->txpowercount = 0;
1075         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");
1076 }
1077
1078 static void rtl88e_dm_init_txpower_tracking(struct ieee80211_hw *hw)
1079 {
1080         struct rtl_priv *rtlpriv = rtl_priv(hw);
1081
1082         rtlpriv->dm.txpower_tracking = true;
1083         rtlpriv->dm.txpower_trackinginit = false;
1084         rtlpriv->dm.txpowercount = 0;
1085         rtlpriv->dm.txpower_track_control = true;
1086
1087         rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] = 12;
1088         rtlpriv->dm.swing_idx_ofdm_cur = 12;
1089         rtlpriv->dm.swing_flag_ofdm = false;
1090         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1091                  "rtlpriv->dm.txpower_tracking = %d\n",
1092                  rtlpriv->dm.txpower_tracking);
1093 }
1094
1095 void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw)
1096 {
1097         struct rtl_priv *rtlpriv = rtl_priv(hw);
1098
1099         if (!rtlpriv->dm.txpower_tracking)
1100                 return;
1101
1102         if (!rtlpriv->dm.tm_trigger) {
1103                 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17)|BIT(16),
1104                               0x03);
1105                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1106                          "Trigger 88E Thermal Meter!!\n");
1107                 rtlpriv->dm.tm_trigger = 1;
1108                 return;
1109         } else {
1110                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1111                          "Schedule TxPowerTracking !!\n");
1112                 dm_txpower_track_cb_therm(hw);
1113                 rtlpriv->dm.tm_trigger = 0;
1114         }
1115 }
1116
1117 void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1118 {
1119         struct rtl_priv *rtlpriv = rtl_priv(hw);
1120         struct rate_adaptive *p_ra = &rtlpriv->ra;
1121
1122         p_ra->ratr_state = DM_RATR_STA_INIT;
1123         p_ra->pre_ratr_state = DM_RATR_STA_INIT;
1124
1125         if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
1126                 rtlpriv->dm.useramask = true;
1127         else
1128                 rtlpriv->dm.useramask = false;
1129 }
1130
1131 static void rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
1132 {
1133         struct rtl_priv *rtlpriv = rtl_priv(hw);
1134         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1135         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1136         struct rate_adaptive *p_ra = &rtlpriv->ra;
1137         u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
1138         struct ieee80211_sta *sta = NULL;
1139
1140         if (is_hal_stop(rtlhal)) {
1141                 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1142                          "driver is going to unload\n");
1143                 return;
1144         }
1145
1146         if (!rtlpriv->dm.useramask) {
1147                 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1148                          "driver does not control rate adaptive mask\n");
1149                 return;
1150         }
1151
1152         if (mac->link_state == MAC80211_LINKED &&
1153             mac->opmode == NL80211_IFTYPE_STATION) {
1154                 switch (p_ra->pre_ratr_state) {
1155                 case DM_RATR_STA_HIGH:
1156                         high_rssithresh_for_ra = 50;
1157                         low_rssithresh_for_ra = 20;
1158                         break;
1159                 case DM_RATR_STA_MIDDLE:
1160                         high_rssithresh_for_ra = 55;
1161                         low_rssithresh_for_ra = 20;
1162                         break;
1163                 case DM_RATR_STA_LOW:
1164                         high_rssithresh_for_ra = 50;
1165                         low_rssithresh_for_ra = 25;
1166                         break;
1167                 default:
1168                         high_rssithresh_for_ra = 50;
1169                         low_rssithresh_for_ra = 20;
1170                         break;
1171                 }
1172
1173                 if (rtlpriv->dm.undec_sm_pwdb >
1174                     (long)high_rssithresh_for_ra)
1175                         p_ra->ratr_state = DM_RATR_STA_HIGH;
1176                 else if (rtlpriv->dm.undec_sm_pwdb >
1177                          (long)low_rssithresh_for_ra)
1178                         p_ra->ratr_state = DM_RATR_STA_MIDDLE;
1179                 else
1180                         p_ra->ratr_state = DM_RATR_STA_LOW;
1181
1182                 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
1183                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1184                                  "RSSI = %ld\n",
1185                                   rtlpriv->dm.undec_sm_pwdb);
1186                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1187                                  "RSSI_LEVEL = %d\n", p_ra->ratr_state);
1188                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1189                                  "PreState = %d, CurState = %d\n",
1190                                   p_ra->pre_ratr_state, p_ra->ratr_state);
1191
1192                         rcu_read_lock();
1193                         sta = rtl_find_sta(hw, mac->bssid);
1194                         if (sta)
1195                                 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1196                                                         p_ra->ratr_state,
1197                                                                    true);
1198                         rcu_read_unlock();
1199
1200                         p_ra->pre_ratr_state = p_ra->ratr_state;
1201                 }
1202         }
1203 }
1204
1205 static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1206 {
1207         struct rtl_priv *rtlpriv = rtl_priv(hw);
1208         struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
1209
1210         dm_pstable->pre_ccastate = CCA_MAX;
1211         dm_pstable->cur_ccasate = CCA_MAX;
1212         dm_pstable->pre_rfstate = RF_MAX;
1213         dm_pstable->cur_rfstate = RF_MAX;
1214         dm_pstable->rssi_val_min = 0;
1215 }
1216
1217 static void rtl88e_dm_update_rx_idle_ant(struct ieee80211_hw *hw,
1218                                          u8 ant)
1219 {
1220         struct rtl_priv *rtlpriv = rtl_priv(hw);
1221         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1222         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1223         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1224         u32 default_ant, optional_ant;
1225
1226         if (pfat_table->rx_idle_ant != ant) {
1227                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1228                          "need to update rx idle ant\n");
1229                 if (ant == MAIN_ANT) {
1230                         default_ant =
1231                           (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1232                           MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
1233                         optional_ant =
1234                           (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1235                           AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
1236                 } else {
1237                         default_ant =
1238                            (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1239                            AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
1240                         optional_ant =
1241                            (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1242                            MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
1243                 }
1244
1245                 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
1246                         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1247                                       BIT(5) | BIT(4) | BIT(3), default_ant);
1248                         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1249                                       BIT(8) | BIT(7) | BIT(6), optional_ant);
1250                         rtl_set_bbreg(hw, DM_REG_ANTSEL_CTRL_11N,
1251                                       BIT(14) | BIT(13) | BIT(12),
1252                                       default_ant);
1253                         rtl_set_bbreg(hw, DM_REG_RESP_TX_11N,
1254                                       BIT(6) | BIT(7), default_ant);
1255                 } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {
1256                         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1257                                       BIT(5) | BIT(4) | BIT(3), default_ant);
1258                         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1259                                       BIT(8) | BIT(7) | BIT(6), optional_ant);
1260                 }
1261         }
1262         pfat_table->rx_idle_ant = ant;
1263         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "RxIdleAnt %s\n",
1264                  (ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT"));
1265 }
1266
1267 static void rtl88e_dm_update_tx_ant(struct ieee80211_hw *hw,
1268                                     u8 ant, u32 mac_id)
1269 {
1270         struct rtl_priv *rtlpriv = rtl_priv(hw);
1271         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1272         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1273         u8 target_ant;
1274
1275         if (ant == MAIN_ANT)
1276                 target_ant = MAIN_ANT_CG_TRX;
1277         else
1278                 target_ant = AUX_ANT_CG_TRX;
1279
1280         pfat_table->antsel_a[mac_id] = target_ant & BIT(0);
1281         pfat_table->antsel_b[mac_id] = (target_ant & BIT(1)) >> 1;
1282         pfat_table->antsel_c[mac_id] = (target_ant & BIT(2)) >> 2;
1283         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "txfrominfo target ant %s\n",
1284                 (ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT"));
1285         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "antsel_tr_mux = 3'b%d%d%d\n",
1286                 pfat_table->antsel_c[mac_id],
1287                 pfat_table->antsel_b[mac_id],
1288                 pfat_table->antsel_a[mac_id]);
1289 }
1290
1291 static void rtl88e_dm_rx_hw_antena_div_init(struct ieee80211_hw *hw)
1292 {
1293         u32  value32;
1294
1295         /*MAC Setting*/
1296         value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1297         rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N,
1298                       MASKDWORD, value32 | (BIT(23) | BIT(25)));
1299         /*Pin Setting*/
1300         rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1301         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1302         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 1);
1303         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1304         /*OFDM Setting*/
1305         rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1306         /*CCK Setting*/
1307         rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);
1308         rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);
1309         rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);
1310         rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);
1311 }
1312
1313 static void rtl88e_dm_trx_hw_antenna_div_init(struct ieee80211_hw *hw)
1314 {
1315         u32  value32;
1316
1317         /*MAC Setting*/
1318         value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1319         rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD,
1320                       value32 | (BIT(23) | BIT(25)));
1321         /*Pin Setting*/
1322         rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1323         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1324         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);
1325         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1326         /*OFDM Setting*/
1327         rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1328         /*CCK Setting*/
1329         rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);
1330         rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);
1331         /*TX Setting*/
1332         rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 0);
1333         rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);
1334         rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);
1335 }
1336
1337 static void rtl88e_dm_fast_training_init(struct ieee80211_hw *hw)
1338 {
1339         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1340         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1341         u32 ant_combination = 2;
1342         u32 value32, i;
1343
1344         for (i = 0; i < 6; i++) {
1345                 pfat_table->bssid[i] = 0;
1346                 pfat_table->ant_sum[i] = 0;
1347                 pfat_table->ant_cnt[i] = 0;
1348                 pfat_table->ant_ave[i] = 0;
1349         }
1350         pfat_table->train_idx = 0;
1351         pfat_table->fat_state = FAT_NORMAL_STATE;
1352
1353         /*MAC Setting*/
1354         value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1355         rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N,
1356                       MASKDWORD, value32 | (BIT(23) | BIT(25)));
1357         value32 = rtl_get_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N, MASKDWORD);
1358         rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1359                       MASKDWORD, value32 | (BIT(16) | BIT(17)));
1360         rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1361                       MASKLWORD, 0);
1362         rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N,
1363                       MASKDWORD, 0);
1364
1365         /*Pin Setting*/
1366         rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1367         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1368         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);
1369         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1370
1371         /*OFDM Setting*/
1372         rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1373         /*antenna mapping table*/
1374         rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE0, 1);
1375         rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE1, 2);
1376
1377         /*TX Setting*/
1378         rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 1);
1379         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1380                       BIT(5) | BIT(4) | BIT(3), 0);
1381         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1382                       BIT(8) | BIT(7) | BIT(6), 1);
1383         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1384                       BIT(2) | BIT(1) | BIT(0), (ant_combination - 1));
1385
1386         rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1387 }
1388
1389 static void rtl88e_dm_antenna_div_init(struct ieee80211_hw *hw)
1390 {
1391         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1392
1393         if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1394                 rtl88e_dm_rx_hw_antena_div_init(hw);
1395         else if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1396                 rtl88e_dm_trx_hw_antenna_div_init(hw);
1397         else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)
1398                 rtl88e_dm_fast_training_init(hw);
1399
1400 }
1401
1402 void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
1403                                      u8 *pdesc, u32 mac_id)
1404 {
1405         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1406         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1407         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1408         __le32 *pdesc32 = (__le32 *)pdesc;
1409
1410         if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
1411             (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)) {
1412                 set_tx_desc_antsel_a(pdesc32, pfat_table->antsel_a[mac_id]);
1413                 set_tx_desc_antsel_b(pdesc32, pfat_table->antsel_b[mac_id]);
1414                 set_tx_desc_antsel_c(pdesc32, pfat_table->antsel_c[mac_id]);
1415         }
1416 }
1417
1418 void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw *hw,
1419                                   u8 antsel_tr_mux, u32 mac_id,
1420                                   u32 rx_pwdb_all)
1421 {
1422         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1423         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1424         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1425
1426         if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
1427                 if (antsel_tr_mux == MAIN_ANT_CG_TRX) {
1428                         pfat_table->main_ant_sum[mac_id] += rx_pwdb_all;
1429                         pfat_table->main_ant_cnt[mac_id]++;
1430                 } else {
1431                         pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all;
1432                         pfat_table->aux_ant_cnt[mac_id]++;
1433                 }
1434         } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {
1435                 if (antsel_tr_mux == MAIN_ANT_CGCS_RX) {
1436                         pfat_table->main_ant_sum[mac_id] += rx_pwdb_all;
1437                         pfat_table->main_ant_cnt[mac_id]++;
1438                 } else {
1439                         pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all;
1440                         pfat_table->aux_ant_cnt[mac_id]++;
1441                 }
1442         }
1443 }
1444
1445 static void rtl88e_dm_hw_ant_div(struct ieee80211_hw *hw)
1446 {
1447         struct rtl_priv *rtlpriv = rtl_priv(hw);
1448         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1449         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1450         struct rtl_sta_info *drv_priv;
1451         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1452         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
1453         u32 i, min_rssi = 0xff, ant_div_max_rssi = 0;
1454         u32 max_rssi = 0, local_min_rssi, local_max_rssi;
1455         u32 main_rssi, aux_rssi;
1456         u8 rx_idle_ant = 0, target_ant = 7;
1457
1458         /*for sta its self*/
1459         i = 0;
1460         main_rssi = (pfat_table->main_ant_cnt[i] != 0) ?
1461                 (pfat_table->main_ant_sum[i] / pfat_table->main_ant_cnt[i]) : 0;
1462         aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ?
1463                 (pfat_table->aux_ant_sum[i] / pfat_table->aux_ant_cnt[i]) : 0;
1464         target_ant = (main_rssi == aux_rssi) ?
1465                 pfat_table->rx_idle_ant : ((main_rssi >= aux_rssi) ?
1466                 MAIN_ANT : AUX_ANT);
1467         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1468                 "main_ant_sum %d main_ant_cnt %d\n",
1469                 pfat_table->main_ant_sum[i],
1470                 pfat_table->main_ant_cnt[i]);
1471         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1472                  "aux_ant_sum %d aux_ant_cnt %d\n",
1473                  pfat_table->aux_ant_sum[i], pfat_table->aux_ant_cnt[i]);
1474         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "main_rssi %d aux_rssi%d\n",
1475                  main_rssi, aux_rssi);
1476         local_max_rssi = (main_rssi > aux_rssi) ? main_rssi : aux_rssi;
1477         if ((local_max_rssi > ant_div_max_rssi) && (local_max_rssi < 40))
1478                 ant_div_max_rssi = local_max_rssi;
1479         if (local_max_rssi > max_rssi)
1480                 max_rssi = local_max_rssi;
1481
1482         if ((pfat_table->rx_idle_ant == MAIN_ANT) && (main_rssi == 0))
1483                 main_rssi = aux_rssi;
1484         else if ((pfat_table->rx_idle_ant == AUX_ANT) && (aux_rssi == 0))
1485                 aux_rssi = main_rssi;
1486
1487         local_min_rssi = (main_rssi > aux_rssi) ? aux_rssi : main_rssi;
1488         if (local_min_rssi < min_rssi) {
1489                 min_rssi = local_min_rssi;
1490                 rx_idle_ant = target_ant;
1491         }
1492         if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1493                 rtl88e_dm_update_tx_ant(hw, target_ant, i);
1494
1495         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1496             rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) {
1497                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1498                 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
1499                         i++;
1500                         main_rssi = (pfat_table->main_ant_cnt[i] != 0) ?
1501                                 (pfat_table->main_ant_sum[i] /
1502                                 pfat_table->main_ant_cnt[i]) : 0;
1503                         aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ?
1504                                 (pfat_table->aux_ant_sum[i] /
1505                                 pfat_table->aux_ant_cnt[i]) : 0;
1506                         target_ant = (main_rssi == aux_rssi) ?
1507                                 pfat_table->rx_idle_ant : ((main_rssi >=
1508                                 aux_rssi) ? MAIN_ANT : AUX_ANT);
1509
1510                         local_max_rssi = (main_rssi > aux_rssi) ?
1511                                          main_rssi : aux_rssi;
1512                         if ((local_max_rssi > ant_div_max_rssi) &&
1513                             (local_max_rssi < 40))
1514                                 ant_div_max_rssi = local_max_rssi;
1515                         if (local_max_rssi > max_rssi)
1516                                 max_rssi = local_max_rssi;
1517
1518                         if ((pfat_table->rx_idle_ant == MAIN_ANT) &&
1519                             (main_rssi == 0))
1520                                 main_rssi = aux_rssi;
1521                         else if ((pfat_table->rx_idle_ant == AUX_ANT) &&
1522                                  (aux_rssi == 0))
1523                                 aux_rssi = main_rssi;
1524
1525                         local_min_rssi = (main_rssi > aux_rssi) ?
1526                                 aux_rssi : main_rssi;
1527                         if (local_min_rssi < min_rssi) {
1528                                 min_rssi = local_min_rssi;
1529                                 rx_idle_ant = target_ant;
1530                         }
1531                         if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1532                                 rtl88e_dm_update_tx_ant(hw, target_ant, i);
1533                 }
1534                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1535         }
1536
1537         for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {
1538                 pfat_table->main_ant_sum[i] = 0;
1539                 pfat_table->aux_ant_sum[i] = 0;
1540                 pfat_table->main_ant_cnt[i] = 0;
1541                 pfat_table->aux_ant_cnt[i] = 0;
1542         }
1543
1544         rtl88e_dm_update_rx_idle_ant(hw, rx_idle_ant);
1545
1546         dm_dig->antdiv_rssi_max = ant_div_max_rssi;
1547         dm_dig->rssi_max = max_rssi;
1548 }
1549
1550 static void rtl88e_set_next_mac_address_target(struct ieee80211_hw *hw)
1551 {
1552         struct rtl_priv *rtlpriv = rtl_priv(hw);
1553         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1554         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1555         struct rtl_sta_info *drv_priv;
1556         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1557         u32 value32, i, j = 0;
1558
1559         if (mac->link_state >= MAC80211_LINKED) {
1560                 for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {
1561                         if ((pfat_table->train_idx + 1) == ASSOCIATE_ENTRY_NUM)
1562                                 pfat_table->train_idx = 0;
1563                         else
1564                                 pfat_table->train_idx++;
1565
1566                         if (pfat_table->train_idx == 0) {
1567                                 value32 = (mac->mac_addr[5] << 8) |
1568                                           mac->mac_addr[4];
1569                                 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1570                                               MASKLWORD, value32);
1571
1572                                 value32 = (mac->mac_addr[3] << 24) |
1573                                           (mac->mac_addr[2] << 16) |
1574                                           (mac->mac_addr[1] << 8) |
1575                                           mac->mac_addr[0];
1576                                 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N,
1577                                               MASKDWORD, value32);
1578                                 break;
1579                         }
1580
1581                         if (rtlpriv->mac80211.opmode !=
1582                             NL80211_IFTYPE_STATION) {
1583                                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1584                                 list_for_each_entry(drv_priv,
1585                                                     &rtlpriv->entry_list, list) {
1586                                         j++;
1587                                         if (j != pfat_table->train_idx)
1588                                                 continue;
1589
1590                                         value32 = (drv_priv->mac_addr[5] << 8) |
1591                                                   drv_priv->mac_addr[4];
1592                                         rtl_set_bbreg(hw,
1593                                                       DM_REG_ANT_TRAIN_PARA2_11N,
1594                                                       MASKLWORD, value32);
1595
1596                                         value32 = (drv_priv->mac_addr[3] << 24) |
1597                                                   (drv_priv->mac_addr[2] << 16) |
1598                                                   (drv_priv->mac_addr[1] << 8) |
1599                                                   drv_priv->mac_addr[0];
1600                                         rtl_set_bbreg(hw,
1601                                                       DM_REG_ANT_TRAIN_PARA1_11N,
1602                                                       MASKDWORD, value32);
1603                                         break;
1604                                 }
1605                                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1606                                 /*find entry, break*/
1607                                 if (j == pfat_table->train_idx)
1608                                         break;
1609                         }
1610                 }
1611         }
1612 }
1613
1614 static void rtl88e_dm_fast_ant_training(struct ieee80211_hw *hw)
1615 {
1616         struct rtl_priv *rtlpriv = rtl_priv(hw);
1617         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1618         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1619         u32 i, max_rssi = 0;
1620         u8 target_ant = 2;
1621         bool bpkt_filter_match = false;
1622
1623         if (pfat_table->fat_state == FAT_TRAINING_STATE) {
1624                 for (i = 0; i < 7; i++) {
1625                         if (pfat_table->ant_cnt[i] == 0) {
1626                                 pfat_table->ant_ave[i] = 0;
1627                         } else {
1628                                 pfat_table->ant_ave[i] =
1629                                         pfat_table->ant_sum[i] /
1630                                         pfat_table->ant_cnt[i];
1631                                 bpkt_filter_match = true;
1632                         }
1633
1634                         if (pfat_table->ant_ave[i] > max_rssi) {
1635                                 max_rssi = pfat_table->ant_ave[i];
1636                                 target_ant = (u8) i;
1637                         }
1638                 }
1639
1640                 if (bpkt_filter_match == false) {
1641                         rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,
1642                                       BIT(16), 0);
1643                         rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1644                 } else {
1645                         rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,
1646                                       BIT(16), 0);
1647                         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(8) |
1648                                       BIT(7) | BIT(6), target_ant);
1649                         rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1650                                       BIT(21), 1);
1651
1652                         pfat_table->antsel_a[pfat_table->train_idx] =
1653                                 target_ant & BIT(0);
1654                         pfat_table->antsel_b[pfat_table->train_idx] =
1655                                 (target_ant & BIT(1)) >> 1;
1656                         pfat_table->antsel_c[pfat_table->train_idx] =
1657                                 (target_ant & BIT(2)) >> 2;
1658
1659                         if (target_ant == 0)
1660                                 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1661                 }
1662
1663                 for (i = 0; i < 7; i++) {
1664                         pfat_table->ant_sum[i] = 0;
1665                         pfat_table->ant_cnt[i] = 0;
1666                 }
1667
1668                 pfat_table->fat_state = FAT_NORMAL_STATE;
1669                 return;
1670         }
1671
1672         if (pfat_table->fat_state == FAT_NORMAL_STATE) {
1673                 rtl88e_set_next_mac_address_target(hw);
1674
1675                 pfat_table->fat_state = FAT_TRAINING_STATE;
1676                 rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N, BIT(16), 1);
1677                 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1678
1679                 mod_timer(&rtlpriv->works.fast_antenna_training_timer,
1680                           jiffies + MSECS(RTL_WATCH_DOG_TIME));
1681         }
1682 }
1683
1684 void rtl88e_dm_fast_antenna_training_callback(struct timer_list *t)
1685 {
1686         struct rtl_priv *rtlpriv =
1687                 from_timer(rtlpriv, t, works.fast_antenna_training_timer);
1688         struct ieee80211_hw *hw = rtlpriv->hw;
1689
1690         rtl88e_dm_fast_ant_training(hw);
1691 }
1692
1693 static void rtl88e_dm_antenna_diversity(struct ieee80211_hw *hw)
1694 {
1695         struct rtl_priv *rtlpriv = rtl_priv(hw);
1696         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1697         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1698         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1699         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1700
1701         if (mac->link_state < MAC80211_LINKED) {
1702                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n");
1703                 if (pfat_table->becomelinked) {
1704                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
1705                                  "need to turn off HW AntDiv\n");
1706                         rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1707                         rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,
1708                                       BIT(15), 0);
1709                         if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1710                                 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1711                                               BIT(21), 0);
1712                         pfat_table->becomelinked =
1713                                 (mac->link_state == MAC80211_LINKED) ?
1714                                 true : false;
1715                 }
1716                 return;
1717         } else {
1718                 if (!pfat_table->becomelinked) {
1719                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
1720                                  "Need to turn on HW AntDiv\n");
1721                         rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1722                         rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,
1723                                       BIT(15), 1);
1724                         if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1725                                 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1726                                               BIT(21), 1);
1727                         pfat_table->becomelinked =
1728                                 (mac->link_state >= MAC80211_LINKED) ?
1729                                 true : false;
1730                 }
1731         }
1732
1733         if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
1734             (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV))
1735                 rtl88e_dm_hw_ant_div(hw);
1736         else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)
1737                 rtl88e_dm_fast_ant_training(hw);
1738 }
1739
1740 void rtl88e_dm_init(struct ieee80211_hw *hw)
1741 {
1742         struct rtl_priv *rtlpriv = rtl_priv(hw);
1743         u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
1744
1745         rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1746         rtl_dm_diginit(hw, cur_igvalue);
1747         rtl88e_dm_init_dynamic_txpower(hw);
1748         rtl88e_dm_init_edca_turbo(hw);
1749         rtl88e_dm_init_rate_adaptive_mask(hw);
1750         rtl88e_dm_init_txpower_tracking(hw);
1751         rtl92c_dm_init_dynamic_bb_powersaving(hw);
1752         rtl88e_dm_antenna_div_init(hw);
1753 }
1754
1755 void rtl88e_dm_watchdog(struct ieee80211_hw *hw)
1756 {
1757         struct rtl_priv *rtlpriv = rtl_priv(hw);
1758         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1759         bool fw_current_inpsmode = false;
1760         bool fw_ps_awake = true;
1761
1762         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1763                                       (u8 *)(&fw_current_inpsmode));
1764         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1765                                       (u8 *)(&fw_ps_awake));
1766         if (ppsc->p2p_ps_info.p2p_ps_mode)
1767                 fw_ps_awake = false;
1768
1769         spin_lock(&rtlpriv->locks.rf_ps_lock);
1770         if ((ppsc->rfpwr_state == ERFON) &&
1771             ((!fw_current_inpsmode) && fw_ps_awake) &&
1772             (!ppsc->rfchange_inprogress)) {
1773                 rtl88e_dm_pwdb_monitor(hw);
1774                 rtl88e_dm_dig(hw);
1775                 rtl88e_dm_false_alarm_counter_statistics(hw);
1776                 rtl92c_dm_dynamic_txpower(hw);
1777                 rtl88e_dm_check_txpower_tracking(hw);
1778                 rtl88e_dm_refresh_rate_adaptive_mask(hw);
1779                 rtl88e_dm_check_edca_turbo(hw);
1780                 rtl88e_dm_antenna_diversity(hw);
1781         }
1782         spin_unlock(&rtlpriv->locks.rf_ps_lock);
1783 }