xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8189fs/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 &
59 	    (ODM_RTL8198F | ODM_RTL8814B))
60 		phydm_lna_sat_chk_bb_init(dm);
61 	#endif
62 }
63 
64 #if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
phydm_lna_sat_chk_bb_init(void * dm_void)65 void phydm_lna_sat_chk_bb_init(void *dm_void)
66 {
67 	struct dm_struct *dm = (struct dm_struct *)dm_void;
68 	struct phydm_lna_sat_t *lna_info = &dm->dm_lna_sat_info;
69 
70 	boolean disable_bb_switch_tab = false;
71 
72 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
73 
74 	/*@set table switch mux r_6table_sel_anten*/
75 	odm_set_bb_reg(dm, 0x18ac, BIT(8), 0);
76 
77 	/*@tab decision when idle*/
78 	odm_set_bb_reg(dm, 0x18ac, BIT(16), disable_bb_switch_tab);
79 	odm_set_bb_reg(dm, 0x41ac, BIT(16), disable_bb_switch_tab);
80 	odm_set_bb_reg(dm, 0x52ac, BIT(16), disable_bb_switch_tab);
81 	odm_set_bb_reg(dm, 0x53ac, BIT(16), disable_bb_switch_tab);
82 	/*@tab decision when ofdmcca*/
83 	odm_set_bb_reg(dm, 0x18ac, BIT(17), disable_bb_switch_tab);
84 	odm_set_bb_reg(dm, 0x41ac, BIT(17), disable_bb_switch_tab);
85 	odm_set_bb_reg(dm, 0x52ac, BIT(17), disable_bb_switch_tab);
86 	odm_set_bb_reg(dm, 0x53ac, BIT(17), disable_bb_switch_tab);
87 }
88 
phydm_set_ofdm_agc_tab_path(void * dm_void,u8 tab_sel,enum rf_path path)89 void phydm_set_ofdm_agc_tab_path(
90 	void *dm_void,
91 	u8 tab_sel,
92 	enum rf_path path)
93 {
94 	struct dm_struct *dm = (struct dm_struct *)dm_void;
95 
96 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
97 	if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B)) {
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) {
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) {
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))
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) {
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) {
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 & (ODM_RTL8198F | ODM_RTL8814B))
404 				phydm_set_ofdm_agc_tab_path(dm,
405 							    OFDM_AGC_TAB_2,
406 							    RF_PATH_A);
407 			else
408 			#endif
409 				phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_2);
410 		else
411 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
412 				  "disable set to AGC Tab%d\n", OFDM_AGC_TAB_2);
413 		lna_info->check_time = 0;
414 		lna_info->sat_cnt_acc_patha = 0;
415 		lna_info->sat_cnt_acc_pathb = 0;
416 		#ifdef PHYDM_IC_ABOVE_3SS
417 		lna_info->sat_cnt_acc_pathc = 0;
418 		#endif
419 		#ifdef PHYDM_IC_ABOVE_4SS
420 		lna_info->sat_cnt_acc_pathd = 0;
421 		#endif
422 		lna_info->pre_sat_status = lna_info->cur_sat_status;
423 
424 	} else if (lna_info->check_time <= (max_check_time - 1)) {
425 		if (lna_info->pre_sat_status && !lna_info->dis_agc_table_swh)
426 			#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
427 			if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B))
428 				phydm_set_ofdm_agc_tab_path(dm,
429 							    OFDM_AGC_TAB_2,
430 							    RF_PATH_A);
431 			else
432 			#endif
433 				phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_2);
434 
435 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "ckeck time not reached\n");
436 		if (lna_info->dis_agc_table_swh)
437 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
438 				  "disable set to AGC Tab%d\n", OFDM_AGC_TAB_2);
439 		lna_info->check_time++;
440 
441 	} else if (lna_info->check_time >= max_check_time) {
442 		if (!lna_info->dis_agc_table_swh)
443 			#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
444 			if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B))
445 				phydm_set_ofdm_agc_tab_path(dm,
446 							    OFDM_AGC_TAB_0,
447 							    RF_PATH_A);
448 			else
449 			#endif
450 				phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_0);
451 
452 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "ckeck time reached\n");
453 		if (lna_info->dis_agc_table_swh)
454 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
455 				  "disable set to AGC Tab%d\n", OFDM_AGC_TAB_0);
456 		lna_info->check_time = 0;
457 		lna_info->sat_cnt_acc_patha = 0;
458 		lna_info->sat_cnt_acc_pathb = 0;
459 		#ifdef PHYDM_IC_ABOVE_3SS
460 		lna_info->sat_cnt_acc_pathc = 0;
461 		#endif
462 		#ifdef PHYDM_IC_ABOVE_4SS
463 		lna_info->sat_cnt_acc_pathd = 0;
464 		#endif
465 		lna_info->pre_sat_status = lna_info->cur_sat_status;
466 	}
467 
468 	#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
469 	if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B))
470 		agc_tab = phydm_get_ofdm_agc_tab_path(dm, RF_PATH_A);
471 	else
472 	#endif
473 		agc_tab = phydm_get_ofdm_agc_tab(dm);
474 
475 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "use AGC tab %d\n", agc_tab);
476 
477 	/*@restore previous igi*/
478 	odm_write_dig(dm, igi_restore);
479 	lna_info->cur_timer_check_cnt++;
480 	odm_set_timer(dm, &lna_info->phydm_lna_sat_chk_timer,
481 		      lna_info->chk_period);
482 }
483 
phydm_lna_sat_chk_callback(void * dm_void)484 void phydm_lna_sat_chk_callback(
485 	void *dm_void
486 
487 	)
488 {
489 	struct dm_struct *dm = (struct dm_struct *)dm_void;
490 
491 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "\n%s ==>\n", __func__);
492 	phydm_lna_sat_chk(dm);
493 }
494 
phydm_lna_sat_chk_timers(void * dm_void,u8 state)495 void phydm_lna_sat_chk_timers(
496 	void *dm_void,
497 	u8 state)
498 {
499 	struct dm_struct *dm = (struct dm_struct *)dm_void;
500 	struct phydm_lna_sat_t *lna_info = &dm->dm_lna_sat_info;
501 
502 	if (state == INIT_LNA_SAT_CHK_TIMMER) {
503 		odm_initialize_timer(dm,
504 				     &lna_info->phydm_lna_sat_chk_timer,
505 				     (void *)phydm_lna_sat_chk_callback, NULL,
506 				     "phydm_lna_sat_chk_timer");
507 	} else if (state == CANCEL_LNA_SAT_CHK_TIMMER) {
508 		odm_cancel_timer(dm, &lna_info->phydm_lna_sat_chk_timer);
509 	} else if (state == RELEASE_LNA_SAT_CHK_TIMMER) {
510 		odm_release_timer(dm, &lna_info->phydm_lna_sat_chk_timer);
511 	}
512 }
513 
phydm_lna_sat_chk_watchdog_type1(void * dm_void)514 void phydm_lna_sat_chk_watchdog_type1(
515 	void *dm_void)
516 {
517 	struct dm_struct *dm = (struct dm_struct *)dm_void;
518 	struct phydm_lna_sat_t *lna_info = &dm->dm_lna_sat_info;
519 
520 	u8 rssi_min = dm->rssi_min;
521 
522 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "\n%s ==>\n", __func__);
523 
524 	if (!(dm->support_ability & ODM_BB_LNA_SAT_CHK)) {
525 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
526 			  "func disable\n");
527 		return;
528 	}
529 
530 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
531 		  "pre_timer_check_cnt=%d, cur_timer_check_cnt=%d\n",
532 		  lna_info->pre_timer_check_cnt,
533 		  lna_info->cur_timer_check_cnt);
534 
535 	if (lna_info->is_disable_lna_sat_chk) {
536 		phydm_lna_sat_chk_init(dm);
537 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
538 			  "is_disable_lna_sat_chk=%d, return\n",
539 			  lna_info->is_disable_lna_sat_chk);
540 		return;
541 	}
542 
543 	if (!(dm->support_ic_type &
544 	    (ODM_RTL8197F | ODM_RTL8198F | ODM_RTL8814B))) {
545 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
546 			  "support_ic_type not 97F/98F/14B, return\n");
547 		return;
548 	}
549 
550 	if (rssi_min == 0 || rssi_min == 0xff) {
551 		/*@adapt agc table 0 */
552 		phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_0);
553 		phydm_lna_sat_chk_init(dm);
554 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
555 			  "rssi_min=%d, return\n", rssi_min);
556 		return;
557 	}
558 
559 	if (lna_info->cur_timer_check_cnt == lna_info->pre_timer_check_cnt) {
560 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "fail, restart timer\n");
561 		odm_set_timer(dm, &lna_info->phydm_lna_sat_chk_timer,
562 			      lna_info->chk_period);
563 	} else {
564 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "Timer check pass\n");
565 	}
566 	lna_info->pre_timer_check_cnt = lna_info->cur_timer_check_cnt;
567 }
568 
569 #endif /*@#ifdef PHYDM_LNA_SAT_CHK_TYPE1*/
570 
571 #ifdef PHYDM_LNA_SAT_CHK_TYPE2
572 
phydm_bubble_sort(void * dm_void,u8 * array,u16 array_length)573 void phydm_bubble_sort(
574 	void *dm_void,
575 	u8 *array,
576 	u16 array_length)
577 {
578 	struct dm_struct *dm = (struct dm_struct *)dm_void;
579 	u16 i, j;
580 	u8 temp;
581 
582 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
583 	for (i = 0; i < (array_length - 1); i++) {
584 		for (j = (i + 1); j < (array_length); j++) {
585 			if (array[i] > array[j]) {
586 				temp = array[i];
587 				array[i] = array[j];
588 				array[j] = temp;
589 			}
590 		}
591 	}
592 }
593 
phydm_lna_sat_chk_type2_init(void * dm_void)594 void phydm_lna_sat_chk_type2_init(
595 	void *dm_void)
596 {
597 	struct dm_struct *dm = (struct dm_struct *)dm_void;
598 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
599 	u8 real_shift = pinfo->total_bit_shift;
600 
601 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
602 
603 	pinfo->total_cnt_snr = 1 << real_shift;
604 	pinfo->is_sm_done = TRUE;
605 	pinfo->is_snr_done = FALSE;
606 	pinfo->cur_snr_mean = 0;
607 	pinfo->cur_snr_var = 0;
608 	pinfo->cur_lower_snr_mean = 0;
609 	pinfo->pre_snr_mean = 0;
610 	pinfo->pre_snr_var = 0;
611 	pinfo->pre_lower_snr_mean = 0;
612 	pinfo->nxt_state = ORI_TABLE_MONITOR;
613 	pinfo->pre_state = ORI_TABLE_MONITOR;
614 }
615 
phydm_snr_collect(void * dm_void,u8 rx_snr)616 void phydm_snr_collect(
617 	void *dm_void,
618 	u8 rx_snr)
619 {
620 	struct dm_struct *dm = (struct dm_struct *)dm_void;
621 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
622 
623 	if (pinfo->is_sm_done) {
624 		/* @adapt only path-A for calculation */
625 		pinfo->snr_statistic[pinfo->cnt_snr_statistic] = rx_snr;
626 
627 		if (pinfo->cnt_snr_statistic == (pinfo->total_cnt_snr - 1)) {
628 			pinfo->is_snr_done = TRUE;
629 			pinfo->cnt_snr_statistic = 0;
630 		} else {
631 			pinfo->cnt_snr_statistic++;
632 		}
633 	} else {
634 		return;
635 	}
636 }
637 
phydm_parsing_snr(void * dm_void,void * pktinfo_void,s8 * rx_snr)638 void phydm_parsing_snr(void *dm_void, void *pktinfo_void, s8 *rx_snr)
639 {
640 	struct dm_struct *dm = (struct dm_struct *)dm_void;
641 	struct phydm_lna_sat_t	*lna_t = &dm->dm_lna_sat_info;
642 	struct phydm_perpkt_info_struct *pktinfo = NULL;
643 	u8 target_macid = dm->rssi_min_macid;
644 
645 	if (!(dm->support_ability & ODM_BB_LNA_SAT_CHK))
646 		return;
647 
648 	pktinfo = (struct phydm_perpkt_info_struct *)pktinfo_void;
649 
650 	if (!pktinfo->is_packet_match_bssid)
651 		return;
652 
653 	if (lna_t->force_traget_macid != 0)
654 		target_macid = lna_t->force_traget_macid;
655 
656 	if (target_macid != pktinfo->station_id)
657 		return;
658 
659 	phydm_snr_collect(dm, rx_snr[0]); /*path-A B C D???*/
660 }
661 
phydm_snr_data_processing(void * dm_void)662 void phydm_snr_data_processing(
663 	void *dm_void)
664 {
665 	struct dm_struct *dm = (struct dm_struct *)dm_void;
666 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
667 	u8 real_shift = pinfo->total_bit_shift;
668 	u16 total_snr_cnt = pinfo->total_cnt_snr;
669 	u16 total_loop_cnt = (total_snr_cnt - 1), i;
670 	u32 temp;
671 	u32 sum_snr_statistic = 0;
672 
673 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
674 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
675 		  "total_loop_cnt=%d\n", total_loop_cnt);
676 
677 	for (i = 0; (i <= total_loop_cnt); i++) {
678 		if (pinfo->is_snr_detail_en) {
679 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
680 				  "snr[%d]=%d\n", i, pinfo->snr_statistic[i]);
681 		}
682 
683 		sum_snr_statistic += (u32)(pinfo->snr_statistic[i]);
684 
685 		pinfo->snr_statistic_sqr[i] = (u16)(pinfo->snr_statistic[i] * pinfo->snr_statistic[i]);
686 	}
687 
688 	phydm_bubble_sort(dm, pinfo->snr_statistic, pinfo->total_cnt_snr);
689 
690 	/*update SNR's cur mean*/
691 	pinfo->cur_snr_mean = (sum_snr_statistic >> real_shift);
692 
693 	for (i = 0; (i <= total_loop_cnt); i++) {
694 		if (pinfo->snr_statistic[i] >= pinfo->cur_snr_mean)
695 			temp = pinfo->snr_statistic[i] - pinfo->cur_snr_mean;
696 		else
697 			temp = pinfo->cur_snr_mean - pinfo->snr_statistic[i];
698 
699 		pinfo->cur_snr_var += (temp * temp);
700 	}
701 
702 	/*update SNR's VAR*/
703 	pinfo->cur_snr_var = (pinfo->cur_snr_var >> real_shift);
704 
705 	/*@acquire lower SNR's statistics*/
706 	temp = 0;
707 	pinfo->cnt_lower_snr_statistic = (total_snr_cnt >> pinfo->lwr_snr_ratio_bit_shift);
708 	pinfo->cnt_lower_snr_statistic = MAX_2(pinfo->cnt_lower_snr_statistic, SNR_RPT_MAX);
709 
710 	for (i = 0; i < pinfo->cnt_lower_snr_statistic; i++)
711 		temp += pinfo->snr_statistic[i];
712 
713 	pinfo->cur_lower_snr_mean = temp >> (real_shift - pinfo->lwr_snr_ratio_bit_shift);
714 }
715 
phydm_is_snr_improve(void * dm_void)716 boolean phydm_is_snr_improve(
717 	void *dm_void)
718 {
719 	struct dm_struct *dm = (struct dm_struct *)dm_void;
720 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
721 	boolean is_snr_improve;
722 	u8 cur_state = pinfo->nxt_state;
723 	u32 cur_mean = pinfo->cur_snr_mean;
724 	u32 pre_mean = pinfo->pre_snr_mean;
725 	u32 cur_lower_mean = pinfo->cur_lower_snr_mean;
726 	u32 pre_lower_mean = pinfo->pre_lower_snr_mean;
727 	u32 cur_var = pinfo->cur_snr_var;
728 
729 	/*special case, zero VAR, interference is gone*/
730 	 /*@make sure pre_var is larger enough*/
731 	if (cur_state == SAT_TABLE_MONITOR ||
732 	    cur_state == ORI_TABLE_TRAINING) {
733 		if (cur_mean >= pre_mean) {
734 			if (cur_var == 0)
735 				return true;
736 		}
737 	}
738 #if 0
739 	/*special case, mean degrade less than VAR improvement*/
740 	/*@make sure pre_var is larger enough*/
741 	if (cur_state == ORI_TABLE_MONITOR &&
742 	    cur_mean < pre_mean &&
743 	    cur_var < pre_var) {
744 		diff_mean = pre_mean - cur_mean;
745 		diff_var = pre_var - cur_var;
746 		return (diff_var > (2 * diff_mean * diff_mean)) ? true : false;
747 	}
748 
749 #endif
750 	if (cur_lower_mean >= (pre_lower_mean + pinfo->delta_snr_mean))
751 		is_snr_improve = true;
752 	else
753 		is_snr_improve = false;
754 #if 0
755 /* @condition refine, mean is bigger enough or VAR is smaller enough*/
756 /* @1. from mean's view, mean improve delta_snr_mean(2), VAR not degrade lot*/
757 	if (cur_mean > (pre_mean + pinfo->delta_snr_mean)) {
758 		is_mean_improve = TRUE;
759 		is_var_improve = (cur_var <= pre_var + dm->delta_snr_var)
760 				 ? TRUE : FALSE;
761 
762 	} else if (cur_var + dm->delta_snr_var <= pre_var) {
763 		is_var_improve = TRUE;
764 		is_mean_improve = ((cur_mean + 1) >= pre_mean) ? TRUE : FALSE;
765 	} else {
766 		return false;
767 	}
768 #endif
769 	return is_snr_improve;
770 }
771 
phydm_is_snr_degrade(void * dm_void)772 boolean phydm_is_snr_degrade(
773 	void *dm_void)
774 {
775 	struct dm_struct *dm = (struct dm_struct *)dm_void;
776 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
777 	u32 cur_lower_mean = pinfo->cur_lower_snr_mean;
778 	u32 pre_lower_mean = pinfo->pre_lower_snr_mean;
779 	boolean is_degrade;
780 
781 	if (cur_lower_mean <= (pre_lower_mean - pinfo->delta_snr_mean))
782 		is_degrade = TRUE;
783 	else
784 		is_degrade = FALSE;
785 #if 0
786 	is_mean_dgrade = (pinfo->cur_snr_mean + pinfo->delta_snr_mean <= pinfo->pre_snr_mean) ? TRUE : FALSE;
787 	is_var_degrade = (pinfo->cur_snr_var > (pinfo->pre_snr_var + pinfo->delta_snr_mean)) ? TRUE : FALSE;
788 
789 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s: cur_mean=%d, pre_mean=%d, cur_var=%d, pre_var=%d\n",
790 		  __func__,
791 		  pinfo->cur_snr_mean,
792 		  pinfo->pre_snr_mean,
793 		  pinfo->cur_snr_var,
794 		  pinfo->pre_snr_var);
795 
796 	return (is_mean_dgrade & is_var_degrade);
797 #endif
798 	return is_degrade;
799 }
800 
phydm_is_large_var(void * dm_void)801 boolean phydm_is_large_var(
802 	void *dm_void)
803 {
804 	struct dm_struct *dm = (struct dm_struct *)dm_void;
805 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
806 	boolean is_large_var = (pinfo->cur_snr_var >= pinfo->snr_var_thd) ? TRUE : FALSE;
807 
808 	return is_large_var;
809 }
810 
phydm_update_pre_status(void * dm_void)811 void phydm_update_pre_status(
812 	void *dm_void)
813 {
814 	struct dm_struct *dm = (struct dm_struct *)dm_void;
815 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
816 
817 	pinfo->pre_lower_snr_mean = pinfo->cur_lower_snr_mean;
818 	pinfo->pre_snr_mean = pinfo->cur_snr_mean;
819 	pinfo->pre_snr_var = pinfo->cur_snr_var;
820 }
821 
phydm_ori_table_monitor(void * dm_void)822 void phydm_ori_table_monitor(
823 	void *dm_void)
824 {
825 	struct dm_struct *dm = (struct dm_struct *)dm_void;
826 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
827 
828 	if (phydm_is_large_var(dm)) {
829 		pinfo->nxt_state = SAT_TABLE_TRAINING;
830 		config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
831 	} else {
832 		pinfo->nxt_state = ORI_TABLE_MONITOR;
833 		/*switch to anti-sat table*/
834 		config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
835 	}
836 	phydm_update_pre_status(dm);
837 	pinfo->pre_state = ORI_TABLE_MONITOR;
838 }
839 
phydm_sat_table_training(void * dm_void)840 void phydm_sat_table_training(
841 	void *dm_void)
842 {
843 	struct dm_struct *dm = (struct dm_struct *)dm_void;
844 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
845 
846 	#if 0
847 	if pre_state = ORI_TABLE_MONITOR || SAT_TABLE_TRY_FAIL,
848 	/*@"pre" adapt ori-table, "cur" adapt sat-table*/
849 	/*@adapt ori table*/
850 	if (pinfo->pre_state == ORI_TABLE_MONITOR) {
851 		pinfo->nxt_state = SAT_TABLE_TRAINING;
852 		config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
853 	} else {
854 	#endif
855 	if (phydm_is_snr_improve(dm)) {
856 		pinfo->nxt_state = SAT_TABLE_MONITOR;
857 	} else {
858 		pinfo->nxt_state = SAT_TABLE_TRY_FAIL;
859 		config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
860 	}
861 	/*@}*/
862 
863 	phydm_update_pre_status(dm);
864 	pinfo->pre_state = SAT_TABLE_TRAINING;
865 }
866 
867 void phydm_sat_table_try_fail(
868 	void *dm_void)
869 {
870 	struct dm_struct *dm = (struct dm_struct *)dm_void;
871 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
872 
873 	/* @if pre_state = SAT_TABLE_TRAINING, "pre" adapt sat-table, "cur" adapt ori-table */
874 	/* @if pre_state = SAT_TABLE_TRY_FAIL, "pre" adapt ori-table, "cur" adapt ori-table */
875 
876 	if (phydm_is_large_var(dm)) {
877 		if (phydm_is_snr_degrade(dm)) {
878 			pinfo->nxt_state = SAT_TABLE_TRAINING;
879 			config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
880 		} else {
881 			pinfo->nxt_state = SAT_TABLE_TRY_FAIL;
882 		}
883 	} else {
884 		pinfo->nxt_state = ORI_TABLE_MONITOR;
885 	}
886 	phydm_update_pre_status(dm);
887 	pinfo->pre_state = SAT_TABLE_TRY_FAIL;
888 }
889 
890 void phydm_sat_table_monitor(
891 	void *dm_void)
892 {
893 	struct dm_struct *dm = (struct dm_struct *)dm_void;
894 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
895 
896 	if (phydm_is_snr_improve(dm)) {
897 		pinfo->sat_table_monitor_times = 0;
898 
899 		/* @if pre_state = SAT_TABLE_MONITOR, "pre" adapt sat-table, "cur" adapt sat-table */
900 		if (pinfo->pre_state == SAT_TABLE_MONITOR) {
901 			pinfo->nxt_state = ORI_TABLE_TRAINING;
902 			config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
903 			//phydm_update_pre_status(dm);
904 		} else {
905 			pinfo->nxt_state = SAT_TABLE_MONITOR;
906 		}
907 
908 		/* @if pre_state = SAT_TABLE_TRAINING, "pre" adapt sat-table, "cur" adapt sat-table */
909 		/* @if pre_state = ORI_TABLE_TRAINING, "pre" adapt ori-table, "cur" adapt sat-table */
910 		/*pre_state above is no need to update*/
911 	} else {
912 		if (pinfo->sat_table_monitor_times == pinfo->force_change_period) {
913 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s: sat_table_monitor_times=%d\n",
914 				  __func__, pinfo->sat_table_monitor_times);
915 
916 			pinfo->nxt_state = ORI_TABLE_TRAINING;
917 			pinfo->sat_table_monitor_times = 0;
918 			config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
919 		} else {
920 			pinfo->nxt_state = SAT_TABLE_MONITOR;
921 			pinfo->sat_table_monitor_times++;
922 		}
923 	}
924 	phydm_update_pre_status(dm);
925 	pinfo->pre_state = SAT_TABLE_MONITOR;
926 }
927 
928 void phydm_ori_table_training(
929 	void *dm_void)
930 {
931 	struct dm_struct *dm = (struct dm_struct *)dm_void;
932 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
933 
934 	/* pre_state = SAT_TABLE_MONITOR, "pre" adapt sat-table, "cur" adapt ori-table */
935 
936 	if (phydm_is_snr_degrade(dm) == FALSE) {
937 		pinfo->nxt_state = ORI_TABLE_MONITOR;
938 	} else {
939 		if (pinfo->pre_snr_var == 0)
940 			pinfo->nxt_state = ORI_TABLE_TRY_FAIL;
941 		else
942 			pinfo->nxt_state = SAT_TABLE_MONITOR;
943 
944 		config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
945 	}
946 	phydm_update_pre_status(dm);
947 	pinfo->pre_state = ORI_TABLE_TRAINING;
948 }
949 
950 void phydm_ori_table_try_fail(
951 	void *dm_void)
952 {
953 	struct dm_struct *dm = (struct dm_struct *)dm_void;
954 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
955 
956 	if (pinfo->pre_state == ORI_TABLE_TRY_FAIL) {
957 		if (phydm_is_snr_improve(dm)) {
958 			pinfo->nxt_state = ORI_TABLE_TRAINING;
959 			pinfo->ori_table_try_fail_times = 0;
960 			config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
961 		} else {
962 			if (pinfo->ori_table_try_fail_times == pinfo->force_change_period) {
963 				PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
964 					  "%s: ori_table_try_fail_times=%d\n", __func__, pinfo->ori_table_try_fail_times);
965 
966 				pinfo->nxt_state = ORI_TABLE_TRY_FAIL;
967 				pinfo->ori_table_try_fail_times = 0;
968 				phydm_update_pre_status(dm);
969 			} else {
970 				pinfo->nxt_state = ORI_TABLE_TRY_FAIL;
971 				pinfo->ori_table_try_fail_times++;
972 				phydm_update_pre_status(dm);
973 				//config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
974 			}
975 		}
976 	} else {
977 		pinfo->nxt_state = ORI_TABLE_TRY_FAIL;
978 		pinfo->ori_table_try_fail_times = 0;
979 		phydm_update_pre_status(dm);
980 		//config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
981 	}
982 
983 #if 0
984 	if (phydm_is_large_var(dm)) {
985 		if (phydm_is_snr_degrade(dm)) {
986 			pinfo->nxt_state = SAT_TABLE_TRAINING;
987 			config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
988 		} else {
989 			pinfo->nxt_state = SAT_TABLE_TRY_FAIL;
990 		}
991 	} else {
992 		pinfo->nxt_state = ORI_TABLE_MONITOR;
993 	}
994 
995 	phydm_update_pre_status(dm);
996 #endif
997 	pinfo->pre_state = ORI_TABLE_TRY_FAIL;
998 }
999 
1000 char *phydm_lna_sat_state_msg(
1001 	void *dm_void,
1002 	IN u8 state)
1003 {
1004 	char *dbg_message;
1005 
1006 	switch (state) {
1007 	case ORI_TABLE_MONITOR:
1008 		dbg_message = "ORI_TABLE_MONITOR";
1009 		break;
1010 
1011 	case SAT_TABLE_TRAINING:
1012 		dbg_message = "SAT_TABLE_TRAINING";
1013 		break;
1014 
1015 	case SAT_TABLE_TRY_FAIL:
1016 		dbg_message = "SAT_TABLE_TRY_FAIL";
1017 		break;
1018 
1019 	case SAT_TABLE_MONITOR:
1020 		dbg_message = "SAT_TABLE_MONITOR";
1021 		break;
1022 
1023 	case ORI_TABLE_TRAINING:
1024 		dbg_message = "ORI_TABLE_TRAINING";
1025 		break;
1026 
1027 	case ORI_TABLE_TRY_FAIL:
1028 		dbg_message = "ORI_TABLE_TRY_FAIL";
1029 		break;
1030 
1031 	default:
1032 		dbg_message = "ORI_TABLE_MONITOR";
1033 		break;
1034 	}
1035 
1036 	return dbg_message;
1037 }
1038 
1039 void phydm_lna_sat_type2_sm(
1040 	void *dm_void)
1041 {
1042 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1043 	struct phydm_lna_sat_t	*pinfo = &dm->dm_lna_sat_info;
1044 	u8 state = pinfo->nxt_state;
1045 	u8 agc_tab = (u8)odm_get_bb_reg(dm, 0x958, 0x1f);
1046 	char *dbg_message, *nxt_dbg_message;
1047 	u8 real_shift = pinfo->total_bit_shift;
1048 
1049 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "\n\n%s ==>\n", __func__);
1050 
1051 	if ((dm->support_ic_type & ODM_RTL8822B) == FALSE) {
1052 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "ODM_BB_LNA_SAT_CHK_TYPE2 only support 22B.\n");
1053 		return;
1054 	}
1055 
1056 	if ((dm->support_ability & ODM_BB_LNA_SAT_CHK) == FALSE) {
1057 		phydm_lna_sat_chk_type2_init(dm);
1058 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "ODM_BB_LNA_SAT_CHK_TYPE2 is NOT supported, cur table=%d\n", agc_tab);
1059 		return;
1060 	}
1061 
1062 	if (pinfo->is_snr_done)
1063 		phydm_snr_data_processing(dm);
1064 	else
1065 		return;
1066 
1067 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "cur agc table %d\n", agc_tab);
1068 
1069 	if (pinfo->is_force_lna_sat_table != AUTO_AGC_TABLE) {
1070 		/*reset state machine*/
1071 		pinfo->nxt_state = ORI_TABLE_MONITOR;
1072 		if (pinfo->is_snr_done) {
1073 			if (pinfo->is_force_lna_sat_table == DEFAULT_AGC_TABLE)
1074 				config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
1075 			else if (pinfo->is_force_lna_sat_table == LNA_SAT_AGC_TABLE)
1076 				config_phydm_switch_agc_tab_8822b(dm, *dm->channel, LNA_SAT_AGC_TABLE);
1077 			else
1078 				config_phydm_switch_agc_tab_8822b(dm, *dm->channel, DEFAULT_AGC_TABLE);
1079 
1080 			PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
1081 				  "%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",
1082 				  __func__,
1083 				  pinfo->cur_snr_mean,
1084 				  pinfo->pre_snr_mean,
1085 				  pinfo->cur_snr_var,
1086 				  pinfo->pre_snr_var,
1087 				  pinfo->cur_lower_snr_mean,
1088 				  pinfo->pre_lower_snr_mean,
1089 				  pinfo->cnt_lower_snr_statistic);
1090 
1091 			pinfo->is_snr_done = FALSE;
1092 			pinfo->is_sm_done = TRUE;
1093 			phydm_update_pre_status(dm);
1094 		} else {
1095 			return;
1096 		}
1097 	} else if (pinfo->is_snr_done) {
1098 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK,
1099 			  "%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",
1100 			  __func__,
1101 			  pinfo->cur_snr_mean,
1102 			  pinfo->pre_snr_mean,
1103 			  pinfo->cur_snr_var,
1104 			  pinfo->pre_snr_var,
1105 			  pinfo->cur_lower_snr_mean,
1106 			  pinfo->pre_lower_snr_mean,
1107 			  pinfo->cnt_lower_snr_statistic);
1108 
1109 		switch (state) {
1110 		case ORI_TABLE_MONITOR:
1111 			dbg_message = "ORI_TABLE_MONITOR";
1112 			phydm_ori_table_monitor(dm);
1113 			break;
1114 
1115 		case SAT_TABLE_TRAINING:
1116 			dbg_message = "SAT_TABLE_TRAINING";
1117 			phydm_sat_table_training(dm);
1118 			break;
1119 
1120 		case SAT_TABLE_TRY_FAIL:
1121 			dbg_message = "SAT_TABLE_TRY_FAIL";
1122 			phydm_sat_table_try_fail(dm);
1123 			break;
1124 
1125 		case SAT_TABLE_MONITOR:
1126 			dbg_message = "SAT_TABLE_MONITOR";
1127 			phydm_sat_table_monitor(dm);
1128 			break;
1129 
1130 		case ORI_TABLE_TRAINING:
1131 			dbg_message = "ORI_TABLE_TRAINING";
1132 			phydm_ori_table_training(dm);
1133 			break;
1134 
1135 		case ORI_TABLE_TRY_FAIL:
1136 			dbg_message = "ORI_TABLE_TRAINING";
1137 			phydm_ori_table_try_fail(dm);
1138 			break;
1139 
1140 		default:
1141 			dbg_message = "ORI_TABLE_MONITOR";
1142 			phydm_ori_table_monitor(dm);
1143 			break;
1144 		}
1145 
1146 		dbg_message = phydm_lna_sat_state_msg(dm, state);
1147 		nxt_dbg_message = phydm_lna_sat_state_msg(dm, pinfo->nxt_state);
1148 		PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "state: [%s]->[%s]\n",
1149 			  dbg_message, nxt_dbg_message);
1150 
1151 		pinfo->is_snr_done = FALSE;
1152 		pinfo->is_sm_done = TRUE;
1153 		pinfo->total_cnt_snr = 1 << real_shift;
1154 
1155 	} else {
1156 		return;
1157 	}
1158 }
1159 
1160 
1161 #endif /*@#ifdef PHYDM_LNA_SAT_CHK_TYPE2*/
1162 
1163 void phydm_lna_sat_debug(
1164 	void *dm_void,
1165 	char input[][16],
1166 	u32 *_used,
1167 	char *output,
1168 	u32 *_out_len)
1169 {
1170 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1171 	struct phydm_lna_sat_t	*lna_t = &dm->dm_lna_sat_info;
1172 	char help[] = "-h";
1173 	char monitor[] = "-m";
1174 	u32 var1[10] = {0};
1175 	u32 used = *_used;
1176 	u32 out_len = *_out_len;
1177 	u8 i;
1178 	u8 agc_tab = 0;
1179 
1180 	if ((strcmp(input[1], help) == 0)) {
1181 		PDM_SNPF(out_len, used, output + used, out_len - used,
1182 			 "monitor: -m\n");
1183 		#ifdef PHYDM_LNA_SAT_CHK_TYPE1
1184 		PDM_SNPF(out_len, used, output + used, out_len - used,
1185 			 "{0} {lna_sat_chk_en}\n");
1186 		PDM_SNPF(out_len, used, output + used, out_len - used,
1187 			 "{1} {agc_table_switch_en}\n");
1188 		PDM_SNPF(out_len, used, output + used, out_len - used,
1189 			 "{2} {chk_cnt per callback}\n");
1190 		PDM_SNPF(out_len, used, output + used, out_len - used,
1191 			 "{3} {chk_period(ms)}\n");
1192 		PDM_SNPF(out_len, used, output + used, out_len - used,
1193 			 "{4} {chk_duty_cycle(%)}\n");
1194 		#endif
1195 	} else if ((strcmp(input[1], monitor) == 0)) {
1196 #ifdef PHYDM_LNA_SAT_CHK_TYPE1
1197 		#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT)
1198 		if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B))
1199 			agc_tab = phydm_get_ofdm_agc_tab_path(dm, RF_PATH_A);
1200 		else
1201 		#endif
1202 			agc_tab = phydm_get_ofdm_agc_tab(dm);
1203 
1204 		PDM_SNPF(out_len, used, output + used, out_len - used,
1205 			 "%s%d, %s%d, %s%d, %s%d\n",
1206 			 "check_time = ", lna_t->check_time,
1207 			 "pre_sat_status = ", lna_t->pre_sat_status,
1208 			 "cur_sat_status = ", lna_t->cur_sat_status,
1209 			 "current AGC tab = ", agc_tab);
1210 #endif
1211 	} else {
1212 		PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
1213 
1214 		for (i = 1; i < 10; i++) {
1215 			if (input[i + 1])
1216 				PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
1217 					     &var1[i]);
1218 		}
1219 		#ifdef PHYDM_LNA_SAT_CHK_TYPE1
1220 		if (var1[0] == 0) {
1221 			if (var1[1] == 1)
1222 				lna_t->is_disable_lna_sat_chk = false;
1223 			else if (var1[1] == 0)
1224 				lna_t->is_disable_lna_sat_chk = true;
1225 
1226 			PDM_SNPF(out_len, used, output + used, out_len - used,
1227 				 "dis_lna_sat_chk=%d\n",
1228 				 lna_t->is_disable_lna_sat_chk);
1229 		} else if (var1[0] == 1) {
1230 			if (var1[1] == 1)
1231 				lna_t->dis_agc_table_swh = false;
1232 			else if (var1[1] == 0)
1233 				lna_t->dis_agc_table_swh = true;
1234 
1235 			PDM_SNPF(out_len, used, output + used, out_len - used,
1236 				 "dis_agc_table_swh=%d\n",
1237 				 lna_t->dis_agc_table_swh);
1238 
1239 		} else if (var1[0] == 2) {
1240 			lna_t->chk_cnt = (u8)var1[1];
1241 			PDM_SNPF(out_len, used, output + used, out_len - used,
1242 				 "chk_cnt=%d\n", lna_t->chk_cnt);
1243 		} else if (var1[0] == 3) {
1244 			lna_t->chk_period = var1[1];
1245 			PDM_SNPF(out_len, used, output + used, out_len - used,
1246 				 "chk_period=%d\n", lna_t->chk_period);
1247 		} else if (var1[0] == 4) {
1248 			lna_t->chk_duty_cycle = (u8)var1[1];
1249 			PDM_SNPF(out_len, used, output + used, out_len - used,
1250 				 "chk_duty_cycle=%d\n",
1251 				 lna_t->chk_duty_cycle);
1252 		}
1253 		#endif
1254 		#ifdef PHYDM_LNA_SAT_CHK_TYPE2
1255 		if (var1[0] == 1)
1256 			lna_t->force_traget_macid = var1[1];
1257 		#endif
1258 	}
1259 	*_used = used;
1260 	*_out_len = out_len;
1261 }
1262 
1263 void phydm_lna_sat_chk_watchdog(
1264 	void *dm_void)
1265 {
1266 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1267 	struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info;
1268 
1269 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__);
1270 
1271 	if (lna_sat->lna_sat_type == LNA_SAT_WITH_PEAK_DET) {
1272 		#ifdef PHYDM_LNA_SAT_CHK_TYPE1
1273 		phydm_lna_sat_chk_watchdog_type1(dm);
1274 		#endif
1275 	} else if (lna_sat->lna_sat_type == LNA_SAT_WITH_TRAIN) {
1276 		#ifdef PHYDM_LNA_SAT_CHK_TYPE2
1277 
1278 		#endif
1279 	}
1280 
1281 }
1282 
1283 void phydm_lna_sat_config(
1284 	void *dm_void)
1285 {
1286 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1287 	struct phydm_lna_sat_t	*lna_sat = &dm->dm_lna_sat_info;
1288 
1289 	#if (RTL8822B_SUPPORT == 1)
1290 	if (dm->support_ic_type & (ODM_RTL8822B))
1291 		lna_sat->lna_sat_type = LNA_SAT_WITH_TRAIN;
1292 	#endif
1293 
1294 	#if (RTL8197F_SUPPORT || RTL8192F_SUPPORT ||\
1295 	     RTL8198F_SUPPORT || RTL8814B_SUPPORT)
1296 	if (dm->support_ic_type &
1297 	    (ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8198F | ODM_RTL8814B))
1298 		lna_sat->lna_sat_type = LNA_SAT_WITH_PEAK_DET;
1299 	#endif
1300 
1301 	PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "[%s] lna_sat_type=%d\n",
1302 		  __func__, lna_sat->lna_sat_type);
1303 }
1304 
1305 void phydm_lna_sat_check_init(
1306 	void *dm_void)
1307 {
1308 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1309 	struct phydm_lna_sat_t	*lna_sat = &dm->dm_lna_sat_info;
1310 
1311 	if ((dm->support_ability & ODM_BB_LNA_SAT_CHK))
1312 		return;
1313 
1314 	/*@2018.04.17 Johnson*/
1315 	phydm_lna_sat_config(dm);
1316 	#ifdef PHYDM_LNA_SAT_CHK_TYPE1
1317 	lna_sat->chk_period = LNA_CHK_PERIOD;
1318 	lna_sat->chk_cnt = LNA_CHK_CNT;
1319 	lna_sat->chk_duty_cycle = LNA_CHK_DUTY_CYCLE;
1320 	lna_sat->dis_agc_table_swh = false;
1321 	#endif
1322 	/*@2018.04.17 Johnson end*/
1323 
1324 	if (lna_sat->lna_sat_type == LNA_SAT_WITH_PEAK_DET) {
1325 		#ifdef PHYDM_LNA_SAT_CHK_TYPE1
1326 		phydm_lna_sat_chk_init(dm);
1327 		#endif
1328 	} else if (lna_sat->lna_sat_type == LNA_SAT_WITH_TRAIN) {
1329 		#ifdef PHYDM_LNA_SAT_CHK_TYPE2
1330 		phydm_lna_sat_chk_type2_init(dm);
1331 		#endif
1332 	}
1333 }
1334 
1335 #endif /*@#ifdef PHYDM_LNA_SAT_CHK_SUPPORT*/
1336