1 /******************************************************************************
3 * Copyright(c) 2007 - 2016 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 *****************************************************************************/
26 /* ************************************************************
28 * *************************************************************/
29 #include "mp_precomp.h"
30 #include "phydm_precomp.h"
32 void phydm_check_adaptivity(void *dm_void)
34 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
35 struct adaptivity_statistics *adaptivity =
36 (struct adaptivity_statistics *)phydm_get_structure(
37 dm, PHYDM_ADAPTIVITY);
39 if (dm->support_ability & ODM_BB_ADAPTIVITY) {
40 if (adaptivity->dynamic_link_adaptivity ||
41 adaptivity->acs_for_adaptivity) {
42 if (dm->is_linked && !adaptivity->is_check) {
43 phydm_nhm_counter_statistics(dm);
44 phydm_check_environment(dm);
45 } else if (!dm->is_linked) {
46 adaptivity->is_check = false;
49 dm->adaptivity_enable = true;
51 if (dm->support_ic_type & (ODM_IC_11AC_GAIN_IDX_EDCCA |
52 ODM_IC_11N_GAIN_IDX_EDCCA))
53 dm->adaptivity_flag = false;
55 dm->adaptivity_flag = true;
58 dm->adaptivity_enable = false;
59 dm->adaptivity_flag = false;
63 void phydm_nhm_counter_statistics_init(void *dm_void)
65 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
67 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
68 /*PHY parameters initialize for n series*/
70 /*0x894[31:16]=0x0xC350
71 *Time duration for NHM unit: us, 0xc350=200ms
73 odm_write_2byte(dm, ODM_REG_CCX_PERIOD_11N + 2, 0xC350);
74 /*0x890[31:16]=0xffff th_9, th_10*/
75 odm_write_2byte(dm, ODM_REG_NHM_TH9_TH10_11N + 2, 0xffff);
76 /*0x898=0xffffff52 th_3, th_2, th_1, th_0*/
77 odm_write_4byte(dm, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff50);
78 /*0x89c=0xffffffff th_7, th_6, th_5, th_4*/
79 odm_write_4byte(dm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff);
80 /*0xe28[7:0]=0xff th_8*/
81 odm_set_bb_reg(dm, ODM_REG_FPGA0_IQK_11N, MASKBYTE0, 0xff);
82 /*0x890[10:8]=1 ignoreCCA ignore PHYTXON enable CCX*/
83 odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N,
84 BIT(10) | BIT(9) | BIT(8), 0x1);
85 /*0xc0c[7]=1 max power among all RX ants*/
86 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(7), 0x1);
87 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
88 /*PHY parameters initialize for ac series*/
90 odm_write_2byte(dm, ODM_REG_CCX_PERIOD_11AC + 2, 0xC350);
91 /*0x994[31:16]=0xffff th_9, th_10*/
92 odm_write_2byte(dm, ODM_REG_NHM_TH9_TH10_11AC + 2, 0xffff);
93 /*0x998=0xffffff52 th_3, th_2, th_1, th_0*/
94 odm_write_4byte(dm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0xffffff50);
95 /*0x99c=0xffffffff th_7, th_6, th_5, th_4*/
96 odm_write_4byte(dm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffffff);
97 /*0x9a0[7:0]=0xff th_8*/
98 odm_set_bb_reg(dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0, 0xff);
99 /*0x994[10:8]=1 ignoreCCA ignore PHYTXON enable CCX*/
100 odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC,
101 BIT(8) | BIT(9) | BIT(10), 0x1);
102 /*0x9e8[7]=1 max power among all RX ants*/
103 odm_set_bb_reg(dm, ODM_REG_NHM_9E8_11AC, BIT(0), 0x1);
107 void phydm_nhm_counter_statistics(void *dm_void)
109 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
111 if (!(dm->support_ability & ODM_BB_NHM_CNT))
115 phydm_get_nhm_counter_statistics(dm);
117 /*Reset NHM counter*/
118 phydm_nhm_counter_statistics_reset(dm);
121 void phydm_get_nhm_counter_statistics(void *dm_void)
123 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
126 if (dm->support_ic_type & ODM_IC_11AC_SERIES)
127 value32 = odm_get_bb_reg(dm, ODM_REG_NHM_CNT_11AC, MASKDWORD);
128 else if (dm->support_ic_type & ODM_IC_11N_SERIES)
129 value32 = odm_get_bb_reg(dm, ODM_REG_NHM_CNT_11N, MASKDWORD);
131 dm->nhm_cnt_0 = (u8)(value32 & MASKBYTE0);
132 dm->nhm_cnt_1 = (u8)((value32 & MASKBYTE1) >> 8);
135 void phydm_nhm_counter_statistics_reset(void *dm_void)
137 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
139 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
140 odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 0);
141 odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 1);
142 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
143 odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 0);
144 odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 1);
148 void phydm_set_edcca_threshold(void *dm_void, s8 H2L, s8 L2H)
150 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
152 if (dm->support_ic_type & ODM_IC_11N_SERIES)
153 odm_set_bb_reg(dm, REG_OFDM_0_ECCA_THRESHOLD,
154 MASKBYTE2 | MASKBYTE0,
155 (u32)((u8)L2H | (u8)H2L << 16));
156 else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
157 odm_set_bb_reg(dm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD,
158 (u16)((u8)L2H | (u8)H2L << 8));
161 static void phydm_set_lna(void *dm_void, enum phydm_set_lna type)
163 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
165 if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8192E)) {
166 if (type == phydm_disable_lna) {
167 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
168 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
169 0x18000); /*select Rx mode*/
170 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
172 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
173 0x37f82); /*disable LNA*/
174 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
175 if (dm->rf_type > ODM_1T1R) {
176 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
178 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
180 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
182 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
184 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
187 } else if (type == phydm_enable_lna) {
188 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
189 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
190 0x18000); /*select Rx mode*/
191 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
193 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
194 0x77f82); /*back to normal*/
195 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
196 if (dm->rf_type > ODM_1T1R) {
197 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
199 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
201 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
203 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
205 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
209 } else if (dm->support_ic_type & ODM_RTL8723B) {
210 if (type == phydm_disable_lna) {
212 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
213 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
214 0x18000); /*select Rx mode*/
215 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
217 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
218 0xe6137); /*disable LNA*/
219 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
221 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x1);
223 dm, ODM_RF_PATH_A, 0x43, 0xfffff,
224 0x3008d); /*select Rx mode and disable LNA*/
225 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x0);
226 } else if (type == phydm_enable_lna) {
228 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
229 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
230 0x18000); /*select Rx mode*/
231 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
233 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
234 0xe6177); /*disable LNA*/
235 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
237 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x1);
239 dm, ODM_RF_PATH_A, 0x43, 0xfffff,
240 0x300bd); /*select Rx mode and disable LNA*/
241 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x0);
244 } else if (dm->support_ic_type & ODM_RTL8812) {
245 if (type == phydm_disable_lna) {
246 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
247 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
248 0x18000); /*select Rx mode*/
249 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
251 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
252 0xc22bf); /*disable LNA*/
253 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
254 if (dm->rf_type > ODM_1T1R) {
255 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
257 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
258 0x18000); /*select Rx mode*/
259 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
261 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
262 0xc22bf); /*disable LNA*/
263 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
266 } else if (type == phydm_enable_lna) {
267 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
268 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
269 0x18000); /*select Rx mode*/
270 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
272 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
273 0xc26bf); /*disable LNA*/
274 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
275 if (dm->rf_type > ODM_1T1R) {
276 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
278 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
279 0x18000); /*select Rx mode*/
280 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
282 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
283 0xc26bf); /*disable LNA*/
284 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
288 } else if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
289 if (type == phydm_disable_lna) {
290 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
291 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
292 0x18000); /*select Rx mode*/
293 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
295 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
296 0xfb09b); /*disable LNA*/
297 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
298 } else if (type == phydm_enable_lna) {
299 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
300 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
301 0x18000); /*select Rx mode*/
302 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
304 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
305 0xfb0bb); /*disable LNA*/
306 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
311 void phydm_set_trx_mux(void *dm_void, enum phydm_trx_mux_type tx_mode,
312 enum phydm_trx_mux_type rx_mode)
314 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
316 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
317 /*set TXmod to standby mode to remove outside noise affect*/
318 odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N,
319 BIT(3) | BIT(2) | BIT(1), tx_mode);
320 /*set RXmod to standby mode to remove outside noise affect*/
321 odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N,
322 BIT(22) | BIT(21) | BIT(20), rx_mode);
323 if (dm->rf_type > ODM_1T1R) {
324 /*set TXmod to standby mode to rm outside noise affect*/
325 odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N_B,
326 BIT(3) | BIT(2) | BIT(1), tx_mode);
327 /*set RXmod to standby mode to rm outside noise affect*/
328 odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N_B,
329 BIT(22) | BIT(21) | BIT(20), rx_mode);
331 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
332 /*set TXmod to standby mode to remove outside noise affect*/
333 odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC,
334 BIT(11) | BIT(10) | BIT(9) | BIT(8), tx_mode);
335 /*set RXmod to standby mode to remove outside noise affect*/
336 odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC,
337 BIT(7) | BIT(6) | BIT(5) | BIT(4), rx_mode);
338 if (dm->rf_type > ODM_1T1R) {
339 /*set TXmod to standby mode to rm outside noise affect*/
340 odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC_B,
341 BIT(11) | BIT(10) | BIT(9) | BIT(8),
343 /*set RXmod to standby mode to rm outside noise affect*/
344 odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC_B,
345 BIT(7) | BIT(6) | BIT(5) | BIT(4),
351 void phydm_mac_edcca_state(void *dm_void, enum phydm_mac_edcca_type state)
353 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
355 if (state == phydm_ignore_edcca) {
356 /*ignore EDCCA reg520[15]=1*/
357 odm_set_mac_reg(dm, REG_TX_PTCL_CTRL, BIT(15), 1);
358 } else { /*don't set MAC ignore EDCCA signal*/
359 /*don't ignore EDCCA reg520[15]=0*/
360 odm_set_mac_reg(dm, REG_TX_PTCL_CTRL, BIT(15), 0);
362 ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY, "EDCCA enable state = %d\n",
366 bool phydm_cal_nhm_cnt(void *dm_void)
368 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
371 base = dm->nhm_cnt_0 + dm->nhm_cnt_1;
374 dm->nhm_cnt_0 = ((dm->nhm_cnt_0) << 8) / base;
375 dm->nhm_cnt_1 = ((dm->nhm_cnt_1) << 8) / base;
377 if ((dm->nhm_cnt_0 - dm->nhm_cnt_1) >= 100)
378 return true; /*clean environment*/
380 return false; /*noisy environment*/
383 void phydm_check_environment(void *dm_void)
385 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
386 struct adaptivity_statistics *adaptivity =
387 (struct adaptivity_statistics *)phydm_get_structure(
388 dm, PHYDM_ADAPTIVITY);
389 bool is_clean_environment = false;
391 if (adaptivity->is_first_link) {
392 if (dm->support_ic_type &
393 (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))
394 dm->adaptivity_flag = false;
396 dm->adaptivity_flag = true;
398 adaptivity->is_first_link = false;
402 if (adaptivity->nhm_wait < 3) { /*Start enter NHM after 4 nhm_wait*/
403 adaptivity->nhm_wait++;
404 phydm_nhm_counter_statistics(dm);
408 phydm_nhm_counter_statistics(dm);
409 is_clean_environment = phydm_cal_nhm_cnt(dm);
411 if (is_clean_environment) {
413 adaptivity->th_l2h_ini_backup; /*adaptivity mode*/
414 dm->th_edcca_hl_diff = adaptivity->th_edcca_hl_diff_backup;
416 dm->adaptivity_enable = true;
418 if (dm->support_ic_type &
419 (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))
420 dm->adaptivity_flag = false;
422 dm->adaptivity_flag = true;
424 if (!adaptivity->acs_for_adaptivity) {
425 dm->th_l2h_ini = dm->th_l2h_ini_mode2; /*mode2*/
426 dm->th_edcca_hl_diff = dm->th_edcca_hl_diff_mode2;
428 dm->adaptivity_flag = false;
429 dm->adaptivity_enable = false;
433 adaptivity->nhm_wait = 0;
434 adaptivity->is_first_link = true;
435 adaptivity->is_check = true;
438 void phydm_search_pwdb_lower_bound(void *dm_void)
440 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
441 struct adaptivity_statistics *adaptivity =
442 (struct adaptivity_statistics *)phydm_get_structure(
443 dm, PHYDM_ADAPTIVITY);
444 u32 value32 = 0, reg_value32 = 0;
445 u8 cnt, try_count = 0;
446 u8 tx_edcca1 = 0, tx_edcca0 = 0;
447 bool is_adjust = true;
448 s8 th_l2h_dmc, th_h2l_dmc, igi_target = 0x32;
450 u8 IGI = adaptivity->igi_base + 30 + (u8)dm->th_l2h_ini -
451 (u8)dm->th_edcca_hl_diff;
453 if (dm->support_ic_type & (ODM_RTL8723B | ODM_RTL8188E | ODM_RTL8192E |
454 ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) {
455 phydm_set_lna(dm, phydm_disable_lna);
457 phydm_set_trx_mux(dm, phydm_standby_mode, phydm_standby_mode);
458 odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, 0x7e);
461 diff = igi_target - (s8)IGI;
462 th_l2h_dmc = dm->th_l2h_ini + diff;
465 th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
467 phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);
471 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
472 odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x0);
474 odm_get_bb_reg(dm, ODM_REG_RPT_11N, MASKDWORD);
475 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
476 odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD,
479 odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
481 while (reg_value32 & BIT(3) && try_count < 3) {
483 try_count = try_count + 1;
484 if (dm->support_ic_type & ODM_IC_11N_SERIES)
485 reg_value32 = odm_get_bb_reg(
486 dm, ODM_REG_RPT_11N, MASKDWORD);
487 else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
488 reg_value32 = odm_get_bb_reg(
489 dm, ODM_REG_RPT_11AC, MASKDWORD);
493 for (cnt = 0; cnt < 20; cnt++) {
494 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
495 odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N,
497 value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11N,
499 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
500 odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC,
502 value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC,
505 if (value32 & BIT(30) &&
506 (dm->support_ic_type &
507 (ODM_RTL8723B | ODM_RTL8188E)))
508 tx_edcca1 = tx_edcca1 + 1;
509 else if (value32 & BIT(29))
510 tx_edcca1 = tx_edcca1 + 1;
512 tx_edcca0 = tx_edcca0 + 1;
517 th_l2h_dmc = th_l2h_dmc + 1;
520 th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
522 phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);
523 if (th_l2h_dmc == 10) {
525 adaptivity->h2l_lb = th_h2l_dmc;
526 adaptivity->l2h_lb = th_l2h_dmc;
527 dm->adaptivity_igi_upper = IGI;
535 adaptivity->h2l_lb = th_h2l_dmc;
536 adaptivity->l2h_lb = th_l2h_dmc;
537 dm->adaptivity_igi_upper = IGI;
543 dm->adaptivity_igi_upper = dm->adaptivity_igi_upper - dm->dc_backoff;
544 adaptivity->h2l_lb = adaptivity->h2l_lb + dm->dc_backoff;
545 adaptivity->l2h_lb = adaptivity->l2h_lb + dm->dc_backoff;
547 if (dm->support_ic_type & (ODM_RTL8723B | ODM_RTL8188E | ODM_RTL8192E |
548 ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) {
549 phydm_set_lna(dm, phydm_enable_lna);
551 phydm_set_trx_mux(dm, phydm_tx_mode, phydm_rx_mode);
552 odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, NONE);
555 phydm_set_edcca_threshold(dm, 0x7f, 0x7f); /*resume to no link state*/
558 static bool phydm_re_search_condition(void *dm_void)
560 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
561 u8 adaptivity_igi_upper;
564 adaptivity_igi_upper = dm->adaptivity_igi_upper + dm->dc_backoff;
566 if (adaptivity_igi_upper <= 0x26 && count < 3) {
574 void phydm_adaptivity_info_init(void *dm_void, enum phydm_adapinfo cmn_info,
577 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
578 struct adaptivity_statistics *adaptivity =
579 (struct adaptivity_statistics *)phydm_get_structure(
580 dm, PHYDM_ADAPTIVITY);
583 case PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE:
584 dm->carrier_sense_enable = (bool)value;
587 case PHYDM_ADAPINFO_DCBACKOFF:
588 dm->dc_backoff = (u8)value;
591 case PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY:
592 adaptivity->dynamic_link_adaptivity = (bool)value;
595 case PHYDM_ADAPINFO_TH_L2H_INI:
596 dm->th_l2h_ini = (s8)value;
599 case PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF:
600 dm->th_edcca_hl_diff = (s8)value;
603 case PHYDM_ADAPINFO_AP_NUM_TH:
604 adaptivity->ap_num_th = (u8)value;
612 void phydm_adaptivity_init(void *dm_void)
614 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
615 struct adaptivity_statistics *adaptivity =
616 (struct adaptivity_statistics *)phydm_get_structure(
617 dm, PHYDM_ADAPTIVITY);
618 s8 igi_target = 0x32;
620 if (!dm->carrier_sense_enable) {
621 if (dm->th_l2h_ini == 0)
622 dm->th_l2h_ini = 0xf5;
624 dm->th_l2h_ini = 0xa;
627 if (dm->th_edcca_hl_diff == 0)
628 dm->th_edcca_hl_diff = 7;
629 if (dm->wifi_test || dm->mp_mode) {
630 /*even no adaptivity, we still enable EDCCA, AP use mib ctrl*/
631 dm->edcca_enable = false;
633 dm->edcca_enable = true;
636 dm->adaptivity_igi_upper = 0;
637 dm->adaptivity_enable =
638 false; /*use this flag to decide enable or disable*/
640 dm->th_l2h_ini_mode2 = 20;
641 dm->th_edcca_hl_diff_mode2 = 8;
642 adaptivity->th_l2h_ini_backup = dm->th_l2h_ini;
643 adaptivity->th_edcca_hl_diff_backup = dm->th_edcca_hl_diff;
645 adaptivity->igi_base = 0x32;
646 adaptivity->igi_target = 0x1c;
647 adaptivity->h2l_lb = 0;
648 adaptivity->l2h_lb = 0;
649 adaptivity->nhm_wait = 0;
650 adaptivity->is_check = false;
651 adaptivity->is_first_link = true;
652 adaptivity->adajust_igi_level = 0;
653 adaptivity->is_stop_edcca = false;
654 adaptivity->backup_h2l = 0;
655 adaptivity->backup_l2h = 0;
657 phydm_mac_edcca_state(dm, phydm_dont_ignore_edcca);
659 /*Search pwdB lower bound*/
660 if (dm->support_ic_type & ODM_IC_11N_SERIES)
661 odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x208);
662 else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
663 odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x209);
665 if (dm->support_ic_type & ODM_IC_11N_GAIN_IDX_EDCCA) {
666 if (dm->support_ic_type & ODM_RTL8197F) {
668 odm_set_bb_reg(dm, ODM_REG_PAGE_B1_97F, BIT(30), 0x1);
669 /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
670 odm_set_bb_reg(dm, ODM_REG_EDCCA_DCNF_97F,
671 BIT(27) | BIT(26), 0x1);
672 odm_set_bb_reg(dm, ODM_REG_PAGE_B1_97F, BIT(30), 0x0);
674 /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
675 odm_set_bb_reg(dm, ODM_REG_EDCCA_DCNF_11N,
676 BIT(21) | BIT(20), 0x1);
679 /*8814a no need to find pwdB lower bound, maybe*/
680 if (dm->support_ic_type & ODM_IC_11AC_GAIN_IDX_EDCCA) {
681 /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
682 odm_set_bb_reg(dm, ODM_REG_ACBB_EDCCA_ENHANCE,
683 BIT(29) | BIT(28), 0x1);
686 if (!(dm->support_ic_type &
687 (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))) {
688 phydm_search_pwdb_lower_bound(dm);
689 if (phydm_re_search_condition(dm))
690 phydm_search_pwdb_lower_bound(dm);
693 /*we need to consider PwdB upper bound for 8814 later IC*/
694 adaptivity->adajust_igi_level =
695 (u8)((dm->th_l2h_ini + igi_target) - pwdb_upper_bound +
696 dfir_loss); /*IGI = L2H - PwdB - dfir_loss*/
699 dm, PHYDM_COMP_ADAPTIVITY,
700 "th_l2h_ini = 0x%x, th_edcca_hl_diff = 0x%x, adaptivity->adajust_igi_level = 0x%x\n",
701 dm->th_l2h_ini, dm->th_edcca_hl_diff,
702 adaptivity->adajust_igi_level);
704 /*Check this later on Windows*/
705 /*phydm_set_edcca_threshold_api(dm, dig_tab->cur_ig_value);*/
708 void phydm_adaptivity(void *dm_void)
710 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
711 struct dig_thres *dig_tab = &dm->dm_dig_table;
712 u8 IGI = dig_tab->cur_ig_value;
713 s8 th_l2h_dmc, th_h2l_dmc;
714 s8 diff = 0, igi_target;
715 struct adaptivity_statistics *adaptivity =
716 (struct adaptivity_statistics *)phydm_get_structure(
717 dm, PHYDM_ADAPTIVITY);
719 if (!dm->edcca_enable || adaptivity->is_stop_edcca) {
720 ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY, "Disable EDCCA!!!\n");
724 if (!(dm->support_ability & ODM_BB_ADAPTIVITY)) {
725 ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY,
726 "adaptivity disable, enable EDCCA mode!!!\n");
727 dm->th_l2h_ini = dm->th_l2h_ini_mode2;
728 dm->th_edcca_hl_diff = dm->th_edcca_hl_diff_mode2;
731 ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY, "%s() =====>\n", __func__);
732 ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY,
733 "igi_base=0x%x, th_l2h_ini = %d, th_edcca_hl_diff = %d\n",
734 adaptivity->igi_base, dm->th_l2h_ini,
735 dm->th_edcca_hl_diff);
736 if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
737 /*fix AC series when enable EDCCA hang issue*/
738 odm_set_bb_reg(dm, 0x800, BIT(10), 1); /*ADC_mask disable*/
739 odm_set_bb_reg(dm, 0x800, BIT(10), 0); /*ADC_mask enable*/
741 if (*dm->band_width == ODM_BW20M) /*CHANNEL_WIDTH_20*/
742 igi_target = adaptivity->igi_base;
743 else if (*dm->band_width == ODM_BW40M)
744 igi_target = adaptivity->igi_base + 2;
745 else if (*dm->band_width == ODM_BW80M)
746 igi_target = adaptivity->igi_base + 2;
748 igi_target = adaptivity->igi_base;
749 adaptivity->igi_target = (u8)igi_target;
752 dm, PHYDM_COMP_ADAPTIVITY,
753 "band_width=%s, igi_target=0x%x, dynamic_link_adaptivity = %d, acs_for_adaptivity = %d\n",
754 (*dm->band_width == ODM_BW80M) ?
756 ((*dm->band_width == ODM_BW40M) ? "40M" : "20M"),
757 igi_target, adaptivity->dynamic_link_adaptivity,
758 adaptivity->acs_for_adaptivity);
760 dm, PHYDM_COMP_ADAPTIVITY,
761 "rssi_min = %d, adaptivity->adajust_igi_level= 0x%x, adaptivity_flag = %d, adaptivity_enable = %d\n",
762 dm->rssi_min, adaptivity->adajust_igi_level,
763 dm->adaptivity_flag, dm->adaptivity_enable);
765 if (adaptivity->dynamic_link_adaptivity && (!dm->is_linked) &&
766 !dm->adaptivity_enable) {
767 phydm_set_edcca_threshold(dm, 0x7f, 0x7f);
769 dm, PHYDM_COMP_ADAPTIVITY,
770 "In DynamicLink mode(noisy) and No link, Turn off EDCCA!!\n");
774 if (dm->support_ic_type &
775 (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
776 if ((adaptivity->adajust_igi_level > IGI) &&
777 dm->adaptivity_enable)
778 diff = adaptivity->adajust_igi_level - IGI;
780 th_l2h_dmc = dm->th_l2h_ini - diff + igi_target;
781 th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
783 diff = igi_target - (s8)IGI;
784 th_l2h_dmc = dm->th_l2h_ini + diff;
785 if (th_l2h_dmc > 10 && dm->adaptivity_enable)
788 th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
790 /*replace lower bound to prevent EDCCA always equal 1*/
791 if (th_h2l_dmc < adaptivity->h2l_lb)
792 th_h2l_dmc = adaptivity->h2l_lb;
793 if (th_l2h_dmc < adaptivity->l2h_lb)
794 th_l2h_dmc = adaptivity->l2h_lb;
796 ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY,
797 "IGI=0x%x, th_l2h_dmc = %d, th_h2l_dmc = %d\n", IGI,
798 th_l2h_dmc, th_h2l_dmc);
800 dm, PHYDM_COMP_ADAPTIVITY,
801 "adaptivity_igi_upper=0x%x, h2l_lb = 0x%x, l2h_lb = 0x%x\n",
802 dm->adaptivity_igi_upper, adaptivity->h2l_lb,
805 phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);
807 if (dm->adaptivity_enable)
808 odm_set_mac_reg(dm, REG_RD_CTRL, BIT(11), 1);
811 /*This is for solving USB can't Tx problem due to USB3.0 interference in 2.4G*/
812 void phydm_pause_edcca(void *dm_void, bool is_pasue_edcca)
814 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
815 struct adaptivity_statistics *adaptivity =
816 (struct adaptivity_statistics *)phydm_get_structure(
817 dm, PHYDM_ADAPTIVITY);
818 struct dig_thres *dig_tab = &dm->dm_dig_table;
819 u8 IGI = dig_tab->cur_ig_value;
822 if (is_pasue_edcca) {
823 adaptivity->is_stop_edcca = true;
825 if (dm->support_ic_type &
826 (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
827 if (adaptivity->adajust_igi_level > IGI)
828 diff = adaptivity->adajust_igi_level - IGI;
830 adaptivity->backup_l2h =
831 dm->th_l2h_ini - diff + adaptivity->igi_target;
832 adaptivity->backup_h2l =
833 adaptivity->backup_l2h - dm->th_edcca_hl_diff;
835 diff = adaptivity->igi_target - (s8)IGI;
836 adaptivity->backup_l2h = dm->th_l2h_ini + diff;
837 if (adaptivity->backup_l2h > 10)
838 adaptivity->backup_l2h = 10;
840 adaptivity->backup_h2l =
841 adaptivity->backup_l2h - dm->th_edcca_hl_diff;
843 /*replace lower bound to prevent EDCCA always equal 1*/
844 if (adaptivity->backup_h2l < adaptivity->h2l_lb)
845 adaptivity->backup_h2l = adaptivity->h2l_lb;
846 if (adaptivity->backup_l2h < adaptivity->l2h_lb)
847 adaptivity->backup_l2h = adaptivity->l2h_lb;
850 dm, PHYDM_COMP_ADAPTIVITY,
851 "pauseEDCCA : L2Hbak = 0x%x, H2Lbak = 0x%x, IGI = 0x%x\n",
852 adaptivity->backup_l2h, adaptivity->backup_h2l, IGI);
855 phydm_pause_edcca_work_item_callback(dm);
858 adaptivity->is_stop_edcca = false;
860 dm, PHYDM_COMP_ADAPTIVITY,
861 "resumeEDCCA : L2Hbak = 0x%x, H2Lbak = 0x%x, IGI = 0x%x\n",
862 adaptivity->backup_l2h, adaptivity->backup_h2l, IGI);
864 phydm_resume_edcca_work_item_callback(dm);
868 void phydm_pause_edcca_work_item_callback(void *dm_void)
870 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
872 if (dm->support_ic_type & ODM_IC_11N_SERIES)
873 odm_set_bb_reg(dm, REG_OFDM_0_ECCA_THRESHOLD,
874 MASKBYTE2 | MASKBYTE0, (u32)(0x7f | 0x7f << 16));
875 else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
876 odm_set_bb_reg(dm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD,
877 (u16)(0x7f | 0x7f << 8));
880 void phydm_resume_edcca_work_item_callback(void *dm_void)
882 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
883 struct adaptivity_statistics *adaptivity =
884 (struct adaptivity_statistics *)phydm_get_structure(
885 dm, PHYDM_ADAPTIVITY);
887 if (dm->support_ic_type & ODM_IC_11N_SERIES)
888 odm_set_bb_reg(dm, REG_OFDM_0_ECCA_THRESHOLD,
889 MASKBYTE2 | MASKBYTE0,
890 (u32)((u8)adaptivity->backup_l2h |
891 (u8)adaptivity->backup_h2l << 16));
892 else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
893 odm_set_bb_reg(dm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD,
894 (u16)((u8)adaptivity->backup_l2h |
895 (u8)adaptivity->backup_h2l << 8));
898 void phydm_set_edcca_threshold_api(void *dm_void, u8 IGI)
900 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
901 struct adaptivity_statistics *adaptivity =
902 (struct adaptivity_statistics *)phydm_get_structure(
903 dm, PHYDM_ADAPTIVITY);
904 s8 th_l2h_dmc, th_h2l_dmc;
905 s8 diff = 0, igi_target = 0x32;
907 if (dm->support_ability & ODM_BB_ADAPTIVITY) {
908 if (dm->support_ic_type &
909 (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
910 if (adaptivity->adajust_igi_level > IGI)
911 diff = adaptivity->adajust_igi_level - IGI;
913 th_l2h_dmc = dm->th_l2h_ini - diff + igi_target;
914 th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
916 diff = igi_target - (s8)IGI;
917 th_l2h_dmc = dm->th_l2h_ini + diff;
921 th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
923 /*replace lower bound to prevent EDCCA always equal 1*/
924 if (th_h2l_dmc < adaptivity->h2l_lb)
925 th_h2l_dmc = adaptivity->h2l_lb;
926 if (th_l2h_dmc < adaptivity->l2h_lb)
927 th_l2h_dmc = adaptivity->l2h_lb;
930 dm, PHYDM_COMP_ADAPTIVITY,
931 "API :IGI=0x%x, th_l2h_dmc = %d, th_h2l_dmc = %d\n",
932 IGI, th_l2h_dmc, th_h2l_dmc);
934 dm, PHYDM_COMP_ADAPTIVITY,
935 "API :adaptivity_igi_upper=0x%x, h2l_lb = 0x%x, l2h_lb = 0x%x\n",
936 dm->adaptivity_igi_upper, adaptivity->h2l_lb,
939 phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);