xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8723ds/hal/phydm/phydm_lna_sat.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017  Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25 
26 /*************************************************************
27  * include files
28  * *************************************************************/
29 #include "mp_precomp.h"
30 #include "phydm_precomp.h"
31 
32 #ifdef PHYDM_LNA_SAT_CHK_SUPPORT
33 
34 #ifdef PHYDM_LNA_SAT_CHK_TYPE1
phydm_lna_sat_chk_init(void * dm_void)35 void phydm_lna_sat_chk_init(
36 	void *dm_void)
37 {
38 	struct dm_struct *dm = (struct dm_struct *)dm_void;
39 	struct phydm_lna_sat_t *lna_info = &dm->dm_lna_sat_info;
40 
41 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
42 
43 	lna_info->check_time = 0;
44 	lna_info->sat_cnt_acc_patha = 0;
45 	lna_info->sat_cnt_acc_pathb = 0;
46 	#ifdef PHYDM_IC_ABOVE_3SS
47 	lna_info->sat_cnt_acc_pathc = 0;
48 	#endif
49 	#ifdef PHYDM_IC_ABOVE_4SS
50 	lna_info->sat_cnt_acc_pathd = 0;
51 	#endif
52 	lna_info->cur_sat_status = 0;
53 	lna_info->pre_sat_status = 0;
54 	lna_info->cur_timer_check_cnt = 0;
55 	lna_info->pre_timer_check_cnt = 0;
56 
57 	#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
58 	if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B))
59 		phydm_lna_sat_chk_bb_init(dm);
60 	#endif
61 }
62 
63 #if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
phydm_lna_sat_chk_bb_init(void * dm_void)64 void phydm_lna_sat_chk_bb_init(void *dm_void)
65 {
66 	struct dm_struct *dm = (struct dm_struct *)dm_void;
67 	struct phydm_lna_sat_t *lna_info = &dm->dm_lna_sat_info;
68 
69 	boolean disable_bb_switch_tab = false;
70 
71 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
72 
73 	/*@set table switch mux r_6table_sel_anten*/
74 	odm_set_bb_reg(dm, 0x18ac, BIT(8), 0);
75 
76 	/*@tab decision when idle*/
77 	odm_set_bb_reg(dm, 0x18ac, BIT(16), disable_bb_switch_tab);
78 	odm_set_bb_reg(dm, 0x41ac, BIT(16), disable_bb_switch_tab);
79 	odm_set_bb_reg(dm, 0x52ac, BIT(16), disable_bb_switch_tab);
80 	odm_set_bb_reg(dm, 0x53ac, BIT(16), disable_bb_switch_tab);
81 	/*@tab decision when ofdmcca*/
82 	odm_set_bb_reg(dm, 0x18ac, BIT(17), disable_bb_switch_tab);
83 	odm_set_bb_reg(dm, 0x41ac, BIT(17), disable_bb_switch_tab);
84 	odm_set_bb_reg(dm, 0x52ac, BIT(17), disable_bb_switch_tab);
85 	odm_set_bb_reg(dm, 0x53ac, BIT(17), disable_bb_switch_tab);
86 }
87 
phydm_set_ofdm_agc_tab_path(void * dm_void,u8 tab_sel,enum rf_path path)88 void phydm_set_ofdm_agc_tab_path(
89 	void *dm_void,
90 	u8 tab_sel,
91 	enum rf_path path)
92 {
93 	struct dm_struct *dm = (struct dm_struct *)dm_void;
94 
95 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
96 	if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B)) {
97 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "set AGC Tab%d\n", tab_sel);
98 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "r_6table_sel_anten = 0x%x\n",
99 			  odm_get_bb_reg(dm, 0x18ac, BIT(8)));
100 	}
101 
102 	if (dm->support_ic_type & ODM_RTL8198F) {
103 		/*@table sel:0/2, mapping 2 to 1 */
104 		if (tab_sel == OFDM_AGC_TAB_0) {
105 			odm_set_bb_reg(dm, 0x18ac, BIT(4), 0);
106 			odm_set_bb_reg(dm, 0x41ac, BIT(4), 0);
107 			odm_set_bb_reg(dm, 0x52ac, BIT(4), 0);
108 			odm_set_bb_reg(dm, 0x53ac, BIT(4), 0);
109 		} else if (tab_sel == OFDM_AGC_TAB_2) {
110 			odm_set_bb_reg(dm, 0x18ac, BIT(4), 1);
111 			odm_set_bb_reg(dm, 0x41ac, BIT(4), 1);
112 			odm_set_bb_reg(dm, 0x52ac, BIT(4), 1);
113 			odm_set_bb_reg(dm, 0x53ac, BIT(4), 1);
114 		} else {
115 			odm_set_bb_reg(dm, 0x18ac, BIT(4), 0);
116 			odm_set_bb_reg(dm, 0x41ac, BIT(4), 0);
117 			odm_set_bb_reg(dm, 0x52ac, BIT(4), 0);
118 			odm_set_bb_reg(dm, 0x53ac, BIT(4), 0);
119 		}
120 	} else if (dm->support_ic_type & ODM_RTL8814B) {
121 		if (tab_sel == OFDM_AGC_TAB_0) {
122 			odm_set_bb_reg(dm, 0x18ac, 0xf0, 0);
123 			odm_set_bb_reg(dm, 0x41ac, 0xf0, 0);
124 			odm_set_bb_reg(dm, 0x52ac, 0xf0, 0);
125 			odm_set_bb_reg(dm, 0x53ac, 0xf0, 0);
126 		} else if (tab_sel == OFDM_AGC_TAB_2) {
127 			odm_set_bb_reg(dm, 0x18ac, 0xf0, 2);
128 			odm_set_bb_reg(dm, 0x41ac, 0xf0, 2);
129 			odm_set_bb_reg(dm, 0x52ac, 0xf0, 2);
130 			odm_set_bb_reg(dm, 0x53ac, 0xf0, 2);
131 		} else {
132 			odm_set_bb_reg(dm, 0x18ac, 0xf0, 0);
133 			odm_set_bb_reg(dm, 0x41ac, 0xf0, 0);
134 			odm_set_bb_reg(dm, 0x52ac, 0xf0, 0);
135 			odm_set_bb_reg(dm, 0x53ac, 0xf0, 0);
136 		}
137 	}
138 }
139 
phydm_get_ofdm_agc_tab_path(void * dm_void,enum rf_path path)140 u8 phydm_get_ofdm_agc_tab_path(
141 	void *dm_void,
142 	enum rf_path path)
143 {
144 	struct dm_struct *dm = (struct dm_struct *)dm_void;
145 	u8 tab_sel = 0;
146 
147 	if (dm->support_ic_type & ODM_RTL8198F) {
148 		tab_sel = (u8)odm_get_bb_reg(dm, R_0x18ac, BIT(4));
149 		if (tab_sel == 0)
150 			tab_sel = OFDM_AGC_TAB_0;
151 		else if (tab_sel == 1)
152 			tab_sel = OFDM_AGC_TAB_2;
153 	} else if (dm->support_ic_type & ODM_RTL8814B) {
154 		tab_sel = (u8)odm_get_bb_reg(dm, R_0x18ac, 0xf0);
155 		if (tab_sel == 0)
156 			tab_sel = OFDM_AGC_TAB_0;
157 		else if (tab_sel == 2)
158 			tab_sel = OFDM_AGC_TAB_2;
159 	}
160 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "get path %d AGC Tab %d\n",
161 		  path, tab_sel);
162 	return tab_sel;
163 }
164 #endif /*@#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)*/
165 
phydm_set_ofdm_agc_tab(void * dm_void,u8 tab_sel)166 void phydm_set_ofdm_agc_tab(
167 	void *dm_void,
168 	u8 tab_sel)
169 {
170 	struct dm_struct *dm = (struct dm_struct *)dm_void;
171 
172 	/*@table sel:0/2, 1 is used for CCK */
173 	if (tab_sel == OFDM_AGC_TAB_0)
174 		odm_set_bb_reg(dm, R_0xc70, 0x1e00, OFDM_AGC_TAB_0);
175 	else if (tab_sel == OFDM_AGC_TAB_2)
176 		odm_set_bb_reg(dm, R_0xc70, 0x1e00, OFDM_AGC_TAB_2);
177 	else
178 		odm_set_bb_reg(dm, R_0xc70, 0x1e00, OFDM_AGC_TAB_0);
179 }
180 
phydm_get_ofdm_agc_tab(void * dm_void)181 u8 phydm_get_ofdm_agc_tab(
182 	void *dm_void)
183 {
184 	struct dm_struct *dm = (struct dm_struct *)dm_void;
185 
186 	return (u8)odm_get_bb_reg(dm, R_0xc70, 0x1e00);
187 }
188 
phydm_lna_sat_chk(void * dm_void)189 void phydm_lna_sat_chk(
190 	void *dm_void)
191 {
192 	struct dm_struct *dm = (struct dm_struct *)dm_void;
193 	struct phydm_dig_struct *dig_t = &dm->dm_dig_table;
194 	struct phydm_lna_sat_t *lna_info = &dm->dm_lna_sat_info;
195 	u8 igi_rssi_min;
196 	u8 rssi_min = dm->rssi_min;
197 	u32 sat_status_a, sat_status_b;
198 	#ifdef PHYDM_IC_ABOVE_3SS
199 	u32 sat_status_c;
200 	#endif
201 	#ifdef PHYDM_IC_ABOVE_4SS
202 	u32 sat_status_d;
203 	#endif
204 	u8 igi_restore = dig_t->cur_ig_value;
205 	u8 i, chk_cnt = lna_info->chk_cnt;
206 	u32 lna_sat_cnt_thd = 0;
207 	u8 agc_tab;
208 	u32 max_check_time = 0;
209 	/*@use rssi_max if rssi_min is not stable;*/
210 	/*@rssi_min = dm->rssi_max;*/
211 
212 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "\n%s ==>\n", __func__);
213 
214 	if (!(dm->support_ability & ODM_BB_LNA_SAT_CHK)) {
215 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "Func disable\n");
216 		return;
217 	}
218 
219 	if (lna_info->is_disable_lna_sat_chk) {
220 		phydm_lna_sat_chk_init(dm);
221 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "disable_lna_sat_chk\n");
222 		return;
223 	}
224 
225 	/*@move igi to target pin of rssi_min */
226 	if (rssi_min == 0 || rssi_min == 0xff) {
227 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
228 			  "rssi_min=%d, set AGC Tab0\n", rssi_min);
229 		/*@adapt agc table 0*/
230 		phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_0);
231 		phydm_lna_sat_chk_init(dm);
232 		return;
233 	} else if (rssi_min % 2 != 0) {
234 		igi_rssi_min = rssi_min + DIFF_RSSI_TO_IGI - 1;
235 	} else {
236 		igi_rssi_min = rssi_min + DIFF_RSSI_TO_IGI;
237 	}
238 
239 	if ((lna_info->chk_period > 0) && (lna_info->chk_period <= ONE_SEC_MS))
240 		max_check_time = chk_cnt * (ONE_SEC_MS / (lna_info->chk_period)) * 5;
241 	else
242 		max_check_time = chk_cnt * 5;
243 
244 	lna_sat_cnt_thd = (max_check_time * lna_info->chk_duty_cycle) / 100;
245 
246 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
247 		  "check_time=%d, rssi_min=%d, igi_rssi_min=0x%x\nchk_cnt=%d, chk_period=%d, max_check_time=%d, lna_sat_cnt_thd=%d\n",
248 		  lna_info->check_time,
249 		  rssi_min,
250 		  igi_rssi_min,
251 		  chk_cnt,
252 		  lna_info->chk_period,
253 		  max_check_time,
254 		  lna_sat_cnt_thd);
255 
256 	odm_write_dig(dm, igi_rssi_min);
257 
258 	/*@adapt agc table 0 check saturation status*/
259 	#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
260 	if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B))
261 		phydm_set_ofdm_agc_tab_path(dm, OFDM_AGC_TAB_0, RF_PATH_A);
262 	else
263 	#endif
264 		phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_0);
265 	/*@open rf power detection ckt & set detection range */
266 #if (RTL8198F_SUPPORT)
267 	if (dm->support_ic_type & ODM_RTL8198F) {
268 		/*@set rf detection range (threshold)*/
269 		config_phydm_write_rf_reg_8198f(dm, RF_PATH_A, 0x85,
270 						0x3f, 0x3f);
271 		config_phydm_write_rf_reg_8198f(dm, RF_PATH_B, 0x85,
272 						0x3f, 0x3f);
273 		config_phydm_write_rf_reg_8198f(dm, RF_PATH_C, 0x85,
274 						0x3f, 0x3f);
275 		config_phydm_write_rf_reg_8198f(dm, RF_PATH_D, 0x85,
276 						0x3f, 0x3f);
277 		/*@open rf power detection ckt*/
278 		config_phydm_write_rf_reg_8198f(dm, RF_PATH_A, 0x86, 0x10, 1);
279 		config_phydm_write_rf_reg_8198f(dm, RF_PATH_B, 0x86, 0x10, 1);
280 		config_phydm_write_rf_reg_8198f(dm, RF_PATH_C, 0x86, 0x10, 1);
281 		config_phydm_write_rf_reg_8198f(dm, RF_PATH_D, 0x86, 0x10, 1);
282 	}
283 #elif (RTL8814B_SUPPORT)
284 	if (dm->support_ic_type & ODM_RTL8814B) {
285 		/*@set rf detection range (threshold)*/
286 		config_phydm_write_rf_reg_8814b(dm, RF_PATH_A, 0x8B, 0x3, 0x3);
287 		config_phydm_write_rf_reg_8814b(dm, RF_PATH_B, 0x8B, 0x3, 0x3);
288 		config_phydm_write_rf_reg_8814b(dm, RF_PATH_C, 0x8B, 0x3, 0x3);
289 		config_phydm_write_rf_reg_8814b(dm, RF_PATH_D, 0x8B, 0x3, 0x3);
290 		/*@open rf power detection ckt*/
291 		config_phydm_write_rf_reg_8814b(dm, RF_PATH_A, 0x8B, 0x4, 1);
292 		config_phydm_write_rf_reg_8814b(dm, RF_PATH_B, 0x8B, 0x4, 1);
293 		config_phydm_write_rf_reg_8814b(dm, RF_PATH_C, 0x8B, 0x4, 1);
294 		config_phydm_write_rf_reg_8814b(dm, RF_PATH_D, 0x8B, 0x4, 1);
295 	}
296 #else
297 	odm_set_rf_reg(dm, RF_PATH_A, RF_0x86, 0x1f, 0x10);
298 	odm_set_rf_reg(dm, RF_PATH_B, RF_0x86, 0x1f, 0x10);
299 	#ifdef PHYDM_IC_ABOVE_3SS
300 	odm_set_rf_reg(dm, RF_PATH_C, RF_0x86, 0x1f, 0x10);
301 	#endif
302 	#ifdef PHYDM_IC_ABOVE_4SS
303 	odm_set_rf_reg(dm, RF_PATH_D, RF_0x86, 0x1f, 0x10);
304 	#endif
305 #endif
306 
307 	/*@check saturation status*/
308 	for (i = 0; i < chk_cnt; i++) {
309 #if (RTL8198F_SUPPORT)
310 	if (dm->support_ic_type & ODM_RTL8198F) {
311 		sat_status_a = config_phydm_read_rf_reg_8198f(dm, RF_PATH_A,
312 							      RF_0xae,
313 							      0xe0000);
314 		sat_status_b = config_phydm_read_rf_reg_8198f(dm, RF_PATH_B,
315 							      RF_0xae,
316 							      0xe0000);
317 		sat_status_c = config_phydm_read_rf_reg_8198f(dm, RF_PATH_C,
318 							      RF_0xae,
319 							      0xe0000);
320 		sat_status_d = config_phydm_read_rf_reg_8198f(dm, RF_PATH_D,
321 							      RF_0xae,
322 							      0xe0000);
323 	}
324 #elif (RTL8814B_SUPPORT)
325 	if (dm->support_ic_type & ODM_RTL8814B) {
326 	/*@read peak detector info from 8814B rf reg*/
327 		sat_status_a = config_phydm_read_rf_reg_8814b(dm, RF_PATH_A,
328 							      RF_0xae,
329 							      0xc0000);
330 		sat_status_b = config_phydm_read_rf_reg_8814b(dm, RF_PATH_B,
331 							      RF_0xae,
332 							      0xc0000);
333 		sat_status_c = config_phydm_read_rf_reg_8814b(dm, RF_PATH_C,
334 							      RF_0xae,
335 							      0xc0000);
336 		sat_status_d = config_phydm_read_rf_reg_8814b(dm, RF_PATH_D,
337 							      RF_0xae,
338 							      0xc0000);
339 	}
340 #else
341 		sat_status_a = odm_get_rf_reg(dm, RF_PATH_A, RF_0xae, 0xc0000);
342 		sat_status_b = odm_get_rf_reg(dm, RF_PATH_B, RF_0xae, 0xc0000);
343 		#ifdef PHYDM_IC_ABOVE_3SS
344 		sat_status_c = odm_get_rf_reg(dm, RF_PATH_C, RF_0xae, 0xc0000);
345 		#endif
346 		#ifdef PHYDM_IC_ABOVE_4SS
347 		sat_status_d = odm_get_rf_reg(dm, RF_PATH_D, RF_0xae, 0xc0000);
348 		#endif
349 #endif
350 
351 		if (sat_status_a != 0)
352 			lna_info->sat_cnt_acc_patha++;
353 		if (sat_status_b != 0)
354 			lna_info->sat_cnt_acc_pathb++;
355 		#ifdef PHYDM_IC_ABOVE_3SS
356 		if (sat_status_c != 0)
357 			lna_info->sat_cnt_acc_pathc++;
358 		#endif
359 		#ifdef PHYDM_IC_ABOVE_4SS
360 		if (sat_status_d != 0)
361 			lna_info->sat_cnt_acc_pathd++;
362 		#endif
363 
364 		if (lna_info->sat_cnt_acc_patha >= lna_sat_cnt_thd ||
365 		    lna_info->sat_cnt_acc_pathb >= lna_sat_cnt_thd ||
366 		    #ifdef PHYDM_IC_ABOVE_3SS
367 		    lna_info->sat_cnt_acc_pathc >= lna_sat_cnt_thd ||
368 		    #endif
369 		    #ifdef PHYDM_IC_ABOVE_4SS
370 		    lna_info->sat_cnt_acc_pathd >= lna_sat_cnt_thd ||
371 		    #endif
372 		    0) {
373 			lna_info->cur_sat_status = 1;
374 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
375 				  "cur_sat_status=%d, check_time=%d\n",
376 				  lna_info->cur_sat_status,
377 				  lna_info->check_time);
378 			break;
379 		}
380 		lna_info->cur_sat_status = 0;
381 	}
382 
383 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
384 		  "cur_sat_status=%d, pre_sat_status=%d, sat_cnt_acc_patha=%d, sat_cnt_acc_pathb=%d\n",
385 		  lna_info->cur_sat_status,
386 		  lna_info->pre_sat_status,
387 		  lna_info->sat_cnt_acc_patha,
388 		  lna_info->sat_cnt_acc_pathb);
389 
390 	#ifdef PHYDM_IC_ABOVE_4SS
391 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
392 		  "cur_sat_status=%d, pre_sat_status=%d, sat_cnt_acc_pathc=%d, sat_cnt_acc_pathd=%d\n",
393 		  lna_info->cur_sat_status,
394 		  lna_info->pre_sat_status,
395 		  lna_info->sat_cnt_acc_pathc,
396 		  lna_info->sat_cnt_acc_pathd);
397 	#endif
398 	/*@agc table decision*/
399 	if (lna_info->cur_sat_status) {
400 		if (!lna_info->dis_agc_table_swh)
401 			#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
402 			if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B))
403 				phydm_set_ofdm_agc_tab_path(dm,
404 							    OFDM_AGC_TAB_2,
405 							    RF_PATH_A);
406 			else
407 			#endif
408 				phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_2);
409 		else
410 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
411 				  "disable set to AGC Tab%d\n", OFDM_AGC_TAB_2);
412 		lna_info->check_time = 0;
413 		lna_info->sat_cnt_acc_patha = 0;
414 		lna_info->sat_cnt_acc_pathb = 0;
415 		#ifdef PHYDM_IC_ABOVE_3SS
416 		lna_info->sat_cnt_acc_pathc = 0;
417 		#endif
418 		#ifdef PHYDM_IC_ABOVE_4SS
419 		lna_info->sat_cnt_acc_pathd = 0;
420 		#endif
421 		lna_info->pre_sat_status = lna_info->cur_sat_status;
422 
423 	} else if (lna_info->check_time <= (max_check_time - 1)) {
424 		if (lna_info->pre_sat_status && !lna_info->dis_agc_table_swh)
425 			#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
426 			if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B))
427 				phydm_set_ofdm_agc_tab_path(dm,
428 							    OFDM_AGC_TAB_2,
429 							    RF_PATH_A);
430 			else
431 			#endif
432 				phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_2);
433 
434 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "ckeck time not reached\n");
435 		if (lna_info->dis_agc_table_swh)
436 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
437 				  "disable set to AGC Tab%d\n", OFDM_AGC_TAB_2);
438 		lna_info->check_time++;
439 
440 	} else if (lna_info->check_time >= max_check_time) {
441 		if (!lna_info->dis_agc_table_swh)
442 			#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
443 			if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B))
444 				phydm_set_ofdm_agc_tab_path(dm,
445 							    OFDM_AGC_TAB_0,
446 							    RF_PATH_A);
447 			else
448 			#endif
449 				phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_0);
450 
451 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "ckeck time reached\n");
452 		if (lna_info->dis_agc_table_swh)
453 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
454 				  "disable set to AGC Tab%d\n", OFDM_AGC_TAB_0);
455 		lna_info->check_time = 0;
456 		lna_info->sat_cnt_acc_patha = 0;
457 		lna_info->sat_cnt_acc_pathb = 0;
458 		#ifdef PHYDM_IC_ABOVE_3SS
459 		lna_info->sat_cnt_acc_pathc = 0;
460 		#endif
461 		#ifdef PHYDM_IC_ABOVE_4SS
462 		lna_info->sat_cnt_acc_pathd = 0;
463 		#endif
464 		lna_info->pre_sat_status = lna_info->cur_sat_status;
465 	}
466 
467 	#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
468 	if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B))
469 		agc_tab = phydm_get_ofdm_agc_tab_path(dm, RF_PATH_A);
470 	else
471 	#endif
472 		agc_tab = phydm_get_ofdm_agc_tab(dm);
473 
474 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "use AGC tab %d\n", agc_tab);
475 
476 	/*@restore previous igi*/
477 	odm_write_dig(dm, igi_restore);
478 	lna_info->cur_timer_check_cnt++;
479 	odm_set_timer(dm, &lna_info->phydm_lna_sat_chk_timer,
480 		      lna_info->chk_period);
481 }
482 
phydm_lna_sat_chk_callback(void * dm_void)483 void phydm_lna_sat_chk_callback(
484 	void *dm_void
485 
486 	)
487 {
488 	struct dm_struct *dm = (struct dm_struct *)dm_void;
489 
490 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "\n%s ==>\n", __func__);
491 	phydm_lna_sat_chk(dm);
492 }
493 
phydm_lna_sat_chk_timers(void * dm_void,u8 state)494 void phydm_lna_sat_chk_timers(
495 	void *dm_void,
496 	u8 state)
497 {
498 	struct dm_struct *dm = (struct dm_struct *)dm_void;
499 	struct phydm_lna_sat_t *lna_info = &dm->dm_lna_sat_info;
500 
501 	if (state == INIT_LNA_SAT_CHK_TIMMER) {
502 		odm_initialize_timer(dm,
503 				     &lna_info->phydm_lna_sat_chk_timer,
504 				     (void *)phydm_lna_sat_chk_callback, NULL,
505 				     "phydm_lna_sat_chk_timer");
506 	} else if (state == CANCEL_LNA_SAT_CHK_TIMMER) {
507 		odm_cancel_timer(dm, &lna_info->phydm_lna_sat_chk_timer);
508 	} else if (state == RELEASE_LNA_SAT_CHK_TIMMER) {
509 		odm_release_timer(dm, &lna_info->phydm_lna_sat_chk_timer);
510 	}
511 }
512 
phydm_lna_sat_chk_watchdog_type1(void * dm_void)513 void phydm_lna_sat_chk_watchdog_type1(
514 	void *dm_void)
515 {
516 	struct dm_struct *dm = (struct dm_struct *)dm_void;
517 	struct phydm_lna_sat_t *lna_info = &dm->dm_lna_sat_info;
518 
519 	u8 rssi_min = dm->rssi_min;
520 
521 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
522 
523 	if (!(dm->support_ability & ODM_BB_LNA_SAT_CHK)) {
524 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
525 			  "func disable\n");
526 		return;
527 	}
528 
529 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
530 		  "pre_timer_check_cnt=%d, cur_timer_check_cnt=%d\n",
531 		  lna_info->pre_timer_check_cnt,
532 		  lna_info->cur_timer_check_cnt);
533 
534 	if (lna_info->is_disable_lna_sat_chk) {
535 		phydm_lna_sat_chk_init(dm);
536 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
537 			  "is_disable_lna_sat_chk=%d, return\n",
538 			  lna_info->is_disable_lna_sat_chk);
539 		return;
540 	}
541 
542 	if (rssi_min == 0 || rssi_min == 0xff) {
543 		/*@adapt agc table 0 */
544 		phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_0);
545 		phydm_lna_sat_chk_init(dm);
546 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
547 			  "rssi_min=%d, return\n", rssi_min);
548 		return;
549 	}
550 
551 	if (lna_info->cur_timer_check_cnt == lna_info->pre_timer_check_cnt) {
552 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "fail, restart timer\n");
553 		odm_set_timer(dm, &lna_info->phydm_lna_sat_chk_timer,
554 			      lna_info->chk_period);
555 	} else {
556 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "Timer check pass\n");
557 	}
558 	lna_info->pre_timer_check_cnt = lna_info->cur_timer_check_cnt;
559 }
560 
561 #endif /*@#ifdef PHYDM_LNA_SAT_CHK_TYPE1*/
562 
563 #ifdef PHYDM_LNA_SAT_CHK_TYPE2
564 
phydm_bubble_sort(void * dm_void,u8 * array,u16 array_length)565 void phydm_bubble_sort(
566 	void *dm_void,
567 	u8 *array,
568 	u16 array_length)
569 {
570 	struct dm_struct *dm = (struct dm_struct *)dm_void;
571 	u16 i, j;
572 	u8 temp;
573 
574 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
575 	for (i = 0; i < (array_length - 1); i++) {
576 		for (j = (i + 1); j < (array_length); j++) {
577 			if (array[i] > array[j]) {
578 				temp = array[i];
579 				array[i] = array[j];
580 				array[j] = temp;
581 			}
582 		}
583 	}
584 }
585 
phydm_lna_sat_chk_type2_init(void * dm_void)586 void phydm_lna_sat_chk_type2_init(
587 	void *dm_void)
588 {
589 	struct dm_struct *dm = (struct dm_struct *)dm_void;
590 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
591 	u8 real_shift = pinfo->total_bit_shift;
592 
593 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
594 
595 	pinfo->total_cnt_snr = 1 << real_shift;
596 	pinfo->is_sm_done = TRUE;
597 	pinfo->is_snr_done = FALSE;
598 	pinfo->cur_snr_mean = 0;
599 	pinfo->cur_snr_var = 0;
600 	pinfo->cur_lower_snr_mean = 0;
601 	pinfo->pre_snr_mean = 0;
602 	pinfo->pre_snr_var = 0;
603 	pinfo->pre_lower_snr_mean = 0;
604 	pinfo->nxt_state = ORI_TABLE_MONITOR;
605 	pinfo->pre_state = ORI_TABLE_MONITOR;
606 }
607 
phydm_snr_collect(void * dm_void,u8 rx_snr)608 void phydm_snr_collect(
609 	void *dm_void,
610 	u8 rx_snr)
611 {
612 	struct dm_struct *dm = (struct dm_struct *)dm_void;
613 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
614 
615 	if (pinfo->is_sm_done) {
616 		/* @adapt only path-A for calculation */
617 		pinfo->snr_statistic[pinfo->cnt_snr_statistic] = rx_snr;
618 
619 		if (pinfo->cnt_snr_statistic == (pinfo->total_cnt_snr - 1)) {
620 			pinfo->is_snr_done = TRUE;
621 			pinfo->cnt_snr_statistic = 0;
622 		} else {
623 			pinfo->cnt_snr_statistic++;
624 		}
625 	} else {
626 		return;
627 	}
628 }
629 
phydm_parsing_snr(void * dm_void,void * pktinfo_void,s8 * rx_snr)630 void phydm_parsing_snr(void *dm_void, void *pktinfo_void, s8 *rx_snr)
631 {
632 	struct dm_struct *dm = (struct dm_struct *)dm_void;
633 	struct phydm_lna_sat_t	*lna_t = &dm->dm_lna_sat_info;
634 	struct phydm_perpkt_info_struct *pktinfo = NULL;
635 	u8 target_macid = dm->rssi_min_macid;
636 
637 	if (!(dm->support_ability & ODM_BB_LNA_SAT_CHK))
638 		return;
639 
640 	pktinfo = (struct phydm_perpkt_info_struct *)pktinfo_void;
641 
642 	if (!pktinfo->is_packet_match_bssid)
643 		return;
644 
645 	if (lna_t->force_traget_macid != 0)
646 		target_macid = lna_t->force_traget_macid;
647 
648 	if (target_macid != pktinfo->station_id)
649 		return;
650 
651 	phydm_snr_collect(dm, rx_snr[0]); /*path-A B C D???*/
652 }
653 
phydm_snr_data_processing(void * dm_void)654 void phydm_snr_data_processing(
655 	void *dm_void)
656 {
657 	struct dm_struct *dm = (struct dm_struct *)dm_void;
658 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
659 	u8 real_shift = pinfo->total_bit_shift;
660 	u16 total_snr_cnt = pinfo->total_cnt_snr;
661 	u16 total_loop_cnt = (total_snr_cnt - 1), i;
662 	u32 temp;
663 	u32 sum_snr_statistic = 0;
664 
665 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
666 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
667 		  "total_loop_cnt=%d\n", total_loop_cnt);
668 
669 	for (i = 0; (i <= total_loop_cnt); i++) {
670 		if (pinfo->is_snr_detail_en) {
671 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
672 				  "snr[%d]=%d\n", i, pinfo->snr_statistic[i]);
673 		}
674 
675 		sum_snr_statistic += (u32)(pinfo->snr_statistic[i]);
676 
677 		pinfo->snr_statistic_sqr[i] = (u16)(pinfo->snr_statistic[i] * pinfo->snr_statistic[i]);
678 	}
679 
680 	phydm_bubble_sort(dm, pinfo->snr_statistic, pinfo->total_cnt_snr);
681 
682 	/*update SNR's cur mean*/
683 	pinfo->cur_snr_mean = (sum_snr_statistic >> real_shift);
684 
685 	for (i = 0; (i <= total_loop_cnt); i++) {
686 		if (pinfo->snr_statistic[i] >= pinfo->cur_snr_mean)
687 			temp = pinfo->snr_statistic[i] - pinfo->cur_snr_mean;
688 		else
689 			temp = pinfo->cur_snr_mean - pinfo->snr_statistic[i];
690 
691 		pinfo->cur_snr_var += (temp * temp);
692 	}
693 
694 	/*update SNR's VAR*/
695 	pinfo->cur_snr_var = (pinfo->cur_snr_var >> real_shift);
696 
697 	/*@acquire lower SNR's statistics*/
698 	temp = 0;
699 	pinfo->cnt_lower_snr_statistic = (total_snr_cnt >> pinfo->lwr_snr_ratio_bit_shift);
700 	pinfo->cnt_lower_snr_statistic = MAX_2(pinfo->cnt_lower_snr_statistic, SNR_RPT_MAX);
701 
702 	for (i = 0; i < pinfo->cnt_lower_snr_statistic; i++)
703 		temp += pinfo->snr_statistic[i];
704 
705 	pinfo->cur_lower_snr_mean = temp >> (real_shift - pinfo->lwr_snr_ratio_bit_shift);
706 }
707 
phydm_is_snr_improve(void * dm_void)708 boolean phydm_is_snr_improve(
709 	void *dm_void)
710 {
711 	struct dm_struct *dm = (struct dm_struct *)dm_void;
712 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
713 	boolean is_snr_improve;
714 	u8 cur_state = pinfo->nxt_state;
715 	u32 cur_mean = pinfo->cur_snr_mean;
716 	u32 pre_mean = pinfo->pre_snr_mean;
717 	u32 cur_lower_mean = pinfo->cur_lower_snr_mean;
718 	u32 pre_lower_mean = pinfo->pre_lower_snr_mean;
719 	u32 cur_var = pinfo->cur_snr_var;
720 
721 	/*special case, zero VAR, interference is gone*/
722 	 /*@make sure pre_var is larger enough*/
723 	if (cur_state == SAT_TABLE_MONITOR ||
724 	    cur_state == ORI_TABLE_TRAINING) {
725 		if (cur_mean >= pre_mean) {
726 			if (cur_var == 0)
727 				return true;
728 		}
729 	}
730 #if 0
731 	/*special case, mean degrade less than VAR improvement*/
732 	/*@make sure pre_var is larger enough*/
733 	if (cur_state == ORI_TABLE_MONITOR &&
734 	    cur_mean < pre_mean &&
735 	    cur_var < pre_var) {
736 		diff_mean = pre_mean - cur_mean;
737 		diff_var = pre_var - cur_var;
738 		return (diff_var > (2 * diff_mean * diff_mean)) ? true : false;
739 	}
740 
741 #endif
742 	if (cur_lower_mean >= (pre_lower_mean + pinfo->delta_snr_mean))
743 		is_snr_improve = true;
744 	else
745 		is_snr_improve = false;
746 #if 0
747 /* @condition refine, mean is bigger enough or VAR is smaller enough*/
748 /* @1. from mean's view, mean improve delta_snr_mean(2), VAR not degrade lot*/
749 	if (cur_mean > (pre_mean + pinfo->delta_snr_mean)) {
750 		is_mean_improve = TRUE;
751 		is_var_improve = (cur_var <= pre_var + dm->delta_snr_var)
752 				 ? TRUE : FALSE;
753 
754 	} else if (cur_var + dm->delta_snr_var <= pre_var) {
755 		is_var_improve = TRUE;
756 		is_mean_improve = ((cur_mean + 1) >= pre_mean) ? TRUE : FALSE;
757 	} else {
758 		return false;
759 	}
760 #endif
761 	return is_snr_improve;
762 }
763 
phydm_is_snr_degrade(void * dm_void)764 boolean phydm_is_snr_degrade(
765 	void *dm_void)
766 {
767 	struct dm_struct *dm = (struct dm_struct *)dm_void;
768 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
769 	u32 cur_lower_mean = pinfo->cur_lower_snr_mean;
770 	u32 pre_lower_mean = pinfo->pre_lower_snr_mean;
771 	boolean is_degrade;
772 
773 	if (cur_lower_mean <= (pre_lower_mean - pinfo->delta_snr_mean))
774 		is_degrade = TRUE;
775 	else
776 		is_degrade = FALSE;
777 #if 0
778 	is_mean_dgrade = (pinfo->cur_snr_mean + pinfo->delta_snr_mean <= pinfo->pre_snr_mean) ? TRUE : FALSE;
779 	is_var_degrade = (pinfo->cur_snr_var > (pinfo->pre_snr_var + pinfo->delta_snr_mean)) ? TRUE : FALSE;
780 
781 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s: cur_mean=%d, pre_mean=%d, cur_var=%d, pre_var=%d\n",
782 		  __func__,
783 		  pinfo->cur_snr_mean,
784 		  pinfo->pre_snr_mean,
785 		  pinfo->cur_snr_var,
786 		  pinfo->pre_snr_var);
787 
788 	return (is_mean_dgrade & is_var_degrade);
789 #endif
790 	return is_degrade;
791 }
792 
phydm_is_large_var(void * dm_void)793 boolean phydm_is_large_var(
794 	void *dm_void)
795 {
796 	struct dm_struct *dm = (struct dm_struct *)dm_void;
797 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
798 	boolean is_large_var = (pinfo->cur_snr_var >= pinfo->snr_var_thd) ? TRUE : FALSE;
799 
800 	return is_large_var;
801 }
802 
phydm_update_pre_status(void * dm_void)803 void phydm_update_pre_status(
804 	void *dm_void)
805 {
806 	struct dm_struct *dm = (struct dm_struct *)dm_void;
807 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
808 
809 	pinfo->pre_lower_snr_mean = pinfo->cur_lower_snr_mean;
810 	pinfo->pre_snr_mean = pinfo->cur_snr_mean;
811 	pinfo->pre_snr_var = pinfo->cur_snr_var;
812 }
813 
phydm_ori_table_monitor(void * dm_void)814 void phydm_ori_table_monitor(
815 	void *dm_void)
816 {
817 	struct dm_struct *dm = (struct dm_struct *)dm_void;
818 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
819 
820 	if (phydm_is_large_var(dm)) {
821 		pinfo->nxt_state = SAT_TABLE_TRAINING;
822 		config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
823 	} else {
824 		pinfo->nxt_state = ORI_TABLE_MONITOR;
825 		/*switch to anti-sat table*/
826 		config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
827 	}
828 	phydm_update_pre_status(dm);
829 	pinfo->pre_state = ORI_TABLE_MONITOR;
830 }
831 
phydm_sat_table_training(void * dm_void)832 void phydm_sat_table_training(
833 	void *dm_void)
834 {
835 	struct dm_struct *dm = (struct dm_struct *)dm_void;
836 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
837 
838 	#if 0
839 	if pre_state = ORI_TABLE_MONITOR || SAT_TABLE_TRY_FAIL,
840 	/*@"pre" adapt ori-table, "cur" adapt sat-table*/
841 	/*@adapt ori table*/
842 	if (pinfo->pre_state == ORI_TABLE_MONITOR) {
843 		pinfo->nxt_state = SAT_TABLE_TRAINING;
844 		config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
845 	} else {
846 	#endif
847 	if (phydm_is_snr_improve(dm)) {
848 		pinfo->nxt_state = SAT_TABLE_MONITOR;
849 	} else {
850 		pinfo->nxt_state = SAT_TABLE_TRY_FAIL;
851 		config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
852 	}
853 	/*@}*/
854 
855 	phydm_update_pre_status(dm);
856 	pinfo->pre_state = SAT_TABLE_TRAINING;
857 }
858 
859 void phydm_sat_table_try_fail(
860 	void *dm_void)
861 {
862 	struct dm_struct *dm = (struct dm_struct *)dm_void;
863 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
864 
865 	/* @if pre_state = SAT_TABLE_TRAINING, "pre" adapt sat-table, "cur" adapt ori-table */
866 	/* @if pre_state = SAT_TABLE_TRY_FAIL, "pre" adapt ori-table, "cur" adapt ori-table */
867 
868 	if (phydm_is_large_var(dm)) {
869 		if (phydm_is_snr_degrade(dm)) {
870 			pinfo->nxt_state = SAT_TABLE_TRAINING;
871 			config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
872 		} else {
873 			pinfo->nxt_state = SAT_TABLE_TRY_FAIL;
874 		}
875 	} else {
876 		pinfo->nxt_state = ORI_TABLE_MONITOR;
877 	}
878 	phydm_update_pre_status(dm);
879 	pinfo->pre_state = SAT_TABLE_TRY_FAIL;
880 }
881 
882 void phydm_sat_table_monitor(
883 	void *dm_void)
884 {
885 	struct dm_struct *dm = (struct dm_struct *)dm_void;
886 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
887 
888 	if (phydm_is_snr_improve(dm)) {
889 		pinfo->sat_table_monitor_times = 0;
890 
891 		/* @if pre_state = SAT_TABLE_MONITOR, "pre" adapt sat-table, "cur" adapt sat-table */
892 		if (pinfo->pre_state == SAT_TABLE_MONITOR) {
893 			pinfo->nxt_state = ORI_TABLE_TRAINING;
894 			config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
895 			//phydm_update_pre_status(dm);
896 		} else {
897 			pinfo->nxt_state = SAT_TABLE_MONITOR;
898 		}
899 
900 		/* @if pre_state = SAT_TABLE_TRAINING, "pre" adapt sat-table, "cur" adapt sat-table */
901 		/* @if pre_state = ORI_TABLE_TRAINING, "pre" adapt ori-table, "cur" adapt sat-table */
902 		/*pre_state above is no need to update*/
903 	} else {
904 		if (pinfo->sat_table_monitor_times == pinfo->force_change_period) {
905 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s: sat_table_monitor_times=%d\n",
906 				  __func__, pinfo->sat_table_monitor_times);
907 
908 			pinfo->nxt_state = ORI_TABLE_TRAINING;
909 			pinfo->sat_table_monitor_times = 0;
910 			config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
911 		} else {
912 			pinfo->nxt_state = SAT_TABLE_MONITOR;
913 			pinfo->sat_table_monitor_times++;
914 		}
915 	}
916 	phydm_update_pre_status(dm);
917 	pinfo->pre_state = SAT_TABLE_MONITOR;
918 }
919 
920 void phydm_ori_table_training(
921 	void *dm_void)
922 {
923 	struct dm_struct *dm = (struct dm_struct *)dm_void;
924 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
925 
926 	/* pre_state = SAT_TABLE_MONITOR, "pre" adapt sat-table, "cur" adapt ori-table */
927 
928 	if (phydm_is_snr_degrade(dm) == FALSE) {
929 		pinfo->nxt_state = ORI_TABLE_MONITOR;
930 	} else {
931 		if (pinfo->pre_snr_var == 0)
932 			pinfo->nxt_state = ORI_TABLE_TRY_FAIL;
933 		else
934 			pinfo->nxt_state = SAT_TABLE_MONITOR;
935 
936 		config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
937 	}
938 	phydm_update_pre_status(dm);
939 	pinfo->pre_state = ORI_TABLE_TRAINING;
940 }
941 
942 void phydm_ori_table_try_fail(
943 	void *dm_void)
944 {
945 	struct dm_struct *dm = (struct dm_struct *)dm_void;
946 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
947 
948 	if (pinfo->pre_state == ORI_TABLE_TRY_FAIL) {
949 		if (phydm_is_snr_improve(dm)) {
950 			pinfo->nxt_state = ORI_TABLE_TRAINING;
951 			pinfo->ori_table_try_fail_times = 0;
952 			config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
953 		} else {
954 			if (pinfo->ori_table_try_fail_times == pinfo->force_change_period) {
955 				PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
956 					  "%s: ori_table_try_fail_times=%d\n", __func__, pinfo->ori_table_try_fail_times);
957 
958 				pinfo->nxt_state = ORI_TABLE_TRY_FAIL;
959 				pinfo->ori_table_try_fail_times = 0;
960 				phydm_update_pre_status(dm);
961 			} else {
962 				pinfo->nxt_state = ORI_TABLE_TRY_FAIL;
963 				pinfo->ori_table_try_fail_times++;
964 				phydm_update_pre_status(dm);
965 				//config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
966 			}
967 		}
968 	} else {
969 		pinfo->nxt_state = ORI_TABLE_TRY_FAIL;
970 		pinfo->ori_table_try_fail_times = 0;
971 		phydm_update_pre_status(dm);
972 		//config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
973 	}
974 
975 #if 0
976 	if (phydm_is_large_var(dm)) {
977 		if (phydm_is_snr_degrade(dm)) {
978 			pinfo->nxt_state = SAT_TABLE_TRAINING;
979 			config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
980 		} else {
981 			pinfo->nxt_state = SAT_TABLE_TRY_FAIL;
982 		}
983 	} else {
984 		pinfo->nxt_state = ORI_TABLE_MONITOR;
985 	}
986 
987 	phydm_update_pre_status(dm);
988 #endif
989 	pinfo->pre_state = ORI_TABLE_TRY_FAIL;
990 }
991 
992 char *phydm_lna_sat_state_msg(
993 	void *dm_void,
994 	IN u8 state)
995 {
996 	char *dbg_message;
997 
998 	switch (state) {
999 	case ORI_TABLE_MONITOR:
1000 		dbg_message = "ORI_TABLE_MONITOR";
1001 		break;
1002 
1003 	case SAT_TABLE_TRAINING:
1004 		dbg_message = "SAT_TABLE_TRAINING";
1005 		break;
1006 
1007 	case SAT_TABLE_TRY_FAIL:
1008 		dbg_message = "SAT_TABLE_TRY_FAIL";
1009 		break;
1010 
1011 	case SAT_TABLE_MONITOR:
1012 		dbg_message = "SAT_TABLE_MONITOR";
1013 		break;
1014 
1015 	case ORI_TABLE_TRAINING:
1016 		dbg_message = "ORI_TABLE_TRAINING";
1017 		break;
1018 
1019 	case ORI_TABLE_TRY_FAIL:
1020 		dbg_message = "ORI_TABLE_TRY_FAIL";
1021 		break;
1022 
1023 	default:
1024 		dbg_message = "ORI_TABLE_MONITOR";
1025 		break;
1026 	}
1027 
1028 	return dbg_message;
1029 }
1030 
1031 void phydm_lna_sat_type2_sm(
1032 	void *dm_void)
1033 {
1034 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1035 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
1036 	u8 state = pinfo->nxt_state;
1037 	u8 agc_tab = (u8)odm_get_bb_reg(dm, 0x958, 0x1f);
1038 	char *dbg_message, *nxt_dbg_message;
1039 	u8 real_shift = pinfo->total_bit_shift;
1040 
1041 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "\n\n%s ==>\n", __func__);
1042 
1043 	if ((dm->support_ic_type & ODM_RTL8822B) == FALSE) {
1044 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "ODM_BB_LNA_SAT_CHK_TYPE2 only support 22B.\n");
1045 		return;
1046 	}
1047 
1048 	if ((dm->support_ability & ODM_BB_LNA_SAT_CHK) == FALSE) {
1049 		phydm_lna_sat_chk_type2_init(dm);
1050 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "ODM_BB_LNA_SAT_CHK_TYPE2 is NOT supported, cur table=%d\n", agc_tab);
1051 		return;
1052 	}
1053 
1054 	if (pinfo->is_snr_done)
1055 		phydm_snr_data_processing(dm);
1056 	else
1057 		return;
1058 
1059 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "cur agc table %d\n", agc_tab);
1060 
1061 	if (pinfo->is_force_lna_sat_table != AUTO_AGC_TABLE) {
1062 		/*reset state machine*/
1063 		pinfo->nxt_state = ORI_TABLE_MONITOR;
1064 		if (pinfo->is_snr_done) {
1065 			if (pinfo->is_force_lna_sat_table == DEFAULT_AGC_TABLE)
1066 				config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
1067 			else if (pinfo->is_force_lna_sat_table == LNA_SAT_AGC_TABLE)
1068 				config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
1069 			else
1070 				config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
1071 
1072 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
1073 				  "%s: cur_mean=%d, pre_mean=%d, cur_var=%d, pre_var=%d,cur_lower_mean=%d, pre_lower_mean=%d, cnt_lower_snr=%d\n",
1074 				  __func__,
1075 				  pinfo->cur_snr_mean,
1076 				  pinfo->pre_snr_mean,
1077 				  pinfo->cur_snr_var,
1078 				  pinfo->pre_snr_var,
1079 				  pinfo->cur_lower_snr_mean,
1080 				  pinfo->pre_lower_snr_mean,
1081 				  pinfo->cnt_lower_snr_statistic);
1082 
1083 			pinfo->is_snr_done = FALSE;
1084 			pinfo->is_sm_done = TRUE;
1085 			phydm_update_pre_status(dm);
1086 		} else {
1087 			return;
1088 		}
1089 	} else if (pinfo->is_snr_done) {
1090 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
1091 			  "%s: cur_mean=%d, pre_mean=%d, cur_var=%d, pre_var=%d,cur_lower_mean=%d, pre_lower_mean=%d, cnt_lower_snr=%d\n",
1092 			  __func__,
1093 			  pinfo->cur_snr_mean,
1094 			  pinfo->pre_snr_mean,
1095 			  pinfo->cur_snr_var,
1096 			  pinfo->pre_snr_var,
1097 			  pinfo->cur_lower_snr_mean,
1098 			  pinfo->pre_lower_snr_mean,
1099 			  pinfo->cnt_lower_snr_statistic);
1100 
1101 		switch (state) {
1102 		case ORI_TABLE_MONITOR:
1103 			dbg_message = "ORI_TABLE_MONITOR";
1104 			phydm_ori_table_monitor(dm);
1105 			break;
1106 
1107 		case SAT_TABLE_TRAINING:
1108 			dbg_message = "SAT_TABLE_TRAINING";
1109 			phydm_sat_table_training(dm);
1110 			break;
1111 
1112 		case SAT_TABLE_TRY_FAIL:
1113 			dbg_message = "SAT_TABLE_TRY_FAIL";
1114 			phydm_sat_table_try_fail(dm);
1115 			break;
1116 
1117 		case SAT_TABLE_MONITOR:
1118 			dbg_message = "SAT_TABLE_MONITOR";
1119 			phydm_sat_table_monitor(dm);
1120 			break;
1121 
1122 		case ORI_TABLE_TRAINING:
1123 			dbg_message = "ORI_TABLE_TRAINING";
1124 			phydm_ori_table_training(dm);
1125 			break;
1126 
1127 		case ORI_TABLE_TRY_FAIL:
1128 			dbg_message = "ORI_TABLE_TRAINING";
1129 			phydm_ori_table_try_fail(dm);
1130 			break;
1131 
1132 		default:
1133 			dbg_message = "ORI_TABLE_MONITOR";
1134 			phydm_ori_table_monitor(dm);
1135 			break;
1136 		}
1137 
1138 		dbg_message = phydm_lna_sat_state_msg(dm, state);
1139 		nxt_dbg_message = phydm_lna_sat_state_msg(dm, pinfo->nxt_state);
1140 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "state: [%s]->[%s]\n",
1141 			  dbg_message, nxt_dbg_message);
1142 
1143 		pinfo->is_snr_done = FALSE;
1144 		pinfo->is_sm_done = TRUE;
1145 		pinfo->total_cnt_snr = 1 << real_shift;
1146 
1147 	} else {
1148 		return;
1149 	}
1150 }
1151 #endif /*@#ifdef PHYDM_LNA_SAT_CHK_TYPE2*/
1152 
1153 #ifdef PHYDM_HW_SWITCH_AGC_TAB
1154 u32 phydm_get_lna_pd_reg(void *dm_void)
1155 {
1156 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1157 	u32 rf_pd_reg = RF_0x8b;
1158 
1159 #if (RTL8814B_SUPPORT)
1160 		if (dm->support_ic_type & ODM_RTL8814B) {
1161 			if (*dm->channel <= 14)
1162 				rf_pd_reg = RF_0x87;
1163 			else
1164 				rf_pd_reg = RF_0x8b;
1165 		}
1166 #endif
1167 	return rf_pd_reg;
1168 }
1169 
1170 u32 phydm_get_lna_pd_en_mask(void *dm_void)
1171 {
1172 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1173 	u32 rf_pd_en_msk = BIT(2);
1174 
1175 #if (RTL8814B_SUPPORT)
1176 		if (dm->support_ic_type & ODM_RTL8814B) {
1177 			if (*dm->channel <= 14)
1178 				rf_pd_en_msk = BIT(4);
1179 			else
1180 				rf_pd_en_msk = BIT(2);
1181 		}
1182 #endif
1183 	return rf_pd_en_msk;
1184 }
1185 
1186 boolean phydm_get_lna_pd_en(void *dm_void)
1187 {
1188 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1189 	u32 rf_pd_reg = RF_0x8b;
1190 	u32 rf_pd_en_msk = BIT(2);
1191 	u32 pd_en = 0;
1192 
1193 	rf_pd_reg = phydm_get_lna_pd_reg(dm);
1194 	rf_pd_en_msk = phydm_get_lna_pd_en_mask(dm);
1195 
1196 #if (RTL8814B_SUPPORT)
1197 		if (dm->support_ic_type & ODM_RTL8814B)
1198 			pd_en = config_phydm_read_rf_reg_8814b(dm, RF_PATH_A,
1199 							       rf_pd_reg,
1200 							       rf_pd_en_msk);
1201 #endif
1202 	return (boolean)pd_en;
1203 }
1204 
1205 void phydm_set_lna_pd_en(void *dm_void, boolean lna_pd_en)
1206 {
1207 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1208 	enum rf_path i = RF_PATH_A;
1209 	u32 rf_pd_reg = RF_0x8b;
1210 	u32 rf_pd_en_msk = BIT(2);
1211 
1212 	rf_pd_reg = phydm_get_lna_pd_reg(dm);
1213 	rf_pd_en_msk = phydm_get_lna_pd_en_mask(dm);
1214 
1215 #if (RTL8814B_SUPPORT)
1216 		if (dm->support_ic_type & ODM_RTL8814B)
1217 			for (i = RF_PATH_A; i < MAX_PATH_NUM_8814B; i++)
1218 				config_phydm_write_rf_reg_8814b(dm, i,
1219 								rf_pd_reg,
1220 								rf_pd_en_msk,
1221 								(u8)lna_pd_en);
1222 #endif
1223 }
1224 
1225 u32 phydm_get_lna_pd_th_mask(void *dm_void)
1226 {
1227 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1228 	u32 rf_pd_th_msk = 0x3;
1229 
1230 #if (RTL8814B_SUPPORT)
1231 		if (dm->support_ic_type & ODM_RTL8814B)
1232 			rf_pd_th_msk = 0x3;
1233 #endif
1234 	return rf_pd_th_msk;
1235 }
1236 
1237 enum lna_pd_th_level phydm_get_lna_pd_th_lv(void *dm_void)
1238 {
1239 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1240 	u32 rf_pd_reg = RF_0x8b;
1241 	u32 rf_pd_th_msk = 0x3;
1242 	u32 pd_th_lv = 0x0;
1243 
1244 	rf_pd_reg = phydm_get_lna_pd_reg(dm);
1245 	rf_pd_th_msk = phydm_get_lna_pd_th_mask(dm);
1246 
1247 #if (RTL8814B_SUPPORT)
1248 	if (dm->support_ic_type & ODM_RTL8814B)
1249 		pd_th_lv = config_phydm_read_rf_reg_8814b(dm, RF_PATH_A,
1250 							  rf_pd_reg,
1251 							  rf_pd_th_msk);
1252 #endif
1253 	return (enum lna_pd_th_level)pd_th_lv;
1254 }
1255 
1256 void phydm_set_lna_pd_th_lv(void *dm_void,
1257 			    enum lna_pd_th_level lna_pd_th_lv)
1258 {
1259 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1260 	enum rf_path i = RF_PATH_A;
1261 	u32 rf_pd_reg = RF_0x8b;
1262 	u32 rf_pd_th_msk = 0x3;
1263 
1264 	rf_pd_reg = phydm_get_lna_pd_reg(dm);
1265 	rf_pd_th_msk = phydm_get_lna_pd_th_mask(dm);
1266 
1267 #if (RTL8814B_SUPPORT)
1268 		if (dm->support_ic_type & ODM_RTL8814B)
1269 			for (i = RF_PATH_A; i < MAX_PATH_NUM_8814B; i++)
1270 				config_phydm_write_rf_reg_8814b(dm, i,
1271 								rf_pd_reg,
1272 								rf_pd_th_msk,
1273 								lna_pd_th_lv);
1274 #endif
1275 }
1276 
1277 u32 phydm_get_sat_agc_tab_version(void *dm_void)
1278 {
1279 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1280 
1281 #if (RTL8814B_SUPPORT)
1282 	if (dm->support_ic_type & ODM_RTL8814B)
1283 		return odm_get_version_mp_8814b_extra_agc_tab();
1284 #endif
1285 	return 0;
1286 }
1287 
1288 boolean phydm_get_auto_agc_config(void *dm_void,
1289 				  enum agc_tab_switch_state state_sel)
1290 {
1291 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1292 	u32 state_en = 0;
1293 #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
1294 	switch (state_sel) {
1295 	case AGC_SWH_IDLE:
1296 		state_en = odm_get_bb_reg(dm, R_0x18ac, BIT(16));
1297 		break;
1298 	case AGC_SWH_OFDM:
1299 		state_en = odm_get_bb_reg(dm, R_0x18ac, BIT(17));
1300 		break;
1301 	case AGC_SWH_CCK:
1302 		state_en = odm_get_bb_reg(dm, R_0x18ac, BIT(18));
1303 		break;
1304 	default:
1305 		state_en = 0;
1306 		break;
1307 	}
1308 #endif
1309 	return (boolean)state_en;
1310 }
1311 
1312 boolean phydm_is_auto_agc_on(void *dm_void)
1313 {
1314 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1315 	boolean state_on = false;
1316 
1317 	state_on = ((phydm_get_auto_agc_config(dm, AGC_SWH_IDLE) ||
1318 		     phydm_get_auto_agc_config(dm, AGC_SWH_CCK) ||
1319 		     phydm_get_auto_agc_config(dm, AGC_SWH_OFDM)) &&
1320 		     phydm_get_lna_pd_en(dm));
1321 
1322 	return state_on;
1323 }
1324 
1325 void phydm_config_auto_agc(void *dm_void,
1326 			   boolean idle_en,
1327 			   boolean cck_cca_en,
1328 			   boolean ofdm_cca_en)
1329 {
1330 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1331 	u32 hwagc_opt = 0;
1332 #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
1333 	if (dm->support_ic_type & ~ODM_RTL8814B)
1334 		return;
1335 
1336 	if (idle_en)
1337 		hwagc_opt |= BIT(0);
1338 	else
1339 		hwagc_opt &= ~BIT(0);
1340 	if (ofdm_cca_en)
1341 		hwagc_opt |= BIT(1);
1342 	else
1343 		hwagc_opt &= ~BIT(1);
1344 	if (cck_cca_en)
1345 		hwagc_opt |= BIT(2);
1346 	else
1347 		hwagc_opt &= ~BIT(2);
1348 
1349 	odm_set_bb_reg(dm, R_0x18ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt);
1350 #ifdef PHYDM_COMPILE_ABOVE_2SS
1351 	odm_set_bb_reg(dm, R_0x41ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt);
1352 #endif
1353 #ifdef PHYDM_COMPILE_ABOVE_3SS
1354 	odm_set_bb_reg(dm, R_0x52ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt);
1355 #endif
1356 #ifdef PHYDM_COMPILE_ABOVE_4SS
1357 	odm_set_bb_reg(dm, R_0x53ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt);
1358 #endif
1359 #endif
1360 }
1361 
1362 void phydm_auto_agc_tab_reset(void *dm_void)
1363 {
1364 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1365 
1366 	phydm_set_lna_pd_th_lv(dm, 0x0);
1367 	phydm_config_auto_agc(dm, true, false, true);
1368 	phydm_set_lna_pd_en(dm, true);
1369 }
1370 
1371 void phydm_auto_agc_tab_off(void *dm_void)
1372 {
1373 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1374 
1375 	phydm_config_auto_agc(dm, false, false, false);
1376 	phydm_set_lna_pd_en(dm, false);
1377 }
1378 
1379 void phydm_switch_sat_agc_by_band(void *dm_void)
1380 {
1381 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1382 	struct phydm_lna_sat_t	*lna_sat = &dm->dm_lna_sat_info;
1383 
1384 #if (RTL8814B_SUPPORT)
1385 	if (dm->support_ic_type & ODM_RTL8814B)
1386 		odm_config_mp_8814b_extra_agc_tab(dm, lna_sat->cur_rf_band);
1387 #endif
1388 #if (DM_ODM_SUPPORT_TYPE == ODM_AP)
1389 	pr_debug("%s ==> switch to band%d\n", __func__, lna_sat->cur_rf_band);
1390 #else
1391 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==> switch to band%d\n",
1392 		  __func__, lna_sat->cur_rf_band);
1393 #endif
1394 }
1395 
1396 void phydm_auto_agc_tab_init(void *dm_void)
1397 {
1398 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1399 	struct phydm_lna_sat_t	*lna_sat = &dm->dm_lna_sat_info;
1400 	u8 channel = *dm->channel;
1401 
1402 	lna_sat->cur_rf_band = phydm_ch_to_rf_band(dm, channel);
1403 	phydm_switch_sat_agc_by_band(dm);
1404 
1405 	if ((dm->support_ability & ODM_BB_LNA_SAT_CHK)) {
1406 		phydm_auto_agc_tab_reset(dm);
1407 		lna_sat->hw_swh_tab_on = true;
1408 	} else {
1409 		phydm_auto_agc_tab_off(dm);
1410 		lna_sat->hw_swh_tab_on = false;
1411 	}
1412 }
1413 
1414 void phydm_auto_agc_tab_watchdog(void *dm_void)
1415 {
1416 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1417 	struct phydm_lna_sat_t	*lna_sat = &dm->dm_lna_sat_info;
1418 	boolean hw_swh_on = false;
1419 
1420 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
1421 
1422 	if (!(dm->support_ability & ODM_BB_LNA_SAT_CHK)) {
1423 		if (lna_sat->hw_swh_tab_on) {
1424 			phydm_auto_agc_tab_off(dm);
1425 			lna_sat->hw_swh_tab_on = false;
1426 		}
1427 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "Disabled LNA sat. check\n");
1428 		return;
1429 	}
1430 
1431 	if (!lna_sat->hw_swh_tab_on)
1432 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
1433 			  "[WARNING] HW switch AGC Tab not fully enabled\n");
1434 }
1435 
1436 void phydm_auto_agc_tab_debug(void *dm_void, char input[][16], u32 *_used,
1437 			      char *output, u32 *_out_len)
1438 {
1439 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1440 	struct phydm_lna_sat_t	*lna_sat = &dm->dm_lna_sat_info;
1441 	char help[] = "-h";
1442 	u32 var1[10] = {0};
1443 	u32 used = *_used;
1444 	u32 out_len = *_out_len;
1445 	u8 i;
1446 	u8 agc_tab = 0;
1447 
1448 	if ((strcmp(input[1], help) == 0)) {
1449 		PDM_SNPF(out_len, used, output + used, out_len - used,
1450 			 "LNA sat. AGC Tab version : %d\n",
1451 			 phydm_get_sat_agc_tab_version(dm));
1452 		PDM_SNPF(out_len, used, output + used, out_len - used,
1453 			 "Enable LNA peak detector : {0} {lna_pd_en = %d}\n",
1454 			 phydm_get_lna_pd_en(dm));
1455 		PDM_SNPF(out_len, used, output + used, out_len - used,
1456 			 "Set LNA peak detector lv : {1} {lna_pd_th_lv = %d}\n",
1457 			 phydm_get_lna_pd_th_lv(dm));
1458 		PDM_SNPF(out_len, used, output + used, out_len - used,
1459 			 "Config hw switch AGC tab : {2} {hw_swh_en_rx_idle} {hw_swh_en_cck_cca} {hw_swh_en_ofdm_cca} = (%d, %d, %d)\n",
1460 			 phydm_get_auto_agc_config(dm, AGC_SWH_IDLE),
1461 			 phydm_get_auto_agc_config(dm, AGC_SWH_CCK),
1462 			 phydm_get_auto_agc_config(dm, AGC_SWH_OFDM));
1463 		PDM_SNPF(out_len, used, output + used, out_len - used,
1464 			 "Reset to default setting : {3}\n",
1465 			 phydm_get_auto_agc_config(dm, AGC_SWH_IDLE),
1466 			 phydm_get_auto_agc_config(dm, AGC_SWH_CCK),
1467 			 phydm_get_auto_agc_config(dm, AGC_SWH_OFDM));
1468 
1469 	} else {
1470 		PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
1471 		for (i = 1; i < 10; i++) {
1472 			if (input[i + 1])
1473 				PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
1474 					     &var1[i]);
1475 		}
1476 
1477 		if (var1[0] == 0) {
1478 			phydm_set_lna_pd_en(dm, (boolean)var1[1]);
1479 			PDM_SNPF(out_len, used, output + used, out_len - used,
1480 				 "set lna_pd_en = %d\n",
1481 				 (u8)phydm_get_lna_pd_en(dm));
1482 		} else if (var1[0] == 1) {
1483 			phydm_set_lna_pd_th_lv(dm, (u8)var1[1]);
1484 			PDM_SNPF(out_len, used, output + used, out_len - used,
1485 				 "set lna_pd_th_lv = %d\n",
1486 				 phydm_get_lna_pd_th_lv(dm));
1487 		}  else if (var1[0] == 2) {
1488 			phydm_config_auto_agc(dm, (boolean)var1[1],
1489 					      (boolean)var1[2],
1490 					      (boolean)var1[3]);
1491 			PDM_SNPF(out_len, used, output + used, out_len - used,
1492 				 "set hw switch agc tab en: (rx_idle, cck_cca, ofdm_cca) = (%d, %d, %d)\n",
1493 				 phydm_get_auto_agc_config(dm, AGC_SWH_IDLE),
1494 				 phydm_get_auto_agc_config(dm, AGC_SWH_CCK),
1495 				 phydm_get_auto_agc_config(dm, AGC_SWH_OFDM));
1496 		}  else if (var1[0] == 3) {
1497 			PDM_SNPF(out_len, used, output + used, out_len - used,
1498 				 "reset to default settings\n");
1499 			phydm_auto_agc_tab_reset(dm);
1500 		}
1501 		lna_sat->hw_swh_tab_on = phydm_is_auto_agc_on(dm);
1502 	}
1503 	*_used = used;
1504 	*_out_len = out_len;
1505 }
1506 #endif /*@#ifdef PHYDM_HW_SWITCH_AGC_TAB*/
1507 
1508 void phydm_lna_sat_debug(void *dm_void,	char input[][16], u32 *_used,
1509 			 char *output, u32 *_out_len)
1510 {
1511 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1512 	struct phydm_lna_sat_t	*lna_t = &dm->dm_lna_sat_info;
1513 	char help[] = "-h";
1514 	char monitor[] = "-m";
1515 	u32 var1[10] = {0};
1516 	u32 used = *_used;
1517 	u32 out_len = *_out_len;
1518 	u8 i;
1519 	u8 agc_tab = 0;
1520 
1521 	if ((strcmp(input[1], help) == 0)) {
1522 		PDM_SNPF(out_len, used, output + used, out_len - used,
1523 			 "monitor: -m\n");
1524 		#ifdef PHYDM_LNA_SAT_CHK_TYPE1
1525 		PDM_SNPF(out_len, used, output + used, out_len - used,
1526 			 "{0} {lna_sat_chk_en}\n");
1527 		PDM_SNPF(out_len, used, output + used, out_len - used,
1528 			 "{1} {agc_table_switch_en}\n");
1529 		PDM_SNPF(out_len, used, output + used, out_len - used,
1530 			 "{2} {chk_cnt per callback}\n");
1531 		PDM_SNPF(out_len, used, output + used, out_len - used,
1532 			 "{3} {chk_period(ms)}\n");
1533 		PDM_SNPF(out_len, used, output + used, out_len - used,
1534 			 "{4} {chk_duty_cycle(%)}\n");
1535 		#endif
1536 	} else if ((strcmp(input[1], monitor) == 0)) {
1537 #ifdef PHYDM_LNA_SAT_CHK_TYPE1
1538 		#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
1539 		if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B))
1540 			agc_tab = phydm_get_ofdm_agc_tab_path(dm, RF_PATH_A);
1541 		else
1542 		#endif
1543 			agc_tab = phydm_get_ofdm_agc_tab(dm);
1544 
1545 		PDM_SNPF(out_len, used, output + used, out_len - used,
1546 			 "%s%d, %s%d, %s%d, %s%d\n",
1547 			 "check_time = ", lna_t->check_time,
1548 			 "pre_sat_status = ", lna_t->pre_sat_status,
1549 			 "cur_sat_status = ", lna_t->cur_sat_status,
1550 			 "current AGC tab = ", agc_tab);
1551 #endif
1552 	} else {
1553 		PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
1554 
1555 		for (i = 1; i < 10; i++) {
1556 			if (input[i + 1])
1557 				PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
1558 					     &var1[i]);
1559 		}
1560 		#ifdef PHYDM_LNA_SAT_CHK_TYPE1
1561 		if (var1[0] == 0) {
1562 			if (var1[1] == 1)
1563 				lna_t->is_disable_lna_sat_chk = false;
1564 			else if (var1[1] == 0)
1565 				lna_t->is_disable_lna_sat_chk = true;
1566 
1567 			PDM_SNPF(out_len, used, output + used, out_len - used,
1568 				 "dis_lna_sat_chk=%d\n",
1569 				 lna_t->is_disable_lna_sat_chk);
1570 		} else if (var1[0] == 1) {
1571 			if (var1[1] == 1)
1572 				lna_t->dis_agc_table_swh = false;
1573 			else if (var1[1] == 0)
1574 				lna_t->dis_agc_table_swh = true;
1575 
1576 			PDM_SNPF(out_len, used, output + used, out_len - used,
1577 				 "dis_agc_table_swh=%d\n",
1578 				 lna_t->dis_agc_table_swh);
1579 
1580 		} else if (var1[0] == 2) {
1581 			lna_t->chk_cnt = (u8)var1[1];
1582 			PDM_SNPF(out_len, used, output + used, out_len - used,
1583 				 "chk_cnt=%d\n", lna_t->chk_cnt);
1584 		} else if (var1[0] == 3) {
1585 			lna_t->chk_period = var1[1];
1586 			PDM_SNPF(out_len, used, output + used, out_len - used,
1587 				 "chk_period=%d\n", lna_t->chk_period);
1588 		} else if (var1[0] == 4) {
1589 			lna_t->chk_duty_cycle = (u8)var1[1];
1590 			PDM_SNPF(out_len, used, output + used, out_len - used,
1591 				 "chk_duty_cycle=%d\n",
1592 				 lna_t->chk_duty_cycle);
1593 		}
1594 		#endif
1595 		#ifdef PHYDM_LNA_SAT_CHK_TYPE2
1596 		if (var1[0] == 1)
1597 			lna_t->force_traget_macid = var1[1];
1598 		#endif
1599 	}
1600 	*_used = used;
1601 	*_out_len = out_len;
1602 }
1603 
1604 void phydm_lna_sat_chk_watchdog(void *dm_void)
1605 {
1606 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1607 	struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info;
1608 
1609 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
1610 
1611 	if (lna_sat->lna_sat_type == LNA_SAT_WITH_PEAK_DET) {
1612 		#ifdef PHYDM_HW_SWITCH_AGC_TAB
1613 		if (dm->support_ic_type & ODM_RTL8814B) {
1614 			phydm_auto_agc_tab_watchdog(dm);
1615 			return;
1616 		}
1617 		#endif
1618 		#ifdef PHYDM_LNA_SAT_CHK_TYPE1
1619 		if (dm->support_ic_type &
1620 		    (ODM_RTL8197F | ODM_RTL8198F | ODM_RTL8814B)) {
1621 			phydm_lna_sat_chk_watchdog_type1(dm);
1622 			return;
1623 		}
1624 		#endif
1625 	} else if (lna_sat->lna_sat_type == LNA_SAT_WITH_TRAIN) {
1626 		#ifdef PHYDM_LNA_SAT_CHK_TYPE2
1627 		return;
1628 		#endif
1629 	}
1630 
1631 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "support_ic_type match fail, return\n");
1632 }
1633 
1634 void phydm_lna_sat_config(void *dm_void)
1635 {
1636 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1637 	struct phydm_lna_sat_t	*lna_sat = &dm->dm_lna_sat_info;
1638 
1639 	lna_sat->lna_sat_type = 0;
1640 	#if (RTL8822B_SUPPORT == 1)
1641 	if (dm->support_ic_type & (ODM_RTL8822B))
1642 		lna_sat->lna_sat_type = LNA_SAT_WITH_TRAIN;
1643 	#endif
1644 
1645 	#if (RTL8197F_SUPPORT || RTL8192F_SUPPORT || \
1646 	     RTL8198F_SUPPORT || RTL8814B_SUPPORT)
1647 	if (dm->support_ic_type &
1648 	    (ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8198F | ODM_RTL8814B))
1649 		lna_sat->lna_sat_type = LNA_SAT_WITH_PEAK_DET;
1650 	#endif
1651 
1652 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "[%s] lna_sat_type=%d\n",
1653 		  __func__, lna_sat->lna_sat_type);
1654 }
1655 
1656 void phydm_lna_sat_check_init(void *dm_void)
1657 {
1658 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1659 	struct phydm_lna_sat_t	*lna_sat = &dm->dm_lna_sat_info;
1660 
1661 	/*@2018.04.17 Johnson*/
1662 	phydm_lna_sat_config(dm);
1663 	#ifdef PHYDM_LNA_SAT_CHK_TYPE1
1664 	lna_sat->chk_period = LNA_CHK_PERIOD;
1665 	lna_sat->chk_cnt = LNA_CHK_CNT;
1666 	lna_sat->chk_duty_cycle = LNA_CHK_DUTY_CYCLE;
1667 	lna_sat->dis_agc_table_swh = false;
1668 	#endif
1669 	/*@2018.04.17 Johnson end*/
1670 
1671 	if (lna_sat->lna_sat_type == LNA_SAT_WITH_PEAK_DET) {
1672 		#ifdef PHYDM_HW_SWITCH_AGC_TAB
1673 		if (dm->support_ic_type & ODM_RTL8814B) {
1674 			phydm_auto_agc_tab_init(dm);
1675 			return;
1676 		}
1677 		#endif
1678 		#ifdef PHYDM_LNA_SAT_CHK_TYPE1
1679 		phydm_lna_sat_chk_init(dm);
1680 		#endif
1681 	} else if (lna_sat->lna_sat_type == LNA_SAT_WITH_TRAIN) {
1682 		#ifdef PHYDM_LNA_SAT_CHK_TYPE2
1683 		phydm_lna_sat_chk_type2_init(dm);
1684 		#endif
1685 	}
1686 }
1687 
1688 #endif /*@#ifdef PHYDM_LNA_SAT_CHK_SUPPORT*/
1689