1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
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.
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
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
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 */
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 */
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 */
156 static void rtl92ee_dm_diginit(struct ieee80211_hw *hw)
158 struct rtl_priv *rtlpriv = rtl_priv(hw);
159 dm_dig.cur_igvalue = rtl_get_bbreg(hw, DM_REG_IGI_A_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;
183 static void rtl92ee_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
186 struct rtl_priv *rtlpriv = rtl_priv(hw);
187 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
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);
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);
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);
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);
204 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
205 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
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;
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);
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);
221 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_LSB_11N, MASKBYTE0);
222 falsealm_cnt->cnt_cck_fail = ret_value;
224 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3);
225 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
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);
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;
239 falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
240 falsealm_cnt->cnt_cck_cca;
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);
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);
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);
270 static void rtl92ee_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
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;
281 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
282 cur_cck_cca_thresh = 0x83;
284 cur_cck_cca_thresh = 0x40;
287 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
288 cur_cck_cca_thresh = 0x83;
290 cur_cck_cca_thresh = 0x40;
292 rtl92ee_dm_write_cck_cca_thres(hw, cur_cck_cca_thresh);
295 static void rtl92ee_dm_dig(struct ieee80211_hw *hw)
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;
306 if (mac->act_scanning == true)
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);
316 dm_dig_min = DM_DIG_MIN;
317 dig_maxofmin = DM_DIG_MAX_AP;
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;
325 dm_dig.rx_gain_range_max = dm_dig.rssi_val_min + 10;
327 if (rtlpriv->dm.b_one_entry_only) {
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 >
333 dig_dynamic_min = dig_maxofmin;
335 dig_dynamic_min = dm_dig.rssi_val_min - offset;
337 dig_dynamic_min = dm_dig_min;
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");
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;
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;
359 dm_dig.rx_gain_range_min =
360 dm_dig.forbidden_igi + 1;
361 dm_dig.recover_cnt = 3600;
364 if (dm_dig.recover_cnt != 0) {
365 dm_dig.recover_cnt--;
367 if (dm_dig.large_fa_hit < 3) {
368 if ((dm_dig.forbidden_igi - 1) <
370 dm_dig.forbidden_igi = dig_dynamic_min;
371 dm_dig.rx_gain_range_min =
374 dm_dig.forbidden_igi--;
375 dm_dig.rx_gain_range_min =
376 dm_dig.forbidden_igi + 1;
379 dm_dig.large_fa_hit = 0;
384 if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 5)
385 dm_dig.rx_gain_range_min = dm_dig_min;
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;
390 if (mac->link_state >= MAC80211_LINKED) {
392 if (dm_dig.rssi_val_min <= dig_maxofmin)
393 current_igi = dm_dig.rssi_val_min;
395 current_igi = dig_maxofmin;
397 dm_dig.large_fa_hit = 0;
399 if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
401 else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
403 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
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;
411 if (bfirstdisconnect) {
412 current_igi = dm_dig.rx_gain_range_min;
414 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
416 else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
418 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
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;
428 rtl92ee_dm_write_dig(hw , current_igi);
429 dm_dig.b_media_connect_0 = ((mac->link_state >= MAC80211_LINKED) ?
431 dm_dig.dig_dynamic_min_0 = dig_dynamic_min;
434 void rtl92ee_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 cur_thres)
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);
440 dm_dig.pre_cck_cca_thres = dm_dig.cur_cck_cca_thres;
441 dm_dig.cur_cck_cca_thres = cur_thres;
444 void rtl92ee_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
446 struct rtl_priv *rtlpriv = rtl_priv(hw);
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);
455 dm_dig.pre_igvalue = dm_dig.cur_igvalue;
456 dm_dig.cur_igvalue = current_igi;
459 static void rtl92ee_rssi_dump_to_register(struct ieee80211_hw *hw)
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*/
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]);
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]));
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]);
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]);
487 static void rtl92ee_dm_find_minimum_rssi(struct ieee80211_hw *hw)
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);
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");
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);
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);
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);
522 RT_TRACE(COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n",
523 rtl_dm_dig->min_undecorated_pwdb_for_dm);
526 static void rtl92ee_dm_check_rssi_monitor(struct ieee80211_hw *hw)
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;
533 long max = 0, min = 0xff;
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;
549 h2c[2] = (u8) (dm->undecorated_smoothed_pwdb & 0xFF);
552 rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c);
554 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
556 /* If associated entry is found */
558 dm->entry_max_undecoratedsmoothed_pwdb = max;
559 RTPRINT(rtlpriv, FDM, DM_PWDB,
560 "EntryMaxPWDB = 0x%lx(%ld)\n", max, max);
562 dm->entry_max_undecoratedsmoothed_pwdb = 0;
564 /* If associated entry is found */
566 dm->entry_min_undecoratedsmoothed_pwdb = min;
567 RTPRINT(rtlpriv, FDM, DM_PWDB,
568 "EntryMinPWDB = 0x%lx(%ld)\n", min, min);
570 dm->entry_min_undecoratedsmoothed_pwdb = 0;
574 /* Indicate Rx signal strength to FW. */
575 if (dm->b_useramask) {
577 h2c[2] = (u8) (dm->undecorated_smoothed_pwdb & 0xFF);
580 rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c);
582 rtl_write_byte(rtlpriv, 0x4fe, dm->undecorated_smoothed_pwdb);
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;
589 static void rtl92ee_dm_init_primary_cca_check(struct ieee80211_hw *hw)
591 struct rtl_priv *rtlpriv = rtl_priv(hw);
592 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
593 struct dynamic_primary_cca *primarycca = &(rtlpriv->primarycca);
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;
604 static bool rtl92ee_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
606 struct rtl_priv *rtlpriv = rtl_priv(hw);
608 if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
614 void rtl92ee_dm_init_edca_turbo(struct ieee80211_hw *hw)
616 struct rtl_priv *rtlpriv = rtl_priv(hw);
618 rtlpriv->dm.bcurrent_turbo_edca = false;
619 rtlpriv->dm.bis_cur_rdlstate = false;
620 rtlpriv->dm.bis_any_nonbepkts = false;
623 static void rtl92ee_dm_check_edca_turbo(struct ieee80211_hw *hw)
625 struct rtl_priv *rtlpriv = rtl_priv(hw);
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;
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;
641 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
642 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
644 /*b_bias_on_rx = false;*/
645 b_edca_turbo_on = ((!rtlpriv->dm.bis_any_nonbepkts) &&
646 (!rtlpriv->dm.b_disable_framebursting)) ?
649 if (rtl92ee_dm_is_edca_turbo_disable(hw))
650 goto dm_CheckEdcaTurbo_EXIT;
652 if (b_edca_turbo_on) {
653 b_is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ?
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;
661 if (rtlpriv->dm.bcurrent_turbo_edca) {
663 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
666 rtlpriv->dm.bcurrent_turbo_edca = false;
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;
675 static void rtl92ee_dm_dynamic_edcca(struct ieee80211_hw *hw)
677 struct rtl_priv *rtlpriv = rtl_priv(hw);
678 u8 reg_c50 , reg_c58;
679 bool b_fw_current_in_ps_mode = false;
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)
686 reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
687 reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
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;
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;
704 static void rtl92ee_dm_adaptivity(struct ieee80211_hw *hw)
706 rtl92ee_dm_dynamic_edcca(hw);
709 static void rtl92ee_dm_write_dynamic_cca(struct ieee80211_hw *hw, u8 cur_mf_state)
711 struct dynamic_primary_cca *primarycca = &(rtl_priv(hw)->primarycca);
713 if (primarycca->mf_state != cur_mf_state)
714 rtl_set_bbreg(hw, DM_REG_L1SBD_PD_CH_11N, BIT(8) | BIT(7),
717 primarycca->mf_state = cur_mf_state;
720 static void rtl92ee_dm_dynamic_primary_cca_ckeck(struct ieee80211_hw *hw)
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;
729 static u8 count_down = MONITOR_TIME;
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 */
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);
745 if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
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;
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;
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;
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;
809 } else {/* PrimaryCCA->PriCCA_flag == 1 */
811 if (count_down == 0) {
812 count_down = MONITOR_TIME;
813 primarycca->pricca_flag = 0;
814 cur_mf_state = MF_USC_LSC;
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;
825 static void rtl92ee_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
827 struct rtl_priv *rtlpriv = rtl_priv(hw);
828 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
831 int cfo_khz_a , cfo_khz_b , cfo_ave = 0, adjust_xtal = 0;
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),
838 rtldm->atc_status = ATC_STATUS_ON;
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");
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)));
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;
860 if (packet_count == rtldm->packet_count_pre)
863 rtldm->packet_count_pre = packet_count;
865 if (rtlpriv->phy.rf_type == RF_1T1R)
868 cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1;
870 cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
871 (rtldm->cfo_ave_pre - cfo_ave) :
872 (cfo_ave - rtldm->cfo_ave_pre);
874 if (cfo_ave_diff > 20 && rtldm->large_cfo_hit == 0) {
875 rtldm->large_cfo_hit = 1;
878 rtldm->large_cfo_hit = 0;
881 rtldm->cfo_ave_pre = cfo_ave;
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;
889 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
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;
899 if (adjust_xtal != 0) {
900 rtldm->is_freeze = 0;
901 rtldm->crystal_cap += adjust_xtal;
903 if (rtldm->crystal_cap > 0x3f)
904 rtldm->crystal_cap = 0x3f;
905 else if (rtldm->crystal_cap < 0)
906 rtldm->crystal_cap = 0;
908 crystal_cap = rtldm->crystal_cap & 0x3f;
909 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
910 (crystal_cap | (crystal_cap << 6)));
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),
918 rtldm->atc_status = ATC_STATUS_OFF;
921 if (rtldm->atc_status == ATC_STATUS_OFF) {
922 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
924 rtldm->atc_status = ATC_STATUS_ON;
930 static void rtl92ee_dm_init_txpower_tracking(struct ieee80211_hw *hw)
932 struct rtl_priv *rtlpriv = rtl_priv(hw);
933 struct rtl_dm *dm = rtl_dm(rtlpriv);
936 dm->btxpower_tracking = true;
937 dm->default_ofdm_index = 30;
938 dm->default_cck_index = 20;
940 dm->bb_swing_idx_cck_base = dm->default_cck_index;
941 dm->cck_index = dm->default_cck_index;
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;
952 void rtl92ee_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
954 struct rtl_priv *rtlpriv = rtl_priv(hw);
955 struct rate_adaptive *p_ra = &(rtlpriv->ra);
957 p_ra->ratr_state = DM_RATR_STA_INIT;
958 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
960 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
961 rtlpriv->dm.b_useramask = true;
963 rtlpriv->dm.b_useramask = false;
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;
972 static bool _rtl92ee_dm_ra_state_check(struct ieee80211_hw *hw,
973 s32 rssi, u8 *ratr_state)
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;
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.
988 switch (*ratr_state) {
989 case DM_RATR_STA_INIT:
990 case DM_RATR_STA_HIGH:
993 case DM_RATR_STA_MIDDLE:
994 high_rssithresh_for_ra += go_up_gap;
997 case DM_RATR_STA_LOW:
998 high_rssithresh_for_ra += go_up_gap;
999 low_rssithresh_for_ra += go_up_gap;
1003 RT_TRACE(COMP_RATR, DBG_DMESG,
1004 "wrong rssi level setting %d !\n",
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;
1015 state = DM_RATR_STA_LOW;
1017 if (*ratr_state != state) {
1018 *ratr_state = state;
1025 static void rtl92ee_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
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;
1033 if (is_hal_stop(rtlhal)) {
1034 RT_TRACE(COMP_RATE, DBG_LOUD, "driver is going to unload\n");
1038 if (!rtlpriv->dm.b_useramask) {
1039 RT_TRACE(COMP_RATE, DBG_LOUD,
1040 "driver does not control rate adaptive mask\n");
1044 if (mac->link_state == MAC80211_LINKED &&
1045 mac->opmode == NL80211_IFTYPE_STATION) {
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;
1055 if (_rtl92ee_dm_ra_state_check(hw,
1056 rtlpriv->dm.undecorated_smoothed_pwdb,
1057 &(p_ra->ratr_state))) {
1060 sta = rtl_find_sta(hw, mac->bssid);
1062 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1066 p_ra->pre_ratr_state = p_ra->ratr_state;
1071 static void rtl92ee_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
1073 struct rtl_priv *rtlpriv = rtl_priv(hw);
1075 rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
1077 rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11));
1078 rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
1081 void rtl92ee_dm_init(struct ieee80211_hw *hw)
1083 struct rtl_priv *rtlpriv = rtl_priv(hw);
1085 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
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);
1095 static void rtl92ee_dm_common_info_self_update(struct ieee80211_hw *hw)
1097 struct rtl_priv *rtlpriv = rtl_priv(hw);
1099 struct rtl_sta_info *drv_priv;
1101 rtlpriv->dm.b_one_entry_only = false;
1103 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
1104 rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1105 rtlpriv->dm.b_one_entry_only = true;
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) {
1116 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1119 rtlpriv->dm.b_one_entry_only = true;
1123 void rtl92ee_dm_dynamic_arfb_select(struct ieee80211_hw *hw,
1124 u8 rate, bool collision_state)
1126 struct rtl_priv *rtlpriv = rtl_priv(hw);
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,
1134 } else if (rate == DESC92C_RATEMCS11) {
1135 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1136 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1138 } else if (rate == DESC92C_RATEMCS10) {
1139 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1140 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1142 } else if (rate == DESC92C_RATEMCS9) {
1143 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1144 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1147 rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
1148 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1151 } else { /* collision_state == 0 */
1152 if (rate == DESC92C_RATEMCS12) {
1153 rtl_write_dword(rtlpriv, REG_DARFRC,
1155 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1157 } else if (rate == DESC92C_RATEMCS11) {
1158 rtl_write_dword(rtlpriv, REG_DARFRC,
1160 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1162 } else if (rate == DESC92C_RATEMCS10) {
1163 rtl_write_dword(rtlpriv, REG_DARFRC,
1165 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1167 } else if (rate == DESC92C_RATEMCS9) {
1168 rtl_write_dword(rtlpriv, REG_DARFRC,
1170 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1173 rtl_write_dword(rtlpriv, REG_DARFRC,
1175 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1179 } else { /* MCS13~MCS15, 1SS, G-mode */
1180 if (collision_state == 1) {
1181 if (rate == DESC92C_RATEMCS15) {
1182 rtl_write_dword(rtlpriv, REG_DARFRC,
1184 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1186 } else if (rate == DESC92C_RATEMCS14) {
1187 rtl_write_dword(rtlpriv, REG_DARFRC,
1189 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1191 } else if (rate == DESC92C_RATEMCS13) {
1192 rtl_write_dword(rtlpriv, REG_DARFRC,
1194 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1197 rtl_write_dword(rtlpriv, REG_DARFRC,
1199 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1202 } else{ /* collision_state == 0 */
1203 if (rate == DESC92C_RATEMCS15) {
1204 rtl_write_dword(rtlpriv, REG_DARFRC,
1206 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1208 } else if (rate == DESC92C_RATEMCS14) {
1209 rtl_write_dword(rtlpriv, REG_DARFRC,
1211 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1213 } else if (rate == DESC92C_RATEMCS13) {
1214 rtl_write_dword(rtlpriv, REG_DARFRC,
1216 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1219 rtl_write_dword(rtlpriv, REG_DARFRC,
1221 rtl_write_dword(rtlpriv, REG_DARFRC + 4,
1228 void rtl92ee_dm_watchdog(struct ieee80211_hw *hw)
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;
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;
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);
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);