Linux-libre 5.4.47-gnu
[librecmc/linux-libre.git] / drivers / net / wireless / realtek / rtlwifi / rtl8192ee / dm.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2014  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 cckswing_table_ch1ch13[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 cckswing_table_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 static void rtl92ee_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
134 {
135         u32 ret_value;
136         struct rtl_priv *rtlpriv = rtl_priv(hw);
137         struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
138
139         rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1);
140         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1);
141
142         ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD);
143         falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
144         falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
145
146         ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD);
147         falsealm_cnt->cnt_ofdm_cca = (ret_value & 0xffff);
148         falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
149
150         ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD);
151         falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
152         falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
153
154         ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
155         falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
156
157         falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
158                                       falsealm_cnt->cnt_rate_illegal +
159                                       falsealm_cnt->cnt_crc8_fail +
160                                       falsealm_cnt->cnt_mcs_fail +
161                                       falsealm_cnt->cnt_fast_fsync_fail +
162                                       falsealm_cnt->cnt_sb_search_fail;
163
164         ret_value = rtl_get_bbreg(hw, DM_REG_SC_CNT_11N, MASKDWORD);
165         falsealm_cnt->cnt_bw_lsc = (ret_value & 0xffff);
166         falsealm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16);
167
168         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1);
169         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1);
170
171         ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_LSB_11N, MASKBYTE0);
172         falsealm_cnt->cnt_cck_fail = ret_value;
173
174         ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3);
175         falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
176
177         ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD);
178         falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
179                                     ((ret_value & 0xFF00) >> 8);
180
181         falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail +
182                                 falsealm_cnt->cnt_sb_search_fail +
183                                 falsealm_cnt->cnt_parity_fail +
184                                 falsealm_cnt->cnt_rate_illegal +
185                                 falsealm_cnt->cnt_crc8_fail +
186                                 falsealm_cnt->cnt_mcs_fail +
187                                 falsealm_cnt->cnt_cck_fail;
188
189         falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
190                                     falsealm_cnt->cnt_cck_cca;
191
192         /*reset false alarm counter registers*/
193         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1);
194         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0);
195         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
196         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
197         /*update ofdm counter*/
198         rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0);
199         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0);
200         /*reset CCK CCA counter*/
201         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0);
202         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2);
203         /*reset CCK FA counter*/
204         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0);
205         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2);
206
207         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
208                  "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
209                   falsealm_cnt->cnt_parity_fail,
210                   falsealm_cnt->cnt_rate_illegal,
211                   falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
212
213         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
214                  "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
215                   falsealm_cnt->cnt_ofdm_fail,
216                   falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
217 }
218
219 static void rtl92ee_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
220 {
221         struct rtl_priv *rtlpriv = rtl_priv(hw);
222         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
223         u8 cur_cck_cca_thresh;
224
225         if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
226                 if (dm_dig->rssi_val_min > 25) {
227                         cur_cck_cca_thresh = 0xcd;
228                 } else if ((dm_dig->rssi_val_min <= 25) &&
229                            (dm_dig->rssi_val_min > 10)) {
230                         cur_cck_cca_thresh = 0x83;
231                 } else {
232                         if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
233                                 cur_cck_cca_thresh = 0x83;
234                         else
235                                 cur_cck_cca_thresh = 0x40;
236                 }
237         } else {
238                 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
239                         cur_cck_cca_thresh = 0x83;
240                 else
241                         cur_cck_cca_thresh = 0x40;
242         }
243         rtl92ee_dm_write_cck_cca_thres(hw, cur_cck_cca_thresh);
244 }
245
246 static void rtl92ee_dm_dig(struct ieee80211_hw *hw)
247 {
248         struct rtl_priv *rtlpriv = rtl_priv(hw);
249         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
250         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
251         u8 dig_min_0, dig_maxofmin;
252         bool bfirstconnect , bfirstdisconnect;
253         u8 dm_dig_max, dm_dig_min;
254         u8 current_igi = dm_dig->cur_igvalue;
255         u8 offset;
256
257         /* AP,BT */
258         if (mac->act_scanning)
259                 return;
260
261         dig_min_0 = dm_dig->dig_min_0;
262         bfirstconnect = (mac->link_state >= MAC80211_LINKED) &&
263                         !dm_dig->media_connect_0;
264         bfirstdisconnect = (mac->link_state < MAC80211_LINKED) &&
265                            dm_dig->media_connect_0;
266
267         dm_dig_max = 0x5a;
268         dm_dig_min = DM_DIG_MIN;
269         dig_maxofmin = DM_DIG_MAX_AP;
270
271         if (mac->link_state >= MAC80211_LINKED) {
272                 if ((dm_dig->rssi_val_min + 10) > dm_dig_max)
273                         dm_dig->rx_gain_max = dm_dig_max;
274                 else if ((dm_dig->rssi_val_min + 10) < dm_dig_min)
275                         dm_dig->rx_gain_max = dm_dig_min;
276                 else
277                         dm_dig->rx_gain_max = dm_dig->rssi_val_min + 10;
278
279                 if (rtlpriv->dm.one_entry_only) {
280                         offset = 0;
281                         if (dm_dig->rssi_val_min - offset < dm_dig_min)
282                                 dig_min_0 = dm_dig_min;
283                         else if (dm_dig->rssi_val_min - offset >
284                                  dig_maxofmin)
285                                 dig_min_0 = dig_maxofmin;
286                         else
287                                 dig_min_0 = dm_dig->rssi_val_min - offset;
288                 } else {
289                         dig_min_0 = dm_dig_min;
290                 }
291
292         } else {
293                 dm_dig->rx_gain_max = dm_dig_max;
294                 dig_min_0 = dm_dig_min;
295                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
296         }
297
298         if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
299                 if (dm_dig->large_fa_hit != 3)
300                         dm_dig->large_fa_hit++;
301                 if (dm_dig->forbidden_igi < current_igi) {
302                         dm_dig->forbidden_igi = current_igi;
303                         dm_dig->large_fa_hit = 1;
304                 }
305
306                 if (dm_dig->large_fa_hit >= 3) {
307                         if (dm_dig->forbidden_igi + 1 > dm_dig->rx_gain_max)
308                                 dm_dig->rx_gain_min =
309                                                 dm_dig->rx_gain_max;
310                         else
311                                 dm_dig->rx_gain_min =
312                                                 dm_dig->forbidden_igi + 1;
313                         dm_dig->recover_cnt = 3600;
314                 }
315         } else {
316                 if (dm_dig->recover_cnt != 0) {
317                         dm_dig->recover_cnt--;
318                 } else {
319                         if (dm_dig->large_fa_hit < 3) {
320                                 if ((dm_dig->forbidden_igi - 1) <
321                                     dig_min_0) {
322                                         dm_dig->forbidden_igi = dig_min_0;
323                                         dm_dig->rx_gain_min =
324                                                                 dig_min_0;
325                                 } else {
326                                         dm_dig->forbidden_igi--;
327                                         dm_dig->rx_gain_min =
328                                                 dm_dig->forbidden_igi + 1;
329                                 }
330                         } else {
331                                 dm_dig->large_fa_hit = 0;
332                         }
333                 }
334         }
335
336         if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 5)
337                 dm_dig->rx_gain_min = dm_dig_min;
338
339         if (dm_dig->rx_gain_min > dm_dig->rx_gain_max)
340                 dm_dig->rx_gain_min = dm_dig->rx_gain_max;
341
342         if (mac->link_state >= MAC80211_LINKED) {
343                 if (bfirstconnect) {
344                         if (dm_dig->rssi_val_min <= dig_maxofmin)
345                                 current_igi = dm_dig->rssi_val_min;
346                         else
347                                 current_igi = dig_maxofmin;
348
349                         dm_dig->large_fa_hit = 0;
350                 } else {
351                         if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
352                                 current_igi += 4;
353                         else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
354                                 current_igi += 2;
355                         else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
356                                 current_igi -= 2;
357
358                         if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 5 &&
359                             rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
360                                 current_igi = dm_dig->rx_gain_min;
361                 }
362         } else {
363                 if (bfirstdisconnect) {
364                         current_igi = dm_dig->rx_gain_min;
365                 } else {
366                         if (rtlpriv->falsealm_cnt.cnt_all > 10000)
367                                 current_igi += 4;
368                         else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
369                                 current_igi += 2;
370                         else if (rtlpriv->falsealm_cnt.cnt_all < 500)
371                                 current_igi -= 2;
372                 }
373         }
374
375         if (current_igi > dm_dig->rx_gain_max)
376                 current_igi = dm_dig->rx_gain_max;
377         if (current_igi < dm_dig->rx_gain_min)
378                 current_igi = dm_dig->rx_gain_min;
379
380         rtl92ee_dm_write_dig(hw , current_igi);
381         dm_dig->media_connect_0 = ((mac->link_state >= MAC80211_LINKED) ?
382                                    true : false);
383         dm_dig->dig_min_0 = dig_min_0;
384 }
385
386 void rtl92ee_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 cur_thres)
387 {
388         struct rtl_priv *rtlpriv = rtl_priv(hw);
389         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
390
391         if (dm_dig->cur_cck_cca_thres != cur_thres)
392                 rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11N, cur_thres);
393
394         dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres;
395         dm_dig->cur_cck_cca_thres = cur_thres;
396 }
397
398 void rtl92ee_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
399 {
400         struct rtl_priv *rtlpriv = rtl_priv(hw);
401         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
402
403         if (dm_dig->stop_dig)
404                 return;
405
406         if (dm_dig->cur_igvalue != current_igi) {
407                 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi);
408                 if (rtlpriv->phy.rf_type != RF_1T1R)
409                         rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, current_igi);
410         }
411         dm_dig->pre_igvalue = dm_dig->cur_igvalue;
412         dm_dig->cur_igvalue = current_igi;
413 }
414
415 static void rtl92ee_rssi_dump_to_register(struct ieee80211_hw *hw)
416 {
417         struct rtl_priv *rtlpriv = rtl_priv(hw);
418
419         rtl_write_byte(rtlpriv, RA_RSSIDUMP,
420                        rtlpriv->stats.rx_rssi_percentage[0]);
421         rtl_write_byte(rtlpriv, RB_RSSIDUMP,
422                        rtlpriv->stats.rx_rssi_percentage[1]);
423         /*It seems the following values are not initialized.
424           *According to Windows code,
425           *these value will only be valid with JAGUAR chips
426           */
427         /* Rx EVM */
428         rtl_write_byte(rtlpriv, RS1_RXEVMDUMP, rtlpriv->stats.rx_evm_dbm[0]);
429         rtl_write_byte(rtlpriv, RS2_RXEVMDUMP, rtlpriv->stats.rx_evm_dbm[1]);
430         /* Rx SNR */
431         rtl_write_byte(rtlpriv, RA_RXSNRDUMP,
432                        (u8)(rtlpriv->stats.rx_snr_db[0]));
433         rtl_write_byte(rtlpriv, RB_RXSNRDUMP,
434                        (u8)(rtlpriv->stats.rx_snr_db[1]));
435         /* Rx Cfo_Short */
436         rtl_write_word(rtlpriv, RA_CFOSHORTDUMP,
437                        rtlpriv->stats.rx_cfo_short[0]);
438         rtl_write_word(rtlpriv, RB_CFOSHORTDUMP,
439                        rtlpriv->stats.rx_cfo_short[1]);
440         /* Rx Cfo_Tail */
441         rtl_write_word(rtlpriv, RA_CFOLONGDUMP, rtlpriv->stats.rx_cfo_tail[0]);
442         rtl_write_word(rtlpriv, RB_CFOLONGDUMP, rtlpriv->stats.rx_cfo_tail[1]);
443 }
444
445 static void rtl92ee_dm_find_minimum_rssi(struct ieee80211_hw *hw)
446 {
447         struct rtl_priv *rtlpriv = rtl_priv(hw);
448         struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable;
449         struct rtl_mac *mac = rtl_mac(rtlpriv);
450
451         /* Determine the minimum RSSI  */
452         if ((mac->link_state < MAC80211_LINKED) &&
453             (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
454                 rtl_dm_dig->min_undec_pwdb_for_dm = 0;
455                 RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
456                          "Not connected to any\n");
457         }
458         if (mac->link_state >= MAC80211_LINKED) {
459                 if (mac->opmode == NL80211_IFTYPE_AP ||
460                     mac->opmode == NL80211_IFTYPE_ADHOC) {
461                         rtl_dm_dig->min_undec_pwdb_for_dm =
462                                 rtlpriv->dm.entry_min_undec_sm_pwdb;
463                         RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
464                                  "AP Client PWDB = 0x%lx\n",
465                                  rtlpriv->dm.entry_min_undec_sm_pwdb);
466                 } else {
467                         rtl_dm_dig->min_undec_pwdb_for_dm =
468                             rtlpriv->dm.undec_sm_pwdb;
469                         RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
470                                  "STA Default Port PWDB = 0x%x\n",
471                                  rtl_dm_dig->min_undec_pwdb_for_dm);
472                 }
473         } else {
474                 rtl_dm_dig->min_undec_pwdb_for_dm =
475                         rtlpriv->dm.entry_min_undec_sm_pwdb;
476                 RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
477                          "AP Ext Port or disconnect PWDB = 0x%x\n",
478                          rtl_dm_dig->min_undec_pwdb_for_dm);
479         }
480         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
481                  "MinUndecoratedPWDBForDM =%d\n",
482                  rtl_dm_dig->min_undec_pwdb_for_dm);
483 }
484
485 static void rtl92ee_dm_check_rssi_monitor(struct ieee80211_hw *hw)
486 {
487         struct rtl_priv *rtlpriv = rtl_priv(hw);
488         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
489         struct rtl_mac *mac = rtl_mac(rtlpriv);
490         struct rtl_dm *dm = rtl_dm(rtlpriv);
491         struct rtl_sta_info *drv_priv;
492         u8 h2c[4] = { 0 };
493         long max = 0, min = 0xff;
494         u8 i = 0;
495
496         if (mac->opmode == NL80211_IFTYPE_AP ||
497             mac->opmode == NL80211_IFTYPE_ADHOC ||
498             mac->opmode == NL80211_IFTYPE_MESH_POINT) {
499                 /* AP & ADHOC & MESH */
500                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
501                 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
502                         struct rssi_sta *stat = &drv_priv->rssi_stat;
503
504                         if (stat->undec_sm_pwdb < min)
505                                 min = stat->undec_sm_pwdb;
506                         if (stat->undec_sm_pwdb > max)
507                                 max = stat->undec_sm_pwdb;
508
509                         h2c[3] = 0;
510                         h2c[2] = (u8)(dm->undec_sm_pwdb & 0xFF);
511                         h2c[1] = 0x20;
512                         h2c[0] = ++i;
513                         rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c);
514                 }
515                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
516
517                 /* If associated entry is found */
518                 if (max != 0) {
519                         dm->entry_max_undec_sm_pwdb = max;
520                         RTPRINT(rtlpriv, FDM, DM_PWDB,
521                                 "EntryMaxPWDB = 0x%lx(%ld)\n", max, max);
522                 } else {
523                         dm->entry_max_undec_sm_pwdb = 0;
524                 }
525                 /* If associated entry is found */
526                 if (min != 0xff) {
527                         dm->entry_min_undec_sm_pwdb = min;
528                         RTPRINT(rtlpriv, FDM, DM_PWDB,
529                                 "EntryMinPWDB = 0x%lx(%ld)\n", min, min);
530                 } else {
531                         dm->entry_min_undec_sm_pwdb = 0;
532                 }
533         }
534
535         /* Indicate Rx signal strength to FW. */
536         if (dm->useramask) {
537                 h2c[3] = 0;
538                 h2c[2] = (u8)(dm->undec_sm_pwdb & 0xFF);
539                 h2c[1] = 0x20;
540                 h2c[0] = 0;
541                 rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c);
542         } else {
543                 rtl_write_byte(rtlpriv, 0x4fe, dm->undec_sm_pwdb);
544         }
545         rtl92ee_rssi_dump_to_register(hw);
546         rtl92ee_dm_find_minimum_rssi(hw);
547         dm_dig->rssi_val_min = rtlpriv->dm_digtable.min_undec_pwdb_for_dm;
548 }
549
550 static void rtl92ee_dm_init_primary_cca_check(struct ieee80211_hw *hw)
551 {
552         struct rtl_priv *rtlpriv = rtl_priv(hw);
553         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
554         struct dynamic_primary_cca *primarycca = &rtlpriv->primarycca;
555
556         rtlhal->rts_en = 0;
557         primarycca->dup_rts_flag = 0;
558         primarycca->intf_flag = 0;
559         primarycca->intf_type = 0;
560         primarycca->monitor_flag = 0;
561         primarycca->ch_offset = 0;
562         primarycca->mf_state = 0;
563 }
564
565 static bool rtl92ee_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
566 {
567         struct rtl_priv *rtlpriv = rtl_priv(hw);
568
569         if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
570                 return true;
571
572         return false;
573 }
574
575 void rtl92ee_dm_init_edca_turbo(struct ieee80211_hw *hw)
576 {
577         struct rtl_priv *rtlpriv = rtl_priv(hw);
578
579         rtlpriv->dm.current_turbo_edca = false;
580         rtlpriv->dm.is_cur_rdlstate = false;
581         rtlpriv->dm.is_any_nonbepkts = false;
582 }
583
584 static void rtl92ee_dm_check_edca_turbo(struct ieee80211_hw *hw)
585 {
586         struct rtl_priv *rtlpriv = rtl_priv(hw);
587
588         static u64 last_txok_cnt;
589         static u64 last_rxok_cnt;
590         u64 cur_txok_cnt = 0;
591         u64 cur_rxok_cnt = 0;
592         u32 edca_be_ul = 0x5ea42b;
593         u32 edca_be_dl = 0x5ea42b; /*not sure*/
594         u32 edca_be = 0x5ea42b;
595         bool is_cur_rdlstate;
596         bool b_edca_turbo_on = false;
597
598         if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100)
599                 rtlpriv->dm.is_any_nonbepkts = true;
600         rtlpriv->dm.dbginfo.num_non_be_pkt = 0;
601
602         cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
603         cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
604
605         /*b_bias_on_rx = false;*/
606         b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
607                            (!rtlpriv->dm.disable_framebursting)) ?
608                           true : false;
609
610         if (rtl92ee_dm_is_edca_turbo_disable(hw))
611                 goto check_exit;
612
613         if (b_edca_turbo_on) {
614                 is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ?
615                                     true : false;
616
617                 edca_be = is_cur_rdlstate ? edca_be_dl : edca_be_ul;
618                 rtl_write_dword(rtlpriv , REG_EDCA_BE_PARAM , edca_be);
619                 rtlpriv->dm.is_cur_rdlstate = is_cur_rdlstate;
620                 rtlpriv->dm.current_turbo_edca = true;
621         } else {
622                 if (rtlpriv->dm.current_turbo_edca) {
623                         u8 tmp = AC0_BE;
624
625                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
626                                                       (u8 *)(&tmp));
627                 }
628                 rtlpriv->dm.current_turbo_edca = false;
629         }
630
631 check_exit:
632         rtlpriv->dm.is_any_nonbepkts = false;
633         last_txok_cnt = rtlpriv->stats.txbytesunicast;
634         last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
635 }
636
637 static void rtl92ee_dm_dynamic_edcca(struct ieee80211_hw *hw)
638 {
639         struct rtl_priv *rtlpriv = rtl_priv(hw);
640         u8 reg_c50 , reg_c58;
641         bool fw_current_in_ps_mode = false;
642
643         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
644                                       (u8 *)(&fw_current_in_ps_mode));
645         if (fw_current_in_ps_mode)
646                 return;
647
648         reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
649         reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
650
651         if (reg_c50 > 0x28 && reg_c58 > 0x28) {
652                 if (!rtlpriv->rtlhal.pre_edcca_enable) {
653                         rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03);
654                         rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00);
655                         rtlpriv->rtlhal.pre_edcca_enable = true;
656                 }
657         } else if (reg_c50 < 0x25 && reg_c58 < 0x25) {
658                 if (rtlpriv->rtlhal.pre_edcca_enable) {
659                         rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f);
660                         rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f);
661                         rtlpriv->rtlhal.pre_edcca_enable = false;
662                 }
663         }
664 }
665
666 static void rtl92ee_dm_adaptivity(struct ieee80211_hw *hw)
667 {
668         rtl92ee_dm_dynamic_edcca(hw);
669 }
670
671 static void rtl92ee_dm_write_dynamic_cca(struct ieee80211_hw *hw,
672                                          u8 cur_mf_state)
673 {
674         struct dynamic_primary_cca *primarycca = &rtl_priv(hw)->primarycca;
675
676         if (primarycca->mf_state != cur_mf_state)
677                 rtl_set_bbreg(hw, DM_REG_L1SBD_PD_CH_11N, BIT(8) | BIT(7),
678                               cur_mf_state);
679
680         primarycca->mf_state = cur_mf_state;
681 }
682
683 static void rtl92ee_dm_dynamic_primary_cca_ckeck(struct ieee80211_hw *hw)
684 {
685         struct rtl_priv *rtlpriv = rtl_priv(hw);
686         struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
687         struct dynamic_primary_cca *primarycca = &rtlpriv->primarycca;
688         bool is40mhz = false;
689         u64 ofdm_cca, ofdm_fa, bw_usc_cnt, bw_lsc_cnt;
690         u8 sec_ch_offset;
691         u8 cur_mf_state;
692         static u8 count_down = MONITOR_TIME;
693
694         ofdm_cca = falsealm_cnt->cnt_ofdm_cca;
695         ofdm_fa = falsealm_cnt->cnt_ofdm_fail;
696         bw_usc_cnt = falsealm_cnt->cnt_bw_usc;
697         bw_lsc_cnt = falsealm_cnt->cnt_bw_lsc;
698         is40mhz = rtlpriv->mac80211.bw_40;
699         sec_ch_offset = rtlpriv->mac80211.cur_40_prime_sc;
700         /* NIC: 2: sec is below,  1: sec is above */
701
702         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) {
703                 cur_mf_state = MF_USC_LSC;
704                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
705                 return;
706         }
707
708         if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
709                 return;
710
711         if (is40mhz)
712                 return;
713
714         if (primarycca->pricca_flag == 0) {
715                 /* Primary channel is above
716                  * NOTE: duplicate CTS can remove this condition
717                  */
718                 if (sec_ch_offset == 2) {
719                         if ((ofdm_cca > OFDMCCA_TH) &&
720                             (bw_lsc_cnt > (bw_usc_cnt + BW_IND_BIAS)) &&
721                             (ofdm_fa > (ofdm_cca >> 1))) {
722                                 primarycca->intf_type = 1;
723                                 primarycca->intf_flag = 1;
724                                 cur_mf_state = MF_USC;
725                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
726                                 primarycca->pricca_flag = 1;
727                         } else if ((ofdm_cca > OFDMCCA_TH) &&
728                                    (bw_lsc_cnt > (bw_usc_cnt + BW_IND_BIAS)) &&
729                                    (ofdm_fa < (ofdm_cca >> 1))) {
730                                 primarycca->intf_type = 2;
731                                 primarycca->intf_flag = 1;
732                                 cur_mf_state = MF_USC;
733                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
734                                 primarycca->pricca_flag = 1;
735                                 primarycca->dup_rts_flag = 1;
736                                 rtlpriv->rtlhal.rts_en = 1;
737                         } else {
738                                 primarycca->intf_type = 0;
739                                 primarycca->intf_flag = 0;
740                                 cur_mf_state = MF_USC_LSC;
741                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
742                                 rtlpriv->rtlhal.rts_en = 0;
743                                 primarycca->dup_rts_flag = 0;
744                         }
745                 } else if (sec_ch_offset == 1) {
746                         if ((ofdm_cca > OFDMCCA_TH) &&
747                             (bw_usc_cnt > (bw_lsc_cnt + BW_IND_BIAS)) &&
748                             (ofdm_fa > (ofdm_cca >> 1))) {
749                                 primarycca->intf_type = 1;
750                                 primarycca->intf_flag = 1;
751                                 cur_mf_state = MF_LSC;
752                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
753                                 primarycca->pricca_flag = 1;
754                         } else if ((ofdm_cca > OFDMCCA_TH) &&
755                                    (bw_usc_cnt > (bw_lsc_cnt + BW_IND_BIAS)) &&
756                                    (ofdm_fa < (ofdm_cca >> 1))) {
757                                 primarycca->intf_type = 2;
758                                 primarycca->intf_flag = 1;
759                                 cur_mf_state = MF_LSC;
760                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
761                                 primarycca->pricca_flag = 1;
762                                 primarycca->dup_rts_flag = 1;
763                                 rtlpriv->rtlhal.rts_en = 1;
764                         } else {
765                                 primarycca->intf_type = 0;
766                                 primarycca->intf_flag = 0;
767                                 cur_mf_state = MF_USC_LSC;
768                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
769                                 rtlpriv->rtlhal.rts_en = 0;
770                                 primarycca->dup_rts_flag = 0;
771                         }
772                 }
773         } else {/* PrimaryCCA->PriCCA_flag==1 */
774                 count_down--;
775                 if (count_down == 0) {
776                         count_down = MONITOR_TIME;
777                         primarycca->pricca_flag = 0;
778                         cur_mf_state = MF_USC_LSC;
779                         /* default */
780                         rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
781                         rtlpriv->rtlhal.rts_en = 0;
782                         primarycca->dup_rts_flag = 0;
783                         primarycca->intf_type = 0;
784                         primarycca->intf_flag = 0;
785                 }
786         }
787 }
788
789 static void rtl92ee_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
790 {
791         struct rtl_priv *rtlpriv = rtl_priv(hw);
792         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
793         u8 crystal_cap;
794         u32 packet_count;
795         int cfo_khz_a , cfo_khz_b , cfo_ave = 0, adjust_xtal = 0;
796         int cfo_ave_diff;
797
798         if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
799                 if (rtldm->atc_status == ATC_STATUS_OFF) {
800                         rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
801                                       ATC_STATUS_ON);
802                         rtldm->atc_status = ATC_STATUS_ON;
803                 }
804                 /* Disable CFO tracking for BT */
805                 if (rtlpriv->cfg->ops->get_btc_status()) {
806                         if (!rtlpriv->btcoexist.btc_ops->
807                             btc_is_bt_disabled(rtlpriv)) {
808                                 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
809                                          "odm_DynamicATCSwitch(): Disable CFO tracking for BT!!\n");
810                                 return;
811                         }
812                 }
813                 /* Reset Crystal Cap */
814                 if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
815                         rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
816                         crystal_cap = rtldm->crystal_cap & 0x3f;
817                         rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
818                                       (crystal_cap | (crystal_cap << 6)));
819                 }
820         } else {
821                 cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
822                 cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
823                 packet_count = rtldm->packet_count;
824
825                 if (packet_count == rtldm->packet_count_pre)
826                         return;
827
828                 rtldm->packet_count_pre = packet_count;
829
830                 if (rtlpriv->phy.rf_type == RF_1T1R)
831                         cfo_ave = cfo_khz_a;
832                 else
833                         cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1;
834
835                 cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
836                                (rtldm->cfo_ave_pre - cfo_ave) :
837                                (cfo_ave - rtldm->cfo_ave_pre);
838
839                 if (cfo_ave_diff > 20 && rtldm->large_cfo_hit == 0) {
840                         rtldm->large_cfo_hit = 1;
841                         return;
842                 }
843                 rtldm->large_cfo_hit = 0;
844
845                 rtldm->cfo_ave_pre = cfo_ave;
846
847                 if (cfo_ave >= -rtldm->cfo_threshold &&
848                     cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) {
849                         if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
850                                 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
851                                 rtldm->is_freeze = 1;
852                         } else {
853                                 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
854                         }
855                 }
856
857                 if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
858                         adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1;
859                 else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
860                          rtlpriv->dm.crystal_cap > 0)
861                         adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1;
862
863                 if (adjust_xtal != 0) {
864                         rtldm->is_freeze = 0;
865                         rtldm->crystal_cap += adjust_xtal;
866
867                         if (rtldm->crystal_cap > 0x3f)
868                                 rtldm->crystal_cap = 0x3f;
869                         else if (rtldm->crystal_cap < 0)
870                                 rtldm->crystal_cap = 0;
871
872                         crystal_cap = rtldm->crystal_cap & 0x3f;
873                         rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
874                                       (crystal_cap | (crystal_cap << 6)));
875                 }
876
877                 if (cfo_ave < CFO_THRESHOLD_ATC &&
878                     cfo_ave > -CFO_THRESHOLD_ATC) {
879                         if (rtldm->atc_status == ATC_STATUS_ON) {
880                                 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
881                                               ATC_STATUS_OFF);
882                                 rtldm->atc_status = ATC_STATUS_OFF;
883                         }
884                 } else {
885                         if (rtldm->atc_status == ATC_STATUS_OFF) {
886                                 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
887                                               ATC_STATUS_ON);
888                                 rtldm->atc_status = ATC_STATUS_ON;
889                         }
890                 }
891         }
892 }
893
894 static void rtl92ee_dm_init_txpower_tracking(struct ieee80211_hw *hw)
895 {
896         struct rtl_priv *rtlpriv = rtl_priv(hw);
897         struct rtl_dm *dm = rtl_dm(rtlpriv);
898         u8 path;
899
900         dm->txpower_tracking = true;
901         dm->default_ofdm_index = 30;
902         dm->default_cck_index = 20;
903
904         dm->swing_idx_cck_base = dm->default_cck_index;
905         dm->cck_index = dm->default_cck_index;
906
907         for (path = RF90_PATH_A; path < MAX_RF_PATH; path++) {
908                 dm->swing_idx_ofdm_base[path] = dm->default_ofdm_index;
909                 dm->ofdm_index[path] = dm->default_ofdm_index;
910                 dm->delta_power_index[path] = 0;
911                 dm->delta_power_index_last[path] = 0;
912                 dm->power_index_offset[path] = 0;
913         }
914 }
915
916 void rtl92ee_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
917 {
918         struct rtl_priv *rtlpriv = rtl_priv(hw);
919         struct rate_adaptive *p_ra = &rtlpriv->ra;
920
921         p_ra->ratr_state = DM_RATR_STA_INIT;
922         p_ra->pre_ratr_state = DM_RATR_STA_INIT;
923
924         if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
925                 rtlpriv->dm.useramask = true;
926         else
927                 rtlpriv->dm.useramask = false;
928
929         p_ra->ldpc_thres = 35;
930         p_ra->use_ldpc = false;
931         p_ra->high_rssi_thresh_for_ra = 50;
932         p_ra->low_rssi_thresh_for_ra40m = 20;
933 }
934
935 static bool _rtl92ee_dm_ra_state_check(struct ieee80211_hw *hw,
936                                        s32 rssi, u8 *ratr_state)
937 {
938         struct rtl_priv *rtlpriv = rtl_priv(hw);
939         struct rate_adaptive *p_ra = &rtlpriv->ra;
940         const u8 go_up_gap = 5;
941         u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
942         u32 low_rssithresh_for_ra = p_ra->low_rssi_thresh_for_ra40m;
943         u8 state;
944
945         /* Threshold Adjustment:
946          * when RSSI state trends to go up one or two levels,
947          * make sure RSSI is high enough.
948          * Here GoUpGap is added to solve
949          * the boundary's level alternation issue.
950          */
951         switch (*ratr_state) {
952         case DM_RATR_STA_INIT:
953         case DM_RATR_STA_HIGH:
954                 break;
955         case DM_RATR_STA_MIDDLE:
956                 high_rssithresh_for_ra += go_up_gap;
957                 break;
958         case DM_RATR_STA_LOW:
959                 high_rssithresh_for_ra += go_up_gap;
960                 low_rssithresh_for_ra += go_up_gap;
961                 break;
962         default:
963                 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
964                          "wrong rssi level setting %d !\n", *ratr_state);
965                 break;
966         }
967
968         /* Decide RATRState by RSSI. */
969         if (rssi > high_rssithresh_for_ra)
970                 state = DM_RATR_STA_HIGH;
971         else if (rssi > low_rssithresh_for_ra)
972                 state = DM_RATR_STA_MIDDLE;
973         else
974                 state = DM_RATR_STA_LOW;
975
976         if (*ratr_state != state) {
977                 *ratr_state = state;
978                 return true;
979         }
980
981         return false;
982 }
983
984 static void rtl92ee_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
985 {
986         struct rtl_priv *rtlpriv = rtl_priv(hw);
987         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
988         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
989         struct rate_adaptive *p_ra = &rtlpriv->ra;
990         struct ieee80211_sta *sta = NULL;
991
992         if (is_hal_stop(rtlhal)) {
993                 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
994                          "driver is going to unload\n");
995                 return;
996         }
997
998         if (!rtlpriv->dm.useramask) {
999                 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1000                          "driver does not control rate adaptive mask\n");
1001                 return;
1002         }
1003
1004         if (mac->link_state == MAC80211_LINKED &&
1005             mac->opmode == NL80211_IFTYPE_STATION) {
1006                 if (rtlpriv->dm.undec_sm_pwdb < p_ra->ldpc_thres) {
1007                         p_ra->use_ldpc = true;
1008                         p_ra->lower_rts_rate = true;
1009                 } else if (rtlpriv->dm.undec_sm_pwdb >
1010                            (p_ra->ldpc_thres - 5)) {
1011                         p_ra->use_ldpc = false;
1012                         p_ra->lower_rts_rate = false;
1013                 }
1014                 if (_rtl92ee_dm_ra_state_check(hw, rtlpriv->dm.undec_sm_pwdb,
1015                                                &p_ra->ratr_state)) {
1016                         rcu_read_lock();
1017                         sta = rtl_find_sta(hw, mac->bssid);
1018                         if (sta)
1019                                 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1020                                                               p_ra->ratr_state,
1021                                                               true);
1022                         rcu_read_unlock();
1023
1024                         p_ra->pre_ratr_state = p_ra->ratr_state;
1025                 }
1026         }
1027 }
1028
1029 static void rtl92ee_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
1030 {
1031         struct rtl_priv *rtlpriv = rtl_priv(hw);
1032
1033         rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
1034
1035         rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11));
1036         rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
1037 }
1038
1039 void rtl92ee_dm_init(struct ieee80211_hw *hw)
1040 {
1041         struct rtl_priv *rtlpriv = rtl_priv(hw);
1042         u32 cur_igvalue = rtl_get_bbreg(hw, DM_REG_IGI_A_11N, DM_BIT_IGI_11N);
1043
1044         rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1045
1046         rtl_dm_diginit(hw, cur_igvalue);
1047         rtl92ee_dm_init_rate_adaptive_mask(hw);
1048         rtl92ee_dm_init_primary_cca_check(hw);
1049         rtl92ee_dm_init_edca_turbo(hw);
1050         rtl92ee_dm_init_txpower_tracking(hw);
1051         rtl92ee_dm_init_dynamic_atc_switch(hw);
1052 }
1053
1054 static void rtl92ee_dm_common_info_self_update(struct ieee80211_hw *hw)
1055 {
1056         struct rtl_priv *rtlpriv = rtl_priv(hw);
1057         struct rtl_sta_info *drv_priv;
1058         u8 cnt = 0;
1059
1060         rtlpriv->dm.one_entry_only = false;
1061
1062         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
1063             rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1064                 rtlpriv->dm.one_entry_only = true;
1065                 return;
1066         }
1067
1068         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1069             rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
1070             rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
1071                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1072                 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
1073                         cnt++;
1074                 }
1075                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1076
1077                 if (cnt == 1)
1078                         rtlpriv->dm.one_entry_only = true;
1079         }
1080 }
1081
1082 void rtl92ee_dm_dynamic_arfb_select(struct ieee80211_hw *hw,
1083                                     u8 rate, bool collision_state)
1084 {
1085         struct rtl_priv *rtlpriv = rtl_priv(hw);
1086
1087         if (rate >= DESC92C_RATEMCS8  && rate <= DESC92C_RATEMCS12) {
1088                 if (collision_state == 1) {
1089                         if (rate == DESC92C_RATEMCS12) {
1090                                 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1091                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1092                                                 0x07060501);
1093                         } else if (rate == DESC92C_RATEMCS11) {
1094                                 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1095                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1096                                                 0x07070605);
1097                         } else if (rate == DESC92C_RATEMCS10) {
1098                                 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1099                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1100                                                 0x08080706);
1101                         } else if (rate == DESC92C_RATEMCS9) {
1102                                 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1103                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1104                                                 0x08080707);
1105                         } else {
1106                                 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1107                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1108                                                 0x09090808);
1109                         }
1110                 } else {   /* collision_state == 0 */
1111                         if (rate == DESC92C_RATEMCS12) {
1112                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1113                                                 0x05010000);
1114                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1115                                                 0x09080706);
1116                         } else if (rate == DESC92C_RATEMCS11) {
1117                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1118                                                 0x06050000);
1119                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1120                                                 0x09080807);
1121                         } else if (rate == DESC92C_RATEMCS10) {
1122                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1123                                                 0x07060000);
1124                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1125                                                 0x0a090908);
1126                         } else if (rate == DESC92C_RATEMCS9) {
1127                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1128                                                 0x07070000);
1129                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1130                                                 0x0a090808);
1131                         } else {
1132                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1133                                                 0x08080000);
1134                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1135                                                 0x0b0a0909);
1136                         }
1137                 }
1138         } else {  /* MCS13~MCS15,  1SS, G-mode */
1139                 if (collision_state == 1) {
1140                         if (rate == DESC92C_RATEMCS15) {
1141                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1142                                                 0x00000000);
1143                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1144                                                 0x05040302);
1145                         } else if (rate == DESC92C_RATEMCS14) {
1146                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1147                                                 0x00000000);
1148                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1149                                                 0x06050302);
1150                         } else if (rate == DESC92C_RATEMCS13) {
1151                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1152                                                 0x00000000);
1153                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1154                                                 0x07060502);
1155                         } else {
1156                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1157                                                 0x00000000);
1158                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1159                                                 0x06050402);
1160                         }
1161                 } else{   /* collision_state == 0 */
1162                         if (rate == DESC92C_RATEMCS15) {
1163                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1164                                                 0x03020000);
1165                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1166                                                 0x07060504);
1167                         } else if (rate == DESC92C_RATEMCS14) {
1168                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1169                                                 0x03020000);
1170                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1171                                                 0x08070605);
1172                         } else if (rate == DESC92C_RATEMCS13) {
1173                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1174                                                 0x05020000);
1175                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1176                                                 0x09080706);
1177                         } else {
1178                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1179                                                 0x04020000);
1180                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1181                                                 0x08070605);
1182                         }
1183                 }
1184         }
1185 }
1186
1187 void rtl92ee_dm_watchdog(struct ieee80211_hw *hw)
1188 {
1189         struct rtl_priv *rtlpriv = rtl_priv(hw);
1190         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1191         bool fw_current_inpsmode = false;
1192         bool fw_ps_awake = true;
1193
1194         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1195                                       (u8 *)(&fw_current_inpsmode));
1196         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1197                                       (u8 *)(&fw_ps_awake));
1198         if (ppsc->p2p_ps_info.p2p_ps_mode)
1199                 fw_ps_awake = false;
1200
1201         spin_lock(&rtlpriv->locks.rf_ps_lock);
1202         if ((ppsc->rfpwr_state == ERFON) &&
1203             ((!fw_current_inpsmode) && fw_ps_awake) &&
1204             (!ppsc->rfchange_inprogress)) {
1205                 rtl92ee_dm_common_info_self_update(hw);
1206                 rtl92ee_dm_false_alarm_counter_statistics(hw);
1207                 rtl92ee_dm_check_rssi_monitor(hw);
1208                 rtl92ee_dm_dig(hw);
1209                 rtl92ee_dm_adaptivity(hw);
1210                 rtl92ee_dm_cck_packet_detection_thresh(hw);
1211                 rtl92ee_dm_refresh_rate_adaptive_mask(hw);
1212                 rtl92ee_dm_check_edca_turbo(hw);
1213                 rtl92ee_dm_dynamic_atc_switch(hw);
1214                 rtl92ee_dm_dynamic_primary_cca_ckeck(hw);
1215         }
1216         spin_unlock(&rtlpriv->locks.rf_ps_lock);
1217 }