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