64254c4070f756b92c20dff35abd76b0c52e8778
[firefly-linux-kernel-4.4.55.git] / drivers / staging / rtl8192ee / rtl8192ee / dm.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2010  Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25
26 #include "../wifi.h"
27 #include "../base.h"
28 #include "../pci.h"
29 #include "reg.h"
30 #include "def.h"
31 #include "phy.h"
32 #include "dm.h"
33 #include "fw.h"
34 #include "trx.h"
35
36 struct dig_t dm_dig;
37
38 static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
39         0x7f8001fe,             /* 0, +6.0dB */
40         0x788001e2,             /* 1, +5.5dB */
41         0x71c001c7,             /* 2, +5.0dB */
42         0x6b8001ae,             /* 3, +4.5dB */
43         0x65400195,             /* 4, +4.0dB */
44         0x5fc0017f,             /* 5, +3.5dB */
45         0x5a400169,             /* 6, +3.0dB */
46         0x55400155,             /* 7, +2.5dB */
47         0x50800142,             /* 8, +2.0dB */
48         0x4c000130,             /* 9, +1.5dB */
49         0x47c0011f,             /* 10, +1.0dB */
50         0x43c0010f,             /* 11, +0.5dB */
51         0x40000100,             /* 12, +0dB */
52         0x3c8000f2,             /* 13, -0.5dB */
53         0x390000e4,             /* 14, -1.0dB */
54         0x35c000d7,             /* 15, -1.5dB */
55         0x32c000cb,             /* 16, -2.0dB */
56         0x300000c0,             /* 17, -2.5dB */
57         0x2d4000b5,             /* 18, -3.0dB */
58         0x2ac000ab,             /* 19, -3.5dB */
59         0x288000a2,             /* 20, -4.0dB */
60         0x26000098,             /* 21, -4.5dB */
61         0x24000090,             /* 22, -5.0dB */
62         0x22000088,             /* 23, -5.5dB */
63         0x20000080,             /* 24, -6.0dB */
64         0x1e400079,             /* 25, -6.5dB */
65         0x1c800072,             /* 26, -7.0dB */
66         0x1b00006c,             /* 27. -7.5dB */
67         0x19800066,             /* 28, -8.0dB */
68         0x18000060,             /* 29, -8.5dB */
69         0x16c0005b,             /* 30, -9.0dB */
70         0x15800056,             /* 31, -9.5dB */
71         0x14400051,             /* 32, -10.0dB */
72         0x1300004c,             /* 33, -10.5dB */
73         0x12000048,             /* 34, -11.0dB */
74         0x11000044,             /* 35, -11.5dB */
75         0x10000040,             /* 36, -12.0dB */
76         0x0f00003c,             /* 37, -12.5dB */
77         0x0e400039,             /* 38, -13.0dB */
78         0x0d800036,             /* 39, -13.5dB */
79         0x0cc00033,             /* 40, -14.0dB */
80         0x0c000030,             /* 41, -14.5dB */
81         0x0b40002d,             /* 42, -15.0dB */
82 };
83
84 static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
85         {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */
86         {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */
87         {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */
88         {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */
89         {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */
90         {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */
91         {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */
92         {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */
93         {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */
94         {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */
95         {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */
96         {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */
97         {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */
98         {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */
99         {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */
100         {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */
101         {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
102         {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */
103         {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */
104         {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */
105         {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB */
106         {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB */
107         {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB */
108         {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB */
109         {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB */
110         {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB */
111         {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB */
112         {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB */
113         {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB */
114         {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB */
115         {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB */
116         {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB */
117         {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}  /* 32, -16.0dB */
118 };
119
120 static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
121         {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */
122         {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */
123         {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */
124         {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */
125         {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */
126         {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */
127         {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */
128         {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */
129         {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */
130         {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */
131         {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */
132         {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */
133         {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */
134         {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */
135         {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */
136         {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */
137         {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
138         {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */
139         {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */
140         {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */
141         {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB */
142         {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB */
143         {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB */
144         {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB */
145         {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB */
146         {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB */
147         {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB */
148         {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB */
149         {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB */
150         {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB */
151         {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB */
152         {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB */
153         {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}  /* 32, -16.0dB */
154 };
155
156 static void rtl92ee_dm_diginit(struct ieee80211_hw *hw)
157 {
158         struct rtl_priv *rtlpriv = rtl_priv(hw);
159         dm_dig.cur_igvalue = rtl_get_bbreg(hw, DM_REG_IGI_A_11N,
160                                                 DM_BIT_IGI_11N);
161         dm_dig.rssi_lowthresh = DM_DIG_THRESH_LOW;
162         dm_dig.rssi_highthresh = DM_DIG_THRESH_HIGH;
163         dm_dig.fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
164         dm_dig.fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
165         dm_dig.rx_gain_range_max = DM_DIG_MAX;
166         dm_dig.rx_gain_range_min = DM_DIG_MIN;
167         dm_dig.backoff_val = DM_DIG_BACKOFF_DEFAULT;
168         dm_dig.backoff_val_range_max = DM_DIG_BACKOFF_MAX;
169         dm_dig.backoff_val_range_min = DM_DIG_BACKOFF_MIN;
170         dm_dig.pre_cck_cca_thres = 0xff;
171         dm_dig.cur_cck_cca_thres = 0x83;
172         dm_dig.forbidden_igi = DM_DIG_MIN;
173         dm_dig.large_fa_hit = 0;
174         dm_dig.recover_cnt = 0;
175         dm_dig.dig_dynamic_min_0 = DM_DIG_MIN;
176         dm_dig.dig_dynamic_min_1 = DM_DIG_MIN;
177         dm_dig.b_media_connect_0 = false;
178         dm_dig.b_media_connect_1 = false;
179         rtlpriv->dm.b_dm_initialgain_enable = true;
180         dm_dig.bt30_cur_igi = 0x32;
181 }
182
183 static void rtl92ee_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
184 {
185         u32 ret_value;
186         struct rtl_priv *rtlpriv = rtl_priv(hw);
187         struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
188
189         rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1);
190         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1);
191
192         ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD);
193         falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
194         falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
195
196         ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD);
197         falsealm_cnt->cnt_ofdm_cca = (ret_value & 0xffff);
198         falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
199
200         ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD);
201         falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
202         falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
203
204         ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
205         falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
206
207         falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
208                                       falsealm_cnt->cnt_rate_illegal +
209                                       falsealm_cnt->cnt_crc8_fail +
210                                       falsealm_cnt->cnt_mcs_fail +
211                                       falsealm_cnt->cnt_fast_fsync_fail +
212                                       falsealm_cnt->cnt_sb_search_fail;
213
214         ret_value = rtl_get_bbreg(hw, DM_REG_SC_CNT_11N, MASKDWORD);
215         falsealm_cnt->cnt_bw_lsc = (ret_value & 0xffff);
216         falsealm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16);
217
218         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1);
219         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1);
220
221         ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_LSB_11N, MASKBYTE0);
222         falsealm_cnt->cnt_cck_fail = ret_value;
223
224         ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3);
225         falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
226
227         ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD);
228         falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
229                                     ((ret_value & 0xFF00) >> 8);
230
231         falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail +
232                                 falsealm_cnt->cnt_sb_search_fail +
233                                 falsealm_cnt->cnt_parity_fail +
234                                 falsealm_cnt->cnt_rate_illegal +
235                                 falsealm_cnt->cnt_crc8_fail +
236                                 falsealm_cnt->cnt_mcs_fail +
237                                 falsealm_cnt->cnt_cck_fail;
238
239         falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
240                                     falsealm_cnt->cnt_cck_cca;
241
242         /*reset false alarm counter registers*/
243         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1);
244         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0);
245         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
246         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
247         /*update ofdm counter*/
248         rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0);
249         rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0);
250         /*reset CCK CCA counter*/
251         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0);
252         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2);
253         /*reset CCK FA counter*/
254         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0);
255         rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2);
256
257
258         RT_TRACE(COMP_DIG, DBG_TRACE,
259                  "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
260                  falsealm_cnt->cnt_parity_fail,
261                  falsealm_cnt->cnt_rate_illegal,
262                  falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
263
264         RT_TRACE(COMP_DIG, DBG_TRACE,
265                  "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
266                  falsealm_cnt->cnt_ofdm_fail,
267                  falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
268 }
269
270 static void rtl92ee_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
271 {
272         struct rtl_priv *rtlpriv = rtl_priv(hw);
273         u8 cur_cck_cca_thresh;
274         if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
275                 if (dm_dig.rssi_val_min > 25) {
276                         cur_cck_cca_thresh = 0xcd;
277                 } else if ((dm_dig.rssi_val_min <= 25) &&
278                            (dm_dig.rssi_val_min > 10)) {
279                         cur_cck_cca_thresh = 0x83;
280                 } else {
281                         if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
282                                 cur_cck_cca_thresh = 0x83;
283                         else
284                                 cur_cck_cca_thresh = 0x40;
285                 }
286         } else {
287                 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
288                         cur_cck_cca_thresh = 0x83;
289                 else
290                         cur_cck_cca_thresh = 0x40;
291         }
292         rtl92ee_dm_write_cck_cca_thres(hw, cur_cck_cca_thresh);
293 }
294
295 static void rtl92ee_dm_dig(struct ieee80211_hw *hw)
296 {
297         struct rtl_priv *rtlpriv = rtl_priv(hw);
298         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
299         u8 dig_dynamic_min , dig_maxofmin;
300         bool bfirstconnect , bfirstdisconnect;
301         u8 dm_dig_max, dm_dig_min;
302         u8 current_igi = dm_dig.cur_igvalue;
303         u8 offset;
304
305         /* AP, BT */
306         if (mac->act_scanning == true)
307                 return;
308
309         dig_dynamic_min = dm_dig.dig_dynamic_min_0;
310         bfirstconnect = (mac->link_state >= MAC80211_LINKED) &&
311                         (dm_dig.b_media_connect_0 == false);
312         bfirstdisconnect = (mac->link_state < MAC80211_LINKED) &&
313                            (dm_dig.b_media_connect_0 == true);
314
315         dm_dig_max = 0x5a;
316         dm_dig_min = DM_DIG_MIN;
317         dig_maxofmin = DM_DIG_MAX_AP;
318
319         if (mac->link_state >= MAC80211_LINKED) {
320                 if ((dm_dig.rssi_val_min + 10) > dm_dig_max)
321                         dm_dig.rx_gain_range_max = dm_dig_max;
322                 else if ((dm_dig.rssi_val_min + 10) < dm_dig_min)
323                         dm_dig.rx_gain_range_max = dm_dig_min;
324                 else
325                         dm_dig.rx_gain_range_max = dm_dig.rssi_val_min + 10;
326
327                 if (rtlpriv->dm.b_one_entry_only) {
328                         offset = 0;
329                         if (dm_dig.rssi_val_min - offset < dm_dig_min)
330                                 dig_dynamic_min = dm_dig_min;
331                         else if (dm_dig.rssi_val_min - offset >
332                                  dig_maxofmin)
333                                 dig_dynamic_min = dig_maxofmin;
334                         else
335                                 dig_dynamic_min = dm_dig.rssi_val_min - offset;
336                 } else {
337                         dig_dynamic_min = dm_dig_min;
338                 }
339
340         } else {
341                 dm_dig.rx_gain_range_max = dm_dig_max;
342                 dig_dynamic_min = dm_dig_min;
343                 RT_TRACE(COMP_DIG, DBG_LOUD, "no link\n");
344         }
345
346         if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
347                 if (dm_dig.large_fa_hit != 3)
348                         dm_dig.large_fa_hit++;
349                 if (dm_dig.forbidden_igi < current_igi) {
350                         dm_dig.forbidden_igi = current_igi;
351                         dm_dig.large_fa_hit = 1;
352                 }
353
354                 if (dm_dig.large_fa_hit >= 3) {
355                         if (dm_dig.forbidden_igi + 1 > dm_dig.rx_gain_range_max)
356                                 dm_dig.rx_gain_range_min =
357                                                 dm_dig.rx_gain_range_max;
358                         else
359                                 dm_dig.rx_gain_range_min =
360                                                 dm_dig.forbidden_igi + 1;
361                         dm_dig.recover_cnt = 3600;
362                 }
363         } else {
364                 if (dm_dig.recover_cnt != 0) {
365                         dm_dig.recover_cnt--;
366                 } else {
367                         if (dm_dig.large_fa_hit < 3) {
368                                 if ((dm_dig.forbidden_igi - 1) <
369                                     dig_dynamic_min) {
370                                         dm_dig.forbidden_igi = dig_dynamic_min;
371                                         dm_dig.rx_gain_range_min =
372                                                                 dig_dynamic_min;
373                                 } else {
374                                         dm_dig.forbidden_igi--;
375                                         dm_dig.rx_gain_range_min =
376                                                 dm_dig.forbidden_igi + 1;
377                                 }
378                         } else {
379                                 dm_dig.large_fa_hit = 0;
380                         }
381                 }
382         }
383
384         if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 5)
385                 dm_dig.rx_gain_range_min = dm_dig_min;
386
387         if (dm_dig.rx_gain_range_min > dm_dig.rx_gain_range_max)
388                 dm_dig.rx_gain_range_min = dm_dig.rx_gain_range_max;
389
390         if (mac->link_state >= MAC80211_LINKED) {
391                 if (bfirstconnect) {
392                         if (dm_dig.rssi_val_min <= dig_maxofmin)
393                                 current_igi = dm_dig.rssi_val_min;
394                         else
395                                 current_igi = dig_maxofmin;
396
397                         dm_dig.large_fa_hit = 0;
398                 } else {
399                         if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
400                                 current_igi += 4;
401                         else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
402                                 current_igi += 2;
403                         else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
404                                 current_igi -= 2;
405
406                         if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 5 &&
407                             rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
408                                 current_igi = dm_dig.rx_gain_range_min;
409                 }
410         } else {
411                 if (bfirstdisconnect) {
412                         current_igi = dm_dig.rx_gain_range_min;
413                 } else {
414                         if (rtlpriv->falsealm_cnt.cnt_all > 10000)
415                                 current_igi += 4;
416                         else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
417                                 current_igi += 2;
418                         else if (rtlpriv->falsealm_cnt.cnt_all < 500)
419                                 current_igi -= 2;
420                 }
421         }
422
423         if (current_igi > dm_dig.rx_gain_range_max)
424                 current_igi = dm_dig.rx_gain_range_max;
425         if (current_igi < dm_dig.rx_gain_range_min)
426                 current_igi = dm_dig.rx_gain_range_min;
427
428         rtl92ee_dm_write_dig(hw , current_igi);
429         dm_dig.b_media_connect_0 = ((mac->link_state >= MAC80211_LINKED) ?
430                                    true : false);
431         dm_dig.dig_dynamic_min_0 = dig_dynamic_min;
432 }
433
434 void rtl92ee_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 cur_thres)
435 {
436         struct rtl_priv *rtlpriv = rtl_priv(hw);
437         if (dm_dig.cur_cck_cca_thres != cur_thres)
438                 rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11N, cur_thres);
439
440         dm_dig.pre_cck_cca_thres = dm_dig.cur_cck_cca_thres;
441         dm_dig.cur_cck_cca_thres = cur_thres;
442 }
443
444 void rtl92ee_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
445 {
446         struct rtl_priv *rtlpriv = rtl_priv(hw);
447         if (dm_dig.stop_dig)
448                 return;
449
450         if (dm_dig.cur_igvalue != current_igi) {
451                 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi);
452                 if (rtlpriv->phy.rf_type != RF_1T1R)
453                         rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, current_igi);
454         }
455         dm_dig.pre_igvalue = dm_dig.cur_igvalue;
456         dm_dig.cur_igvalue = current_igi;
457 }
458
459 static void rtl92ee_rssi_dump_to_register(struct ieee80211_hw *hw)
460 {
461         struct rtl_priv *rtlpriv = rtl_priv(hw);
462         rtl_write_byte(rtlpriv, RA_RSSIDUMP,
463                        rtlpriv->stats.rx_rssi_percentage[0]);
464         rtl_write_byte(rtlpriv, RB_RSSIDUMP,
465                        rtlpriv->stats.rx_rssi_percentage[1]);
466         /*It seems the following values is not initialized.
467           *According to Windows code,
468           *these value will only be valid when JAGUAR chips*/
469         /* Rx EVM */
470         rtl_write_byte(rtlpriv, RS1_RXEVMDUMP, rtlpriv->stats.rx_evm_dbm[0]);
471         rtl_write_byte(rtlpriv, RS2_RXEVMDUMP, rtlpriv->stats.rx_evm_dbm[1]);
472         /* Rx SNR */
473         rtl_write_byte(rtlpriv, RA_RXSNRDUMP,
474                        (u8)(rtlpriv->stats.rx_snr_db[0]));
475         rtl_write_byte(rtlpriv, RB_RXSNRDUMP,
476                        (u8)(rtlpriv->stats.rx_snr_db[1]));
477         /* Rx Cfo_Short */
478         rtl_write_word(rtlpriv, RA_CFOSHORTDUMP,
479                        rtlpriv->stats.rx_cfo_short[0]);
480         rtl_write_word(rtlpriv, RB_CFOSHORTDUMP,
481                        rtlpriv->stats.rx_cfo_short[1]);
482         /* Rx Cfo_Tail */
483         rtl_write_word(rtlpriv, RA_CFOLONGDUMP, rtlpriv->stats.rx_cfo_tail[0]);
484         rtl_write_word(rtlpriv, RB_CFOLONGDUMP, rtlpriv->stats.rx_cfo_tail[1]);
485 }
486
487 static void rtl92ee_dm_find_minimum_rssi(struct ieee80211_hw *hw)
488 {
489         struct rtl_priv *rtlpriv = rtl_priv(hw);
490         struct rtl_dig *rtl_dm_dig = &(rtlpriv->dm.dm_digtable);
491         struct rtl_mac *mac = rtl_mac(rtlpriv);
492
493         /* Determine the minimum RSSI  */
494         if ((mac->link_state < MAC80211_LINKED) &&
495             (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
496                 rtl_dm_dig->min_undecorated_pwdb_for_dm = 0;
497                 RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
498                          "Not connected to any\n");
499         }
500         if (mac->link_state >= MAC80211_LINKED) {
501                 if (mac->opmode == NL80211_IFTYPE_AP ||
502                     mac->opmode == NL80211_IFTYPE_ADHOC) {
503                         rtl_dm_dig->min_undecorated_pwdb_for_dm =
504                                 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
505                         RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
506                                  "AP Client PWDB = 0x%lx\n",
507                                  rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb);
508                 } else {
509                         rtl_dm_dig->min_undecorated_pwdb_for_dm =
510                             rtlpriv->dm.undecorated_smoothed_pwdb;
511                         RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
512                                  "STA Default Port PWDB = 0x%x\n",
513                                  rtl_dm_dig->min_undecorated_pwdb_for_dm);
514                 }
515         } else {
516                 rtl_dm_dig->min_undecorated_pwdb_for_dm =
517                         rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
518                 RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
519                          "AP Ext Port or disconnet PWDB = 0x%x\n",
520                          rtl_dm_dig->min_undecorated_pwdb_for_dm);
521         }
522         RT_TRACE(COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n",
523                  rtl_dm_dig->min_undecorated_pwdb_for_dm);
524 }
525
526 static void rtl92ee_dm_check_rssi_monitor(struct ieee80211_hw *hw)
527 {
528         struct rtl_priv *rtlpriv = rtl_priv(hw);
529         struct rtl_mac *mac = rtl_mac(rtlpriv);
530         struct rtl_dm *dm = rtl_dm(rtlpriv);
531         struct rtl_sta_info *drv_priv;
532         u8 h2c[4] = { 0 };
533         long max = 0, min = 0xff;
534         u8 i = 0;
535
536         if (mac->opmode == NL80211_IFTYPE_AP ||
537             mac->opmode == NL80211_IFTYPE_ADHOC ||
538             mac->opmode == NL80211_IFTYPE_MESH_POINT) {
539                 /* AP & ADHOC & MESH */
540                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
541                 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
542                         struct rssi_sta *stat = &(drv_priv->rssi_stat);
543                         if (stat->undecorated_smoothed_pwdb < min)
544                                 min = stat->undecorated_smoothed_pwdb;
545                         if (stat->undecorated_smoothed_pwdb > max)
546                                 max = stat->undecorated_smoothed_pwdb;
547
548                         h2c[3] = 0;
549                         h2c[2] = (u8) (dm->undecorated_smoothed_pwdb & 0xFF);
550                         h2c[1] = 0x20;
551                         h2c[0] = ++i;
552                         rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c);
553                 }
554                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
555
556                 /* If associated entry is found */
557                 if (max != 0) {
558                         dm->entry_max_undecoratedsmoothed_pwdb = max;
559                         RTPRINT(rtlpriv, FDM, DM_PWDB,
560                                 "EntryMaxPWDB = 0x%lx(%ld)\n", max, max);
561                 } else {
562                         dm->entry_max_undecoratedsmoothed_pwdb = 0;
563                 }
564                 /* If associated entry is found */
565                 if (min != 0xff) {
566                         dm->entry_min_undecoratedsmoothed_pwdb = min;
567                         RTPRINT(rtlpriv, FDM, DM_PWDB,
568                                 "EntryMinPWDB = 0x%lx(%ld)\n", min, min);
569                 } else {
570                         dm->entry_min_undecoratedsmoothed_pwdb = 0;
571                 }
572         }
573
574         /* Indicate Rx signal strength to FW. */
575         if (dm->b_useramask) {
576                 h2c[3] = 0;
577                 h2c[2] = (u8) (dm->undecorated_smoothed_pwdb & 0xFF);
578                 h2c[1] = 0x20;
579                 h2c[0] = 0;
580                 rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c);
581         } else {
582                 rtl_write_byte(rtlpriv, 0x4fe, dm->undecorated_smoothed_pwdb);
583         }
584         rtl92ee_rssi_dump_to_register(hw);
585         rtl92ee_dm_find_minimum_rssi(hw);
586         dm_dig.rssi_val_min = dm->dm_digtable.min_undecorated_pwdb_for_dm;
587 }
588
589 static void rtl92ee_dm_init_primary_cca_check(struct ieee80211_hw *hw)
590 {
591         struct rtl_priv *rtlpriv = rtl_priv(hw);
592         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
593         struct dynamic_primary_cca *primarycca = &(rtlpriv->primarycca);
594
595         rtlhal->rts_en = 0;
596         primarycca->dup_rts_flag = 0;
597         primarycca->intf_flag = 0;
598         primarycca->intf_type = 0;
599         primarycca->monitor_flag = 0;
600         primarycca->ch_offset = 0;
601         primarycca->mf_state = 0;
602 }
603
604 static bool rtl92ee_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
605 {
606         struct rtl_priv *rtlpriv = rtl_priv(hw);
607
608         if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
609                 return true;
610
611         return false;
612 }
613
614 void rtl92ee_dm_init_edca_turbo(struct ieee80211_hw *hw)
615 {
616         struct rtl_priv *rtlpriv = rtl_priv(hw);
617
618         rtlpriv->dm.bcurrent_turbo_edca = false;
619         rtlpriv->dm.bis_cur_rdlstate = false;
620         rtlpriv->dm.bis_any_nonbepkts = false;
621 }
622
623 static void rtl92ee_dm_check_edca_turbo(struct ieee80211_hw *hw)
624 {
625         struct rtl_priv *rtlpriv = rtl_priv(hw);
626
627         static u64 last_txok_cnt;
628         static u64 last_rxok_cnt;
629         u64 cur_txok_cnt = 0;
630         u64 cur_rxok_cnt = 0;
631         u32 edca_be_ul = 0x5ea42b;
632         u32 edca_be_dl = 0x5ea42b; /*not sure*/
633         u32 edca_be = 0x5ea42b;
634         bool b_is_cur_rdlstate;
635         bool b_edca_turbo_on = false;
636
637         if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100)
638                 rtlpriv->dm.bis_any_nonbepkts = true;
639         rtlpriv->dm.dbginfo.num_non_be_pkt = 0;
640
641         cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
642         cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
643
644         /*b_bias_on_rx = false;*/
645         b_edca_turbo_on = ((!rtlpriv->dm.bis_any_nonbepkts) &&
646                            (!rtlpriv->dm.b_disable_framebursting)) ?
647                           true : false;
648
649         if (rtl92ee_dm_is_edca_turbo_disable(hw))
650                 goto dm_CheckEdcaTurbo_EXIT;
651
652         if (b_edca_turbo_on) {
653                 b_is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ?
654                                     true : false;
655
656                 edca_be = b_is_cur_rdlstate ? edca_be_dl : edca_be_ul;
657                 rtl_write_dword(rtlpriv , REG_EDCA_BE_PARAM , edca_be);
658                 rtlpriv->dm.bis_cur_rdlstate = b_is_cur_rdlstate;
659                 rtlpriv->dm.bcurrent_turbo_edca = true;
660         } else {
661                 if (rtlpriv->dm.bcurrent_turbo_edca) {
662                         u8 tmp = AC0_BE;
663                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
664                                                       (u8 *) (&tmp));
665                 }
666                 rtlpriv->dm.bcurrent_turbo_edca = false;
667         }
668
669 dm_CheckEdcaTurbo_EXIT:
670         rtlpriv->dm.bis_any_nonbepkts = false;
671         last_txok_cnt = rtlpriv->stats.txbytesunicast;
672         last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
673 }
674
675 static void rtl92ee_dm_dynamic_edcca(struct ieee80211_hw *hw)
676 {
677         struct rtl_priv *rtlpriv = rtl_priv(hw);
678         u8 reg_c50 , reg_c58;
679         bool b_fw_current_in_ps_mode = false;
680
681         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
682                                       (u8 *)(&b_fw_current_in_ps_mode));
683         if (b_fw_current_in_ps_mode)
684                 return;
685
686         reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
687         reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
688
689         if (reg_c50 > 0x28 && reg_c58 > 0x28) {
690                 if (!rtlpriv->rtlhal.b_pre_edcca_enable) {
691                         rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03);
692                         rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00);
693                         rtlpriv->rtlhal.b_pre_edcca_enable = true;
694                 }
695         } else if (reg_c50 < 0x25 && reg_c58 < 0x25) {
696                 if (rtlpriv->rtlhal.b_pre_edcca_enable) {
697                         rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f);
698                         rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f);
699                         rtlpriv->rtlhal.b_pre_edcca_enable = false;
700                 }
701         }
702 }
703
704 static void rtl92ee_dm_adaptivity(struct ieee80211_hw *hw)
705 {
706         rtl92ee_dm_dynamic_edcca(hw);
707 }
708
709 static void rtl92ee_dm_write_dynamic_cca(struct ieee80211_hw *hw, u8 cur_mf_state)
710 {
711         struct dynamic_primary_cca *primarycca = &(rtl_priv(hw)->primarycca);
712
713         if (primarycca->mf_state != cur_mf_state)
714                 rtl_set_bbreg(hw, DM_REG_L1SBD_PD_CH_11N, BIT(8) | BIT(7),
715                               cur_mf_state);
716
717         primarycca->mf_state = cur_mf_state;
718 }
719
720 static void rtl92ee_dm_dynamic_primary_cca_ckeck(struct ieee80211_hw *hw)
721 {
722         struct rtl_priv *rtlpriv = rtl_priv(hw);
723         struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
724         struct dynamic_primary_cca *primarycca = &(rtlpriv->primarycca);
725         bool is40mhz = false;
726         u64 ofdm_cca, ofdm_fa, bw_usc_cnt, bw_lsc_cnt;
727         u8 sec_ch_offset;
728         u8 cur_mf_state;
729         static u8 count_down = MONITOR_TIME;
730
731         ofdm_cca = falsealm_cnt->cnt_ofdm_cca;
732         ofdm_fa = falsealm_cnt->cnt_ofdm_fail;
733         bw_usc_cnt = falsealm_cnt->cnt_bw_usc;
734         bw_lsc_cnt = falsealm_cnt->cnt_bw_lsc;
735         is40mhz = rtlpriv->mac80211.bw_40;
736         sec_ch_offset = rtlpriv->mac80211.cur_40_prime_sc;
737         /* NIC: 2: sec is below,  1: sec is above */
738
739         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) {
740                 cur_mf_state = MF_USC_LSC;
741                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
742                 return;
743         }
744
745         if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
746                 return;
747
748         if (is40mhz)
749                 return;
750
751         if (primarycca->pricca_flag == 0) {
752                 /* Primary channel is above
753                  * NOTE: duplicate CTS can remove this condition*/
754                 if (sec_ch_offset == 2) {
755                         if ((ofdm_cca > OFDMCCA_TH) &&
756                             (bw_lsc_cnt > (bw_usc_cnt + BW_IND_BIAS)) &&
757                             (ofdm_fa > (ofdm_cca >> 1))) {
758                                 primarycca->intf_type = 1;
759                                 primarycca->intf_flag = 1;
760                                 cur_mf_state = MF_USC;
761                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
762                                 primarycca->pricca_flag = 1;
763                         } else if ((ofdm_cca > OFDMCCA_TH) &&
764                                    (bw_lsc_cnt > (bw_usc_cnt + BW_IND_BIAS)) &&
765                                    (ofdm_fa < (ofdm_cca >> 1))) {
766                                 primarycca->intf_type = 2;
767                                 primarycca->intf_flag = 1;
768                                 cur_mf_state = MF_USC;
769                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
770                                 primarycca->pricca_flag = 1;
771                                 primarycca->dup_rts_flag = 1;
772                                 rtlpriv->rtlhal.rts_en = 1;
773                         } else {
774                                 primarycca->intf_type = 0;
775                                 primarycca->intf_flag = 0;
776                                 cur_mf_state = MF_USC_LSC;
777                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
778                                 rtlpriv->rtlhal.rts_en = 0;
779                                 primarycca->dup_rts_flag = 0;
780                         }
781                 } else if (sec_ch_offset == 1) {
782                         if ((ofdm_cca > OFDMCCA_TH) &&
783                             (bw_usc_cnt > (bw_lsc_cnt + BW_IND_BIAS)) &&
784                             (ofdm_fa > (ofdm_cca >> 1))) {
785                                 primarycca->intf_type = 1;
786                                 primarycca->intf_flag = 1;
787                                 cur_mf_state = MF_LSC;
788                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
789                                 primarycca->pricca_flag = 1;
790                         } else if ((ofdm_cca > OFDMCCA_TH) &&
791                                    (bw_usc_cnt > (bw_lsc_cnt + BW_IND_BIAS)) &&
792                                    (ofdm_fa < (ofdm_cca >> 1))) {
793                                 primarycca->intf_type = 2;
794                                 primarycca->intf_flag = 1;
795                                 cur_mf_state = MF_LSC;
796                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
797                                 primarycca->pricca_flag = 1;
798                                 primarycca->dup_rts_flag = 1;
799                                 rtlpriv->rtlhal.rts_en = 1;
800                         } else {
801                                 primarycca->intf_type = 0;
802                                 primarycca->intf_flag = 0;
803                                 cur_mf_state = MF_USC_LSC;
804                                 rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
805                                 rtlpriv->rtlhal.rts_en = 0;
806                                 primarycca->dup_rts_flag = 0;
807                         }
808                 }
809         } else {/* PrimaryCCA->PriCCA_flag == 1 */
810                 count_down--;
811                 if (count_down == 0) {
812                         count_down = MONITOR_TIME;
813                         primarycca->pricca_flag = 0;
814                         cur_mf_state = MF_USC_LSC;
815                         /* default */
816                         rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
817                         rtlpriv->rtlhal.rts_en = 0;
818                         primarycca->dup_rts_flag = 0;
819                         primarycca->intf_type = 0;
820                         primarycca->intf_flag = 0;
821                 }
822         }
823 }
824
825 static void rtl92ee_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
826 {
827         struct rtl_priv *rtlpriv = rtl_priv(hw);
828         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
829         u8 crystal_cap;
830         u32 packet_count;
831         int cfo_khz_a , cfo_khz_b , cfo_ave = 0, adjust_xtal = 0;
832         int cfo_ave_diff;
833
834         if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
835                 if (rtldm->atc_status == ATC_STATUS_OFF) {
836                         rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
837                                       ATC_STATUS_ON);
838                         rtldm->atc_status = ATC_STATUS_ON;
839                 }
840                 /* Disable CFO tracking for BT */
841                 if (rtlpriv->cfg->ops->get_btc_status()) {
842                         if (!rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled(rtlpriv)) {
843                                 RT_TRACE(COMP_BT_COEXIST, DBG_LOUD,
844                                          "odm_DynamicATCSwitch(): Disable CFO tracking for BT!!\n");
845                                 return;
846                         }
847                 }
848                 /* Reset Crystal Cap */
849                 if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
850                         rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
851                         crystal_cap = rtldm->crystal_cap & 0x3f;
852                         rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
853                                       (crystal_cap | (crystal_cap << 6)));
854                 }
855         } else {
856                 cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
857                 cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
858                 packet_count = rtldm->packet_count;
859
860                 if (packet_count == rtldm->packet_count_pre)
861                         return;
862
863                 rtldm->packet_count_pre = packet_count;
864
865                 if (rtlpriv->phy.rf_type == RF_1T1R)
866                         cfo_ave = cfo_khz_a;
867                 else
868                         cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1;
869
870                 cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
871                                (rtldm->cfo_ave_pre - cfo_ave) :
872                                (cfo_ave - rtldm->cfo_ave_pre);
873
874                 if (cfo_ave_diff > 20 && rtldm->large_cfo_hit == 0) {
875                         rtldm->large_cfo_hit = 1;
876                         return;
877                 } else {
878                         rtldm->large_cfo_hit = 0;
879                 }
880
881                 rtldm->cfo_ave_pre = cfo_ave;
882
883                 if (cfo_ave >= -rtldm->cfo_threshold &&
884                     cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) {
885                         if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
886                                 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
887                                 rtldm->is_freeze = 1;
888                         } else {
889                                 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
890                         }
891                 }
892
893                 if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
894                         adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1;
895                 else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
896                          rtlpriv->dm.crystal_cap > 0)
897                         adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1;
898
899                 if (adjust_xtal != 0) {
900                         rtldm->is_freeze = 0;
901                         rtldm->crystal_cap += adjust_xtal;
902
903                         if (rtldm->crystal_cap > 0x3f)
904                                 rtldm->crystal_cap = 0x3f;
905                         else if (rtldm->crystal_cap < 0)
906                                 rtldm->crystal_cap = 0;
907
908                         crystal_cap = rtldm->crystal_cap & 0x3f;
909                         rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
910                                       (crystal_cap | (crystal_cap << 6)));
911                 }
912
913                 if (cfo_ave < CFO_THRESHOLD_ATC &&
914                     cfo_ave > -CFO_THRESHOLD_ATC) {
915                         if (rtldm->atc_status == ATC_STATUS_ON) {
916                                 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
917                                               ATC_STATUS_OFF);
918                                 rtldm->atc_status = ATC_STATUS_OFF;
919                         }
920                 } else {
921                         if (rtldm->atc_status == ATC_STATUS_OFF) {
922                                 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
923                                               ATC_STATUS_ON);
924                                 rtldm->atc_status = ATC_STATUS_ON;
925                         }
926                 }
927         }
928 }
929
930 static void rtl92ee_dm_init_txpower_tracking(struct ieee80211_hw *hw)
931 {
932         struct rtl_priv *rtlpriv = rtl_priv(hw);
933         struct rtl_dm *dm = rtl_dm(rtlpriv);
934         u8 path;
935
936         dm->btxpower_tracking = true;
937         dm->default_ofdm_index = 30;
938         dm->default_cck_index = 20;
939
940         dm->bb_swing_idx_cck_base = dm->default_cck_index;
941         dm->cck_index = dm->default_cck_index;
942
943         for (path = RF90_PATH_A; path < MAX_RF_PATH; path++) {
944                 dm->bb_swing_idx_ofdm_base[path] = dm->default_ofdm_index;
945                 dm->ofdm_index[path] = dm->default_ofdm_index;
946                 dm->delta_power_index[path] = 0;
947                 dm->delta_power_index_last[path] = 0;
948                 dm->power_index_offset[path] = 0;
949         }
950 }
951
952 void rtl92ee_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
953 {
954         struct rtl_priv *rtlpriv = rtl_priv(hw);
955         struct rate_adaptive *p_ra = &(rtlpriv->ra);
956
957         p_ra->ratr_state = DM_RATR_STA_INIT;
958         p_ra->pre_ratr_state = DM_RATR_STA_INIT;
959
960         if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
961                 rtlpriv->dm.b_useramask = true;
962         else
963                 rtlpriv->dm.b_useramask = false;
964
965         p_ra->ldpc_thres = 35;
966         p_ra->use_ldpc = false;
967         p_ra->high_rssi_thresh_for_ra = 50;
968         p_ra->low_rssi_thresh_for_ra = 20;
969
970 }
971
972 static bool _rtl92ee_dm_ra_state_check(struct ieee80211_hw *hw,
973                                       s32 rssi, u8 *ratr_state)
974 {
975         struct rtl_priv *rtlpriv = rtl_priv(hw);
976         struct rate_adaptive *p_ra = &(rtlpriv->ra);
977         const u8 go_up_gap = 5;
978         u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
979         u32 low_rssithresh_for_ra = p_ra->low_rssi_thresh_for_ra;
980         u8 state;
981
982         /* Threshold Adjustment:
983          * when RSSI state trends to go up one or two levels,
984          * make sure RSSI is high enough.
985          * Here GoUpGap is added to solve
986          * the boundary's level alternation issue.
987          */
988         switch (*ratr_state) {
989         case DM_RATR_STA_INIT:
990         case DM_RATR_STA_HIGH:
991                         break;
992
993         case DM_RATR_STA_MIDDLE:
994                         high_rssithresh_for_ra += go_up_gap;
995                         break;
996
997         case DM_RATR_STA_LOW:
998                         high_rssithresh_for_ra += go_up_gap;
999                         low_rssithresh_for_ra += go_up_gap;
1000                         break;
1001
1002         default:
1003                         RT_TRACE(COMP_RATR, DBG_DMESG,
1004                                  "wrong rssi level setting %d !\n",
1005                                  *ratr_state);
1006                         break;
1007         }
1008
1009         /* Decide RATRState by RSSI. */
1010         if (rssi > high_rssithresh_for_ra)
1011                 state = DM_RATR_STA_HIGH;
1012         else if (rssi > low_rssithresh_for_ra)
1013                 state = DM_RATR_STA_MIDDLE;
1014         else
1015                 state = DM_RATR_STA_LOW;
1016
1017         if (*ratr_state != state) {
1018                 *ratr_state = state;
1019                 return true;
1020         }
1021
1022         return false;
1023 }
1024
1025 static void rtl92ee_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
1026 {
1027         struct rtl_priv *rtlpriv = rtl_priv(hw);
1028         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1029         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1030         struct rate_adaptive *p_ra = &(rtlpriv->ra);
1031         struct ieee80211_sta *sta = NULL;
1032
1033         if (is_hal_stop(rtlhal)) {
1034                 RT_TRACE(COMP_RATE, DBG_LOUD, "driver is going to unload\n");
1035                 return;
1036         }
1037
1038         if (!rtlpriv->dm.b_useramask) {
1039                 RT_TRACE(COMP_RATE, DBG_LOUD,
1040                          "driver does not control rate adaptive mask\n");
1041                 return;
1042         }
1043
1044         if (mac->link_state == MAC80211_LINKED &&
1045                 mac->opmode == NL80211_IFTYPE_STATION) {
1046
1047                 if (rtlpriv->dm.undecorated_smoothed_pwdb < p_ra->ldpc_thres) {
1048                         p_ra->use_ldpc = true;
1049                         p_ra->lower_rts_rate = true;
1050                 } else if (rtlpriv->dm.undecorated_smoothed_pwdb >
1051                            (p_ra->ldpc_thres - 5)) {
1052                         p_ra->use_ldpc = false;
1053                         p_ra->lower_rts_rate = false;
1054                 }
1055                 if (_rtl92ee_dm_ra_state_check(hw,
1056                                         rtlpriv->dm.undecorated_smoothed_pwdb,
1057                                         &(p_ra->ratr_state))) {
1058
1059                         rcu_read_lock();
1060                         sta = rtl_find_sta(hw, mac->bssid);
1061                         if (sta)
1062                                 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1063                                                               p_ra->ratr_state);
1064                         rcu_read_unlock();
1065
1066                         p_ra->pre_ratr_state = p_ra->ratr_state;
1067                 }
1068         }
1069 }
1070
1071 static void rtl92ee_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
1072 {
1073         struct rtl_priv *rtlpriv = rtl_priv(hw);
1074
1075         rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
1076
1077         rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11));
1078         rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
1079 }
1080
1081 void rtl92ee_dm_init(struct ieee80211_hw *hw)
1082 {
1083         struct rtl_priv *rtlpriv = rtl_priv(hw);
1084
1085         rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1086
1087         rtl92ee_dm_diginit(hw);
1088         rtl92ee_dm_init_rate_adaptive_mask(hw);
1089         rtl92ee_dm_init_primary_cca_check(hw);
1090         rtl92ee_dm_init_edca_turbo(hw);
1091         rtl92ee_dm_init_txpower_tracking(hw);
1092         rtl92ee_dm_init_dynamic_atc_switch(hw);
1093 }
1094
1095 static void rtl92ee_dm_common_info_self_update(struct ieee80211_hw *hw)
1096 {
1097         struct rtl_priv *rtlpriv = rtl_priv(hw);
1098         u8 cnt = 0;
1099         struct rtl_sta_info *drv_priv;
1100
1101         rtlpriv->dm.b_one_entry_only = false;
1102
1103         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
1104                 rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1105                 rtlpriv->dm.b_one_entry_only = true;
1106                 return;
1107         }
1108
1109         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1110             rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
1111             rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
1112                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1113                 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
1114                         cnt++;
1115                 }
1116                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1117
1118                 if (cnt == 1)
1119                         rtlpriv->dm.b_one_entry_only = true;
1120         }
1121 }
1122
1123 void rtl92ee_dm_dynamic_arfb_select(struct ieee80211_hw *hw,
1124                                     u8 rate, bool collision_state)
1125 {
1126         struct rtl_priv *rtlpriv = rtl_priv(hw);
1127
1128         if (rate >= DESC92C_RATEMCS8  && rate <= DESC92C_RATEMCS12) {
1129                 if (collision_state == 1) {
1130                         if (rate == DESC92C_RATEMCS12) {
1131                                 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1132                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1133                                                 0x07060501);
1134                         } else if (rate == DESC92C_RATEMCS11) {
1135                                 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1136                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1137                                                 0x07070605);
1138                         } else if (rate == DESC92C_RATEMCS10) {
1139                                 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1140                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1141                                                 0x08080706);
1142                         } else if (rate == DESC92C_RATEMCS9) {
1143                                 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1144                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1145                                                 0x08080707);
1146                         } else {
1147                                 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1148                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1149                                                 0x09090808);
1150                         }
1151                 } else {   /* collision_state == 0 */
1152                         if (rate == DESC92C_RATEMCS12) {
1153                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1154                                                 0x05010000);
1155                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1156                                                 0x09080706);
1157                         } else if (rate == DESC92C_RATEMCS11) {
1158                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1159                                                 0x06050000);
1160                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1161                                                 0x09080807);
1162                         } else if (rate == DESC92C_RATEMCS10) {
1163                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1164                                                 0x07060000);
1165                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1166                                                 0x0a090908);
1167                         } else if (rate == DESC92C_RATEMCS9) {
1168                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1169                                                 0x07070000);
1170                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1171                                                 0x0a090808);
1172                         } else {
1173                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1174                                                 0x08080000);
1175                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1176                                                 0x0b0a0909);
1177                         }
1178                 }
1179         } else {  /* MCS13~MCS15,  1SS, G-mode */
1180                 if (collision_state == 1) {
1181                         if (rate == DESC92C_RATEMCS15) {
1182                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1183                                                 0x00000000);
1184                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1185                                                 0x05040302);
1186                         } else if (rate == DESC92C_RATEMCS14) {
1187                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1188                                                 0x00000000);
1189                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1190                                                 0x06050302);
1191                         } else if (rate == DESC92C_RATEMCS13) {
1192                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1193                                                 0x00000000);
1194                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1195                                                 0x07060502);
1196                         } else {
1197                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1198                                                 0x00000000);
1199                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1200                                                 0x06050402);
1201                         }
1202                 } else{   /* collision_state == 0 */
1203                         if (rate == DESC92C_RATEMCS15) {
1204                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1205                                                 0x03020000);
1206                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1207                                                 0x07060504);
1208                         } else if (rate == DESC92C_RATEMCS14) {
1209                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1210                                                 0x03020000);
1211                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1212                                                 0x08070605);
1213                         } else if (rate == DESC92C_RATEMCS13) {
1214                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1215                                                 0x05020000);
1216                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1217                                                 0x09080706);
1218                         } else {
1219                                 rtl_write_dword(rtlpriv, REG_DARFRC,
1220                                                 0x04020000);
1221                                 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1222                                                 0x08070605);
1223                         }
1224                 }
1225         }
1226 }
1227
1228 void rtl92ee_dm_watchdog(struct ieee80211_hw *hw)
1229 {
1230         struct rtl_priv *rtlpriv = rtl_priv(hw);
1231         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1232         bool b_fw_current_inpsmode = false;
1233         bool b_fw_ps_awake = true;
1234
1235         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1236                                       (u8 *) (&b_fw_current_inpsmode));
1237         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1238                                       (u8 *) (&b_fw_ps_awake));
1239         if (ppsc->p2p_ps_info.p2p_ps_mode)
1240                 b_fw_ps_awake = false;
1241
1242         if ((ppsc->rfpwr_state == ERFON) &&
1243             ((!b_fw_current_inpsmode) && b_fw_ps_awake) &&
1244             (!ppsc->rfchange_inprogress)) {
1245                 rtl92ee_dm_common_info_self_update(hw);
1246                 rtl92ee_dm_false_alarm_counter_statistics(hw);
1247                 rtl92ee_dm_check_rssi_monitor(hw);
1248                 rtl92ee_dm_dig(hw);
1249                 rtl92ee_dm_adaptivity(hw);
1250                 rtl92ee_dm_cck_packet_detection_thresh(hw);
1251                 rtl92ee_dm_refresh_rate_adaptive_mask(hw);
1252                 rtl92ee_dm_check_edca_turbo(hw);
1253                 rtl92ee_dm_dynamic_atc_switch(hw);
1254                 rtl92ee_dm_dynamic_primary_cca_ckeck(hw);
1255         }
1256 }