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, "
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
));
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
));
271 static void rtl92ee_dm_cck_packet_detection_thresh(struct ieee80211_hw
*hw
)
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;
282 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
283 cur_cck_cca_thresh
= 0x83;
285 cur_cck_cca_thresh
= 0x40;
288 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
289 cur_cck_cca_thresh
= 0x83;
291 cur_cck_cca_thresh
= 0x40;
293 rtl92ee_dm_write_cck_cca_thres(hw
, cur_cck_cca_thresh
);
296 static void rtl92ee_dm_dig(struct ieee80211_hw
*hw
)
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
;
307 if (mac
->act_scanning
== true)
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);
317 dm_dig_min
= DM_DIG_MIN
;
318 dig_maxofmin
= DM_DIG_MAX_AP
;
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
;
326 dm_dig
.rx_gain_range_max
= dm_dig
.rssi_val_min
+ 10;
328 if (rtlpriv
->dm
.b_one_entry_only
) {
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
>
334 dig_dynamic_min
= dig_maxofmin
;
336 dig_dynamic_min
= dm_dig
.rssi_val_min
- offset
;
338 dig_dynamic_min
= dm_dig_min
;
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"));
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;
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
;
360 dm_dig
.rx_gain_range_min
=
361 dm_dig
.forbidden_igi
+ 1;
362 dm_dig
.recover_cnt
= 3600;
365 if (dm_dig
.recover_cnt
!= 0) {
366 dm_dig
.recover_cnt
--;
368 if (dm_dig
.large_fa_hit
< 3) {
369 if ((dm_dig
.forbidden_igi
- 1) <
371 dm_dig
.forbidden_igi
= dig_dynamic_min
;
372 dm_dig
.rx_gain_range_min
=
375 dm_dig
.forbidden_igi
--;
376 dm_dig
.rx_gain_range_min
=
377 dm_dig
.forbidden_igi
+ 1;
380 dm_dig
.large_fa_hit
= 0;
385 if (rtlpriv
->dm
.dbginfo
.num_qry_beacon_pkt
< 5)
386 dm_dig
.rx_gain_range_min
= dm_dig_min
;
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
;
391 if (mac
->link_state
>= MAC80211_LINKED
) {
393 if (dm_dig
.rssi_val_min
<= dig_maxofmin
)
394 current_igi
= dm_dig
.rssi_val_min
;
396 current_igi
= dig_maxofmin
;
398 dm_dig
.large_fa_hit
= 0;
400 if (rtlpriv
->falsealm_cnt
.cnt_all
> DM_DIG_FA_TH2
)
402 else if (rtlpriv
->falsealm_cnt
.cnt_all
> DM_DIG_FA_TH1
)
404 else if (rtlpriv
->falsealm_cnt
.cnt_all
< DM_DIG_FA_TH0
)
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
;
412 if (bfirstdisconnect
) {
413 current_igi
= dm_dig
.rx_gain_range_min
;
415 if (rtlpriv
->falsealm_cnt
.cnt_all
> 10000)
417 else if (rtlpriv
->falsealm_cnt
.cnt_all
> 8000)
419 else if (rtlpriv
->falsealm_cnt
.cnt_all
< 500)
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
;
429 rtl92ee_dm_write_dig(hw
, current_igi
);
430 dm_dig
.b_media_connect_0
= ((mac
->link_state
>= MAC80211_LINKED
) ?
432 dm_dig
.dig_dynamic_min_0
= dig_dynamic_min
;
435 void rtl92ee_dm_write_cck_cca_thres(struct ieee80211_hw
*hw
, u8 cur_thres
)
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
);
441 dm_dig
.pre_cck_cca_thres
= dm_dig
.cur_cck_cca_thres
;
442 dm_dig
.cur_cck_cca_thres
= cur_thres
;
445 void rtl92ee_dm_write_dig(struct ieee80211_hw
*hw
, u8 current_igi
)
447 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
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
);
456 dm_dig
.pre_igvalue
= dm_dig
.cur_igvalue
;
457 dm_dig
.cur_igvalue
= current_igi
;
460 static void rtl92ee_rssi_dump_to_register(struct ieee80211_hw
*hw
)
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*/
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]);
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]));
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]);
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]);
488 static void rtl92ee_dm_find_minimum_rssi(struct ieee80211_hw
*hw
)
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
);
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"));
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
));
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
));
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
));
523 RT_TRACE(COMP_DIG
, DBG_LOUD
, ("MinUndecoratedPWDBForDM =%d\n",
524 rtl_dm_dig
->min_undecorated_pwdb_for_dm
));
527 static void rtl92ee_dm_check_rssi_monitor(struct ieee80211_hw
*hw
)
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
;
534 long max
= 0, min
= 0xff;
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
;
550 h2c
[2] = (u8
) (dm
->undecorated_smoothed_pwdb
& 0xFF);
553 rtl92ee_fill_h2c_cmd(hw
, H2C_92E_RSSI_REPORT
, 4, h2c
);
555 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
557 /* If associated entry is found */
559 dm
->entry_max_undecoratedsmoothed_pwdb
= max
;
560 RTPRINT(rtlpriv
, FDM
, DM_PWDB
,
561 "EntryMaxPWDB = 0x%lx(%ld)\n", max
, max
);
563 dm
->entry_max_undecoratedsmoothed_pwdb
= 0;
565 /* If associated entry is found */
567 dm
->entry_min_undecoratedsmoothed_pwdb
= min
;
568 RTPRINT(rtlpriv
, FDM
, DM_PWDB
,
569 "EntryMinPWDB = 0x%lx(%ld)\n", min
, min
);
571 dm
->entry_min_undecoratedsmoothed_pwdb
= 0;
575 /* Indicate Rx signal strength to FW. */
576 if (dm
->b_useramask
) {
578 h2c
[2] = (u8
) (dm
->undecorated_smoothed_pwdb
& 0xFF);
581 rtl92ee_fill_h2c_cmd(hw
, H2C_92E_RSSI_REPORT
, 4, h2c
);
583 rtl_write_byte(rtlpriv
, 0x4fe, dm
->undecorated_smoothed_pwdb
);
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
;
590 static void rtl92ee_dm_init_primary_cca_check(struct ieee80211_hw
*hw
)
592 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
593 struct rtl_hal
*rtlhal
= rtl_hal(rtlpriv
);
594 struct dynamic_primary_cca
*primarycca
= &(rtlpriv
->primarycca
);
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;
605 static bool rtl92ee_dm_is_edca_turbo_disable(struct ieee80211_hw
*hw
)
607 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
609 if (rtlpriv
->mac80211
.mode
== WIRELESS_MODE_B
)
615 void rtl92ee_dm_init_edca_turbo(struct ieee80211_hw
*hw
)
617 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
619 rtlpriv
->dm
.bcurrent_turbo_edca
= false;
620 rtlpriv
->dm
.bis_cur_rdlstate
= false;
621 rtlpriv
->dm
.bis_any_nonbepkts
= false;
624 static void rtl92ee_dm_check_edca_turbo(struct ieee80211_hw
*hw
)
626 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
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;
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;
642 cur_txok_cnt
= rtlpriv
->stats
.txbytesunicast
- last_txok_cnt
;
643 cur_rxok_cnt
= rtlpriv
->stats
.rxbytesunicast
- last_rxok_cnt
;
645 /*b_bias_on_rx = false;*/
646 b_edca_turbo_on
= ((!rtlpriv
->dm
.bis_any_nonbepkts
) &&
647 (!rtlpriv
->dm
.b_disable_framebursting
)) ?
650 if (rtl92ee_dm_is_edca_turbo_disable(hw
))
651 goto dm_CheckEdcaTurbo_EXIT
;
653 if (b_edca_turbo_on
) {
654 b_is_cur_rdlstate
= (cur_rxok_cnt
> cur_txok_cnt
* 4) ?
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;
662 if (rtlpriv
->dm
.bcurrent_turbo_edca
) {
664 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_AC_PARAM
,
667 rtlpriv
->dm
.bcurrent_turbo_edca
= false;
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
;
676 static void rtl92ee_dm_dynamic_edcca(struct ieee80211_hw
*hw
)
678 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
679 u8 reg_c50
, reg_c58
;
680 bool b_fw_current_in_ps_mode
= false;
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
)
687 reg_c50
= rtl_get_bbreg(hw
, ROFDM0_XAAGCCORE1
, MASKBYTE0
);
688 reg_c58
= rtl_get_bbreg(hw
, ROFDM0_XBAGCCORE1
, MASKBYTE0
);
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;
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;
705 static void rtl92ee_dm_adaptivity(struct ieee80211_hw
*hw
)
707 rtl92ee_dm_dynamic_edcca(hw
);
710 static void rtl92ee_dm_write_dynamic_cca(struct ieee80211_hw
*hw
, u8 cur_mf_state
)
712 struct dynamic_primary_cca
*primarycca
= &(rtl_priv(hw
)->primarycca
);
714 if (primarycca
->mf_state
!= cur_mf_state
)
715 rtl_set_bbreg(hw
, DM_REG_L1SBD_PD_CH_11N
, BIT(8) | BIT(7),
718 primarycca
->mf_state
= cur_mf_state
;
721 static void rtl92ee_dm_dynamic_primary_cca_ckeck(struct ieee80211_hw
*hw
)
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
;
730 static u8 count_down
= MONITOR_TIME
;
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 */
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
);
746 if (rtlpriv
->mac80211
.link_state
< MAC80211_LINKED
)
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;
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;
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;
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;
810 } else {/* PrimaryCCA->PriCCA_flag == 1 */
812 if (count_down
== 0) {
813 count_down
= MONITOR_TIME
;
814 primarycca
->pricca_flag
= 0;
815 cur_mf_state
= MF_USC_LSC
;
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;
826 static void rtl92ee_dm_dynamic_atc_switch(struct ieee80211_hw
*hw
)
828 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
829 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
832 int cfo_khz_a
, cfo_khz_b
, cfo_ave
= 0, adjust_xtal
= 0;
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),
839 rtldm
->atc_status
= ATC_STATUS_ON
;
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"));
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)));
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
;
862 if (packet_count
== rtldm
->packet_count_pre
)
865 rtldm
->packet_count_pre
= packet_count
;
867 if (rtlpriv
->phy
.rf_type
== RF_1T1R
)
870 cfo_ave
= (int)(cfo_khz_a
+ cfo_khz_b
) >> 1;
872 cfo_ave_diff
= (rtldm
->cfo_ave_pre
>= cfo_ave
) ?
873 (rtldm
->cfo_ave_pre
- cfo_ave
) :
874 (cfo_ave
- rtldm
->cfo_ave_pre
);
876 if (cfo_ave_diff
> 20 && rtldm
->large_cfo_hit
== 0) {
877 rtldm
->large_cfo_hit
= 1;
880 rtldm
->large_cfo_hit
= 0;
883 rtldm
->cfo_ave_pre
= cfo_ave
;
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;
891 rtldm
->cfo_threshold
= CFO_THRESHOLD_XTAL
;
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;
901 if (adjust_xtal
!= 0) {
902 rtldm
->is_freeze
= 0;
903 rtldm
->crystal_cap
+= adjust_xtal
;
905 if (rtldm
->crystal_cap
> 0x3f)
906 rtldm
->crystal_cap
= 0x3f;
907 else if (rtldm
->crystal_cap
< 0)
908 rtldm
->crystal_cap
= 0;
910 crystal_cap
= rtldm
->crystal_cap
& 0x3f;
911 rtl_set_bbreg(hw
, REG_MAC_PHY_CTRL
, 0xFFF000,
912 (crystal_cap
| (crystal_cap
<< 6)));
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),
920 rtldm
->atc_status
= ATC_STATUS_OFF
;
923 if (rtldm
->atc_status
== ATC_STATUS_OFF
) {
924 rtl_set_bbreg(hw
, ROFDM1_CFOTRACKING
, BIT(11),
926 rtldm
->atc_status
= ATC_STATUS_ON
;
932 static void rtl92ee_dm_init_txpower_tracking(struct ieee80211_hw
*hw
)
934 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
935 struct rtl_dm
*dm
= rtl_dm(rtlpriv
);
938 dm
->btxpower_tracking
= true;
939 dm
->default_ofdm_index
= 30;
940 dm
->default_cck_index
= 20;
942 dm
->bb_swing_idx_cck_base
= dm
->default_cck_index
;
943 dm
->cck_index
= dm
->default_cck_index
;
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;
954 void rtl92ee_dm_init_rate_adaptive_mask(struct ieee80211_hw
*hw
)
956 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
957 struct rate_adaptive
*p_ra
= &(rtlpriv
->ra
);
959 p_ra
->ratr_state
= DM_RATR_STA_INIT
;
960 p_ra
->pre_ratr_state
= DM_RATR_STA_INIT
;
962 if (rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
)
963 rtlpriv
->dm
.b_useramask
= true;
965 rtlpriv
->dm
.b_useramask
= false;
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;
974 static bool _rtl92ee_dm_ra_state_check(struct ieee80211_hw
*hw
,
975 s32 rssi
, u8
*ratr_state
)
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
;
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.
990 switch (*ratr_state
) {
991 case DM_RATR_STA_INIT
:
992 case DM_RATR_STA_HIGH
:
995 case DM_RATR_STA_MIDDLE
:
996 high_rssithresh_for_ra
+= go_up_gap
;
999 case DM_RATR_STA_LOW
:
1000 high_rssithresh_for_ra
+= go_up_gap
;
1001 low_rssithresh_for_ra
+= go_up_gap
;
1005 RT_TRACE(COMP_RATR
, DBG_DMESG
,
1006 ("wrong rssi level setting %d !", *ratr_state
));
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
;
1016 state
= DM_RATR_STA_LOW
;
1018 if (*ratr_state
!= state
) {
1019 *ratr_state
= state
;
1026 static void rtl92ee_dm_refresh_rate_adaptive_mask(struct ieee80211_hw
*hw
)
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
;
1034 if (is_hal_stop(rtlhal
)) {
1035 RT_TRACE(COMP_RATE
, DBG_LOUD
,
1036 ("driver is going to unload\n"));
1040 if (!rtlpriv
->dm
.b_useramask
) {
1041 RT_TRACE(COMP_RATE
, DBG_LOUD
,
1042 ("driver does not control rate adaptive mask\n"));
1046 if (mac
->link_state
== MAC80211_LINKED
&&
1047 mac
->opmode
== NL80211_IFTYPE_STATION
) {
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;
1057 if (_rtl92ee_dm_ra_state_check(hw
,
1058 rtlpriv
->dm
.undecorated_smoothed_pwdb
,
1059 &(p_ra
->ratr_state
))) {
1062 sta
= rtl_find_sta(hw
, mac
->bssid
);
1064 rtlpriv
->cfg
->ops
->update_rate_tbl(hw
, sta
,
1068 p_ra
->pre_ratr_state
= p_ra
->ratr_state
;
1073 static void rtl92ee_dm_init_dynamic_atc_switch(struct ieee80211_hw
*hw
)
1075 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1077 rtlpriv
->dm
.crystal_cap
= rtlpriv
->efuse
.crystalcap
;
1079 rtlpriv
->dm
.atc_status
= rtl_get_bbreg(hw
, ROFDM1_CFOTRACKING
, BIT(11));
1080 rtlpriv
->dm
.cfo_threshold
= CFO_THRESHOLD_XTAL
;
1083 void rtl92ee_dm_init(struct ieee80211_hw
*hw
)
1085 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1087 rtlpriv
->dm
.dm_type
= DM_TYPE_BYDRIVER
;
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
);
1097 static void rtl92ee_dm_common_info_self_update(struct ieee80211_hw
*hw
)
1099 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1101 struct rtl_sta_info
*drv_priv
;
1103 rtlpriv
->dm
.b_one_entry_only
= false;
1105 if (rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_STATION
&&
1106 rtlpriv
->mac80211
.link_state
>= MAC80211_LINKED
) {
1107 rtlpriv
->dm
.b_one_entry_only
= true;
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
) {
1118 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
1121 rtlpriv
->dm
.b_one_entry_only
= true;
1125 void rtl92ee_dm_dynamic_arfb_select(struct ieee80211_hw
*hw
,
1126 u8 rate
, bool collision_state
)
1128 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
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,
1136 } else if (rate
== DESC92C_RATEMCS11
) {
1137 rtl_write_dword(rtlpriv
, REG_DARFRC
, 0x0);
1138 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1140 } else if (rate
== DESC92C_RATEMCS10
) {
1141 rtl_write_dword(rtlpriv
, REG_DARFRC
, 0x0);
1142 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1144 } else if (rate
== DESC92C_RATEMCS9
) {
1145 rtl_write_dword(rtlpriv
, REG_DARFRC
, 0x0);
1146 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1149 rtl_write_dword(rtlpriv
, REG_DARFRC
, 0x0);
1150 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1153 } else { /* collision_state == 0 */
1154 if (rate
== DESC92C_RATEMCS12
) {
1155 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1157 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1159 } else if (rate
== DESC92C_RATEMCS11
) {
1160 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1162 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1164 } else if (rate
== DESC92C_RATEMCS10
) {
1165 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1167 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1169 } else if (rate
== DESC92C_RATEMCS9
) {
1170 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1172 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1175 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1177 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1181 } else { /* MCS13~MCS15, 1SS, G-mode */
1182 if (collision_state
== 1) {
1183 if (rate
== DESC92C_RATEMCS15
) {
1184 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1186 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1188 } else if (rate
== DESC92C_RATEMCS14
) {
1189 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1191 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1193 } else if (rate
== DESC92C_RATEMCS13
) {
1194 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1196 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1199 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1201 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1204 } else{ /* collision_state == 0 */
1205 if (rate
== DESC92C_RATEMCS15
) {
1206 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1208 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1210 } else if (rate
== DESC92C_RATEMCS14
) {
1211 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1213 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1215 } else if (rate
== DESC92C_RATEMCS13
) {
1216 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1218 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1221 rtl_write_dword(rtlpriv
, REG_DARFRC
,
1223 rtl_write_dword(rtlpriv
, REG_DARFRC
+ 4,
1230 void rtl92ee_dm_watchdog(struct ieee80211_hw
*hw
)
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;
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;
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
);
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
);