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