• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "mp_precomp.h"
27 #include "phydm_precomp.h"
28 
phydm_env_mntr_get_802_11_k_rsni(void * dm_void,s8 rcpi,s8 anpi)29 u8 phydm_env_mntr_get_802_11_k_rsni(void *dm_void, s8 rcpi, s8 anpi)
30 {
31 	u8 rsni = 0;
32 	u8 signal = 0;
33 	u8 sig_to_rsni[13] = {0, 8, 15, 20, 24, 27, 30, 32, 35, 37, 39, 41, 43};
34 
35 	/*rcpi = signal + noise + interference = rssi*/
36 	/*anpi = noise + interferecne = nhm*/
37 	/*signal = rcpi - anpi*/
38 
39 	/*rsni = 2*(10*log10((rcpi_lin/anpi_lin)-1)+10), unit = 0.5dB*/
40 	/*rcpi_lin/anpi_lin=10^((rcpi_dB-anpi_db)/10)*/
41 	/*rsni is approximated as 2*((rcpi_db-anpi_db)+10) when signal >= 13*/
42 
43 	if (rcpi <= anpi)
44 		signal = 0;
45 	else if (rcpi - anpi >= 117)
46 		signal = 117;
47 	else
48 		signal = rcpi - anpi;
49 
50 	if (signal < 13)
51 		rsni = sig_to_rsni[signal];
52 	else
53 		rsni = 2 * (signal + 10);
54 
55 	return rsni;
56 }
57 
phydm_ccx_hw_restart(void * dm_void)58 void phydm_ccx_hw_restart(void *dm_void)
59 			  /*@Will Restart NHM/CLM/FAHM simultaneously*/
60 {
61 	struct dm_struct *dm = (struct dm_struct *)dm_void;
62 	u32 reg1 = 0;
63 
64 	if (dm->support_ic_type & ODM_IC_11AC_SERIES)
65 		reg1 = R_0x994;
66 	#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
67 	else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)
68 		reg1 = R_0x1e60;
69 	#endif
70 	else
71 		reg1 = R_0x890;
72 
73 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
74 	/*@disable NHM,CLM, FAHM*/
75 	odm_set_bb_reg(dm, reg1, 0x7, 0x0);
76 	odm_set_bb_reg(dm, reg1, BIT(8), 0x0);
77 	odm_set_bb_reg(dm, reg1, BIT(8), 0x1);
78 }
79 
phydm_ccx_get_rpt_ratio(void * dm_void,u16 rpt,u16 denom)80 u8 phydm_ccx_get_rpt_ratio(void *dm_void, u16 rpt, u16 denom)
81 {
82 	u32 numer = 0;
83 
84 	numer = rpt * 100 + (denom >> 1);
85 
86 	return (u8)PHYDM_DIV(numer, denom);
87 }
88 
89 #ifdef NHM_SUPPORT
90 
phydm_nhm_racing_release(void * dm_void)91 void phydm_nhm_racing_release(void *dm_void)
92 {
93 	struct dm_struct *dm = (struct dm_struct *)dm_void;
94 	struct ccx_info *ccx = &dm->dm_ccx_info;
95 	u32 value32 = 0;
96 
97 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
98 	PHYDM_DBG(dm, DBG_ENV_MNTR, "lv:(%d)->(0)\n", ccx->nhm_set_lv);
99 
100 	ccx->nhm_ongoing = false;
101 	ccx->nhm_set_lv = NHM_RELEASE;
102 
103 	if (!(ccx->nhm_app == NHM_BACKGROUND || ccx->nhm_app == NHM_ACS)) {
104 		phydm_pause_func(dm, F00_DIG, PHYDM_RESUME,
105 				 PHYDM_PAUSE_LEVEL_1, 1, &value32);
106 	}
107 
108 	ccx->nhm_app = NHM_BACKGROUND;
109 }
110 
phydm_nhm_racing_ctrl(void * dm_void,enum phydm_nhm_level nhm_lv)111 u8 phydm_nhm_racing_ctrl(void *dm_void, enum phydm_nhm_level nhm_lv)
112 {
113 	struct dm_struct *dm = (struct dm_struct *)dm_void;
114 	struct ccx_info *ccx = &dm->dm_ccx_info;
115 	u8 set_result = PHYDM_SET_SUCCESS;
116 	/*@acquire to control NHM API*/
117 
118 	PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_ongoing=%d, lv:(%d)->(%d)\n",
119 		  ccx->nhm_ongoing, ccx->nhm_set_lv, nhm_lv);
120 	if (ccx->nhm_ongoing) {
121 		if (nhm_lv <= ccx->nhm_set_lv) {
122 			set_result = PHYDM_SET_FAIL;
123 		} else {
124 			phydm_ccx_hw_restart(dm);
125 			ccx->nhm_ongoing = false;
126 		}
127 	}
128 
129 	if (set_result)
130 		ccx->nhm_set_lv = nhm_lv;
131 
132 	PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm racing success=%d\n", set_result);
133 	return set_result;
134 }
135 
phydm_nhm_trigger(void * dm_void)136 void phydm_nhm_trigger(void *dm_void)
137 {
138 	struct dm_struct *dm = (struct dm_struct *)dm_void;
139 	struct ccx_info *ccx = &dm->dm_ccx_info;
140 	u32 nhm_reg1 = 0;
141 
142 	if (dm->support_ic_type & ODM_IC_11AC_SERIES)
143 		nhm_reg1 = R_0x994;
144 	#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
145 	else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)
146 		nhm_reg1 = R_0x1e60;
147 	#endif
148 	else
149 		nhm_reg1 = R_0x890;
150 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
151 
152 	/* @Trigger NHM*/
153 	pdm_set_reg(dm, nhm_reg1, BIT(1), 0);
154 	pdm_set_reg(dm, nhm_reg1, BIT(1), 1);
155 	ccx->nhm_trigger_time = dm->phydm_sys_up_time;
156 	ccx->nhm_rpt_stamp++;
157 	ccx->nhm_ongoing = true;
158 }
159 
160 boolean
phydm_nhm_check_rdy(void * dm_void)161 phydm_nhm_check_rdy(void *dm_void)
162 {
163 	struct dm_struct *dm = (struct dm_struct *)dm_void;
164 	boolean is_ready = false;
165 	u32 reg1 = 0, reg1_bit = 0;
166 
167 	if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
168 		reg1 = R_0xfb4;
169 		reg1_bit = 16;
170 	#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
171 	} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {
172 		reg1 = R_0x2d4c;
173 		reg1_bit = 16;
174 	#endif
175 	} else {
176 		reg1 = R_0x8b4;
177 		if (dm->support_ic_type & (ODM_RTL8710B | ODM_RTL8721D |
178 					ODM_RTL8710C))
179 			reg1_bit = 25;
180 		else
181 			reg1_bit = 17;
182 	}
183 	if (odm_get_bb_reg(dm, reg1, BIT(reg1_bit)))
184 		is_ready = true;
185 
186 	PHYDM_DBG(dm, DBG_ENV_MNTR, "NHM rdy=%d\n", is_ready);
187 
188 	return is_ready;
189 }
190 
phydm_nhm_cal_wgt(void * dm_void)191 void phydm_nhm_cal_wgt(void *dm_void)
192 {
193 	struct dm_struct *dm = (struct dm_struct *)dm_void;
194 	struct ccx_info *ccx = &dm->dm_ccx_info;
195 	u8 i = 0;
196 
197 	for (i = 0; i < NHM_RPT_NUM; i++) {
198 		if (i == 0)
199 			ccx->nhm_wgt[0] = (u8)(MAX_2(ccx->nhm_th[0] - 2, 0));
200 		else if (i == (NHM_RPT_NUM - 1))
201 			ccx->nhm_wgt[NHM_RPT_NUM - 1] = (u8)(ccx->nhm_th[NHM_TH_NUM - 1] + 2);
202 		else
203 			ccx->nhm_wgt[i] = (u8)((ccx->nhm_th[i - 1] + ccx->nhm_th[i]) >> 1);
204 	}
205 }
206 
phydm_nhm_cal_wgt_avg(void * dm_void,u8 start_i,u8 end_i,u8 n_sum)207 u8 phydm_nhm_cal_wgt_avg(void *dm_void, u8 start_i, u8 end_i, u8 n_sum)
208 {
209 	struct dm_struct *dm = (struct dm_struct *)dm_void;
210 	struct ccx_info *ccx = &dm->dm_ccx_info;
211 	u8 i = 0;
212 	u32 noise_tmp = 0;
213 	u8 noise = 0;
214 	u32 nhm_valid = 0;
215 
216 	if (n_sum == 0) {
217 		PHYDM_DBG(dm, DBG_ENV_MNTR,
218 			  "n_sum = 0, don't need to update noise\n");
219 		return 0x0;
220 	} else if (end_i > NHM_RPT_NUM - 1) {
221 		PHYDM_DBG(dm, DBG_ENV_MNTR,
222 			  "[WARNING]end_i is larger than 11!!\n");
223 		return 0x0;
224 	}
225 
226 	for (i = start_i; i <= end_i; i++)
227 		noise_tmp += ccx->nhm_result[i] * ccx->nhm_wgt[i];
228 
229 	/* protection for the case of minus noise(RSSI)*/
230 	noise = (u8)(NTH_TH_2_RSSI(MAX_2(PHYDM_DIV(noise_tmp, n_sum), 20)));
231 	nhm_valid = (n_sum * 100) >> 8;
232 	PHYDM_DBG(dm, DBG_ENV_MNTR,
233 		  "cal wgt_avg : valid: ((%d)) percent, noise(RSSI)=((%d))\n",
234 		  nhm_valid, noise);
235 
236 	return noise;
237 }
238 
phydm_nhm_cal_nhm_env(void * dm_void)239 u8 phydm_nhm_cal_nhm_env(void *dm_void)
240 {
241 	struct dm_struct *dm = (struct dm_struct *)dm_void;
242 	struct ccx_info *ccx = &dm->dm_ccx_info;
243 	u8 first_idx = 0;
244 	u8 nhm_env = 0;
245 	u8 i = 0;
246 
247 	nhm_env = ccx->nhm_rpt_sum;
248 
249 	/*search first cluster*/
250 	for (i = 0; i < NHM_RPT_NUM; i++) {
251 		if (ccx->nhm_result[i]) {
252 			first_idx = i;
253 			break;
254 		}
255 	}
256 
257 	/*exclude first cluster under -80dBm*/
258 	for (i = 0; i < 4; i++) {
259 		if (((first_idx + i) < NHM_RPT_NUM) &&
260 		    (ccx->nhm_wgt[first_idx + i] <= NHM_IC_NOISE_TH))
261 			nhm_env -= ccx->nhm_result[first_idx + i];
262 	}
263 
264 	/*exclude nhm_rpt[0] above -80dBm*/
265 	if (ccx->nhm_wgt[0] > NHM_IC_NOISE_TH)
266 		nhm_env -= ccx->nhm_result[0];
267 
268 	PHYDM_DBG(dm, DBG_ENV_MNTR, "cal nhm_env: first_idx=%d, nhm_env=%d\n",
269 		  first_idx, nhm_env);
270 
271 	return nhm_env;
272 }
273 
phydm_nhm_get_utility(void * dm_void)274 void phydm_nhm_get_utility(void *dm_void)
275 {
276 	struct dm_struct *dm = (struct dm_struct *)dm_void;
277 	struct ccx_info *ccx = &dm->dm_ccx_info;
278 	u8 nhm_rpt_non_0 = 0;
279 	u8 nhm_rpt_non_11 = 0;
280 	u8 nhm_env = 0;
281 
282 	if (ccx->nhm_rpt_sum >= ccx->nhm_result[0]) {
283 		phydm_nhm_cal_wgt(dm);
284 
285 		nhm_rpt_non_0 = ccx->nhm_rpt_sum - ccx->nhm_result[0];
286 		nhm_rpt_non_11 = ccx->nhm_rpt_sum - ccx->nhm_result[11];
287 		/*exclude nhm_r[0] above -80dBm or first cluster under -80dBm*/
288 		nhm_env = phydm_nhm_cal_nhm_env(dm);
289 		ccx->nhm_ratio = phydm_ccx_get_rpt_ratio(dm, nhm_rpt_non_0,
290 				 NHM_RPT_MAX);
291 		ccx->nhm_env_ratio = phydm_ccx_get_rpt_ratio(dm, nhm_env,
292 				     NHM_RPT_MAX);
293 		ccx->nhm_level_valid = phydm_ccx_get_rpt_ratio(dm,
294 				       nhm_rpt_non_11, NHM_RPT_MAX);
295 		ccx->nhm_level = phydm_nhm_cal_wgt_avg(dm, 0, NHM_RPT_NUM - 2,
296 						     nhm_rpt_non_11);
297 		ccx->nhm_pwr = phydm_nhm_cal_wgt_avg(dm, 0, NHM_RPT_NUM - 1,
298 						     ccx->nhm_rpt_sum);
299 	} else {
300 		PHYDM_DBG(dm, DBG_ENV_MNTR, "[warning] nhm_rpt_sum invalid\n");
301 		ccx->nhm_ratio = 0;
302 		ccx->nhm_env_ratio = 0;
303 	}
304 
305 	PHYDM_DBG(dm, DBG_ENV_MNTR,
306 		  "nhm_ratio=%d, nhm_env_ratio=%d, nhm_level=%d, nhm_pwr=%d\n",
307 		  ccx->nhm_ratio, ccx->nhm_env_ratio, ccx->nhm_level,
308 		  ccx->nhm_pwr);
309 }
310 
311 boolean
phydm_nhm_get_result(void * dm_void)312 phydm_nhm_get_result(void *dm_void)
313 {
314 	struct dm_struct *dm = (struct dm_struct *)dm_void;
315 	struct ccx_info *ccx = &dm->dm_ccx_info;
316 	u32 value32 = 0;
317 	u8 i = 0;
318 	u32 nhm_reg1 = 0;
319 	u16 nhm_rpt_sum_tmp = 0;
320 	u16 nhm_duration = 0;
321 
322 	if (dm->support_ic_type & ODM_IC_11AC_SERIES)
323 		nhm_reg1 = R_0x994;
324 	#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
325 	else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)
326 		nhm_reg1 = R_0x1e60;
327 	#endif
328 	else
329 		nhm_reg1 = R_0x890;
330 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
331 
332 	if ((dm->support_ic_type & ODM_IC_11N_SERIES) ||
333 	    (dm->support_ic_type & ODM_IC_11AC_SERIES) ||
334 	    (dm->support_ic_type & ODM_RTL8198F) ||
335 	    (dm->support_ic_type & ODM_RTL8814B))
336 		pdm_set_reg(dm, nhm_reg1, BIT(1), 0);
337 
338 	if (!(phydm_nhm_check_rdy(dm))) {
339 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM report Fail\n");
340 		phydm_nhm_racing_release(dm);
341 		return false;
342 	}
343 
344 	if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
345 		value32 = odm_read_4byte(dm, R_0xfa8);
346 		value32 = odm_convert_to_le32(value32);
347 		odm_move_memory(dm, &ccx->nhm_result[0], &value32, 4);
348 
349 		value32 = odm_read_4byte(dm, R_0xfac);
350 		value32 = odm_convert_to_le32(value32);
351 		odm_move_memory(dm, &ccx->nhm_result[4], &value32, 4);
352 
353 		value32 = odm_read_4byte(dm, R_0xfb0);
354 		value32 = odm_convert_to_le32(value32);
355 		odm_move_memory(dm, &ccx->nhm_result[8], &value32, 4);
356 
357 		/*@Get NHM duration*/
358 		value32 = odm_read_4byte(dm, R_0xfb4);
359 		nhm_duration = (u16)(value32 & MASKLWORD);
360 	#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
361 	} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {
362 		value32 = odm_read_4byte(dm, R_0x2d40);
363 		value32 = odm_convert_to_le32(value32);
364 		odm_move_memory(dm, &ccx->nhm_result[0], &value32, 4);
365 
366 		value32 = odm_read_4byte(dm, R_0x2d44);
367 		value32 = odm_convert_to_le32(value32);
368 		odm_move_memory(dm, &ccx->nhm_result[4], &value32, 4);
369 
370 		value32 = odm_read_4byte(dm, R_0x2d48);
371 		value32 = odm_convert_to_le32(value32);
372 		odm_move_memory(dm, &ccx->nhm_result[8], &value32, 4);
373 
374 		/*@Get NHM duration*/
375 		value32 = odm_read_4byte(dm, R_0x2d4c);
376 		nhm_duration = (u16)(value32 & MASKLWORD);
377 	#endif
378 	} else {
379 		value32 = odm_read_4byte(dm, R_0x8d8);
380 		value32 = odm_convert_to_le32(value32);
381 		odm_move_memory(dm, &ccx->nhm_result[0], &value32, 4);
382 
383 		value32 = odm_read_4byte(dm, R_0x8dc);
384 		value32 = odm_convert_to_le32(value32);
385 		odm_move_memory(dm, &ccx->nhm_result[4], &value32, 4);
386 
387 		value32 = odm_read_4byte(dm, R_0x8d0);
388 
389 		ccx->nhm_result[8] = (u8)((value32 & MASKBYTE2) >> 16);
390 		ccx->nhm_result[9] = (u8)((value32 & MASKBYTE3) >> 24);
391 
392 		value32 = odm_read_4byte(dm, R_0x8d4);
393 
394 		ccx->nhm_result[10] = (u8)((value32 & MASKBYTE2) >> 16);
395 		ccx->nhm_result[11] = (u8)((value32 & MASKBYTE3) >> 24);
396 
397 		/*@Get NHM duration*/
398 		nhm_duration = (u16)(value32 & MASKLWORD);
399 	}
400 	ccx->nhm_duration = nhm_duration;
401 
402 	/* sum all nhm_result */
403 	if (ccx->nhm_period >= 65530)
404 		PHYDM_DBG(dm, DBG_ENV_MNTR,
405 			  "NHM valid time = %d, valid: %d percent\n",
406 			  nhm_duration, (nhm_duration * 100) >> 16);
407 
408 	for (i = 0; i < NHM_RPT_NUM; i++)
409 		nhm_rpt_sum_tmp = (u16)(nhm_rpt_sum_tmp + ccx->nhm_result[i]);
410 
411 	ccx->nhm_rpt_sum = (u8)nhm_rpt_sum_tmp;
412 
413 	PHYDM_DBG(dm, DBG_ENV_MNTR,
414 		  "NHM_Rpt[%d](H->L)[%d %d %d %d %d %d %d %d %d %d %d %d]\n",
415 		  ccx->nhm_rpt_stamp, ccx->nhm_result[11], ccx->nhm_result[10],
416 		  ccx->nhm_result[9], ccx->nhm_result[8], ccx->nhm_result[7],
417 		  ccx->nhm_result[6], ccx->nhm_result[5], ccx->nhm_result[4],
418 		  ccx->nhm_result[3], ccx->nhm_result[2], ccx->nhm_result[1],
419 		  ccx->nhm_result[0]);
420 
421 	phydm_nhm_racing_release(dm);
422 
423 	if (nhm_rpt_sum_tmp > 255) {
424 		PHYDM_DBG(dm, DBG_ENV_MNTR,
425 			  "[Warning] Invalid NHM RPT, total=%d\n",
426 			  nhm_rpt_sum_tmp);
427 		return false;
428 	}
429 
430 	return true;
431 }
432 
phydm_nhm_set_th_reg(void * dm_void)433 void phydm_nhm_set_th_reg(void *dm_void)
434 {
435 	struct dm_struct *dm = (struct dm_struct *)dm_void;
436 	struct ccx_info *ccx = &dm->dm_ccx_info;
437 	u32 reg1 = 0, reg2 = 0, reg3 = 0, reg4 = 0, reg4_bit = 0;
438 	u32 val = 0;
439 
440 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
441 
442 	if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
443 		reg1 = R_0x994;
444 		reg2 = R_0x998;
445 		reg3 = R_0x99c;
446 		reg4 = R_0x9a0;
447 		reg4_bit = MASKBYTE0;
448 	#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
449 	} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {
450 		reg1 = R_0x1e60;
451 		reg2 = R_0x1e44;
452 		reg3 = R_0x1e48;
453 		reg4 = R_0x1e5c;
454 		reg4_bit = MASKBYTE2;
455 	#endif
456 	} else {
457 		reg1 = R_0x890;
458 		reg2 = R_0x898;
459 		reg3 = R_0x89c;
460 		reg4 = R_0xe28;
461 		reg4_bit = MASKBYTE0;
462 	}
463 
464 	/*Set NHM threshold*/ /*Unit: PWdB U(8,1)*/
465 	val = BYTE_2_DWORD(ccx->nhm_th[3], ccx->nhm_th[2],
466 			   ccx->nhm_th[1], ccx->nhm_th[0]);
467 	pdm_set_reg(dm, reg2, MASKDWORD, val);
468 	val = BYTE_2_DWORD(ccx->nhm_th[7], ccx->nhm_th[6],
469 			   ccx->nhm_th[5], ccx->nhm_th[4]);
470 	pdm_set_reg(dm, reg3, MASKDWORD, val);
471 	pdm_set_reg(dm, reg4, reg4_bit, ccx->nhm_th[8]);
472 	val = BYTE_2_DWORD(0, 0, ccx->nhm_th[10], ccx->nhm_th[9]);
473 	pdm_set_reg(dm, reg1, 0xffff0000, val);
474 
475 	PHYDM_DBG(dm, DBG_ENV_MNTR,
476 		  "Update NHM_th[H->L]=[%d %d %d %d %d %d %d %d %d %d %d]\n",
477 		  ccx->nhm_th[10], ccx->nhm_th[9], ccx->nhm_th[8],
478 		  ccx->nhm_th[7], ccx->nhm_th[6], ccx->nhm_th[5],
479 		  ccx->nhm_th[4], ccx->nhm_th[3], ccx->nhm_th[2],
480 		  ccx->nhm_th[1], ccx->nhm_th[0]);
481 }
482 
483 boolean
phydm_nhm_th_update_chk(void * dm_void,enum nhm_application nhm_app,u8 * nhm_th,u32 * igi_new,boolean en_1db_mode,u8 nhm_th0_manual)484 phydm_nhm_th_update_chk(void *dm_void, enum nhm_application nhm_app, u8 *nhm_th,
485 			u32 *igi_new, boolean en_1db_mode, u8 nhm_th0_manual)
486 {
487 	struct dm_struct *dm = (struct dm_struct *)dm_void;
488 	struct ccx_info *ccx = &dm->dm_ccx_info;
489 	boolean is_update = false;
490 	u8 igi_curr = phydm_get_igi(dm, BB_PATH_A);
491 	u8 nhm_igi_th_11k_low[NHM_TH_NUM] = {0x12, 0x15, 0x18, 0x1b, 0x1e,
492 					     0x23, 0x28, 0x2c, 0x78,
493 					     0x78, 0x78};
494 	u8 nhm_igi_th_11k_high[NHM_TH_NUM] = {0x1e, 0x23, 0x28, 0x2d, 0x32,
495 					      0x37, 0x78, 0x78, 0x78, 0x78,
496 					      0x78};
497 	u8 nhm_igi_th_xbox[NHM_TH_NUM] = {0x1a, 0x2c, 0x2e, 0x30, 0x32, 0x34,
498 					  0x36, 0x38, 0x3a, 0x3c, 0x3d};
499 	u8 nhm_igi_th_11k[NHM_TH_NUM] = {0x12, 0x15, 0x18, 0x1b, 0x1e, 0x23,
500 					  0x28, 0x2d, 0x32, 0x37, 0x3c};
501 	/*11k_dbm : {-92, -89, -86, -83, -80, -75, -70, -65, -60, -55, -50};*/
502 	/*11k_gain_idx : {18, 21, 24, 27, 30, 35, 40, 45, 50, 55, 60};*/
503 
504 	u8 i = 0;
505 	u8 th_tmp = igi_curr - CCA_CAP;
506 	u8 th_step = 2;
507 
508 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
509 	PHYDM_DBG(dm, DBG_ENV_MNTR, "App=%d, nhm_igi=0x%x, igi_curr=0x%x\n",
510 		  nhm_app, ccx->nhm_igi, igi_curr);
511 
512 	if (igi_curr < 0x10) /* Protect for invalid IGI*/
513 		return false;
514 
515 	switch (nhm_app) {
516 	case NHM_BACKGROUND: /* @Get IGI form driver parameter(cur_ig_value)*/
517 		if (ccx->nhm_igi != igi_curr || ccx->nhm_app != nhm_app) {
518 			is_update = true;
519 			*igi_new = (u32)igi_curr;
520 
521 			#ifdef NHM_DYM_PW_TH_SUPPORT
522 			if (ccx->nhm_dym_pw_th_en) {
523 				th_tmp = MAX_2(igi_curr - DYM_PWTH_CCA_CAP, 0);
524 				th_step = 3;
525 			}
526 			#endif
527 
528 			nhm_th[0] = (u8)IGI_2_NHM_TH(th_tmp);
529 
530 			for (i = 1; i <= 10; i++)
531 				nhm_th[i] = nhm_th[0] +
532 					    IGI_2_NHM_TH(th_step * i);
533 
534 		}
535 		break;
536 
537 	case NHM_ACS:
538 		if (ccx->nhm_igi != igi_curr || ccx->nhm_app != nhm_app) {
539 			is_update = true;
540 			*igi_new = (u32)igi_curr;
541 			for (i = 0; i < NHM_TH_NUM; i++)
542 				nhm_th[i] = IGI_2_NHM_TH(nhm_igi_th_11k[i]);
543 		}
544 		break;
545 
546 	case IEEE_11K_HIGH:
547 		is_update = true;
548 		*igi_new = 0x2c;
549 		for (i = 0; i < NHM_TH_NUM; i++)
550 			nhm_th[i] = IGI_2_NHM_TH(nhm_igi_th_11k_high[i]);
551 		break;
552 
553 	case IEEE_11K_LOW:
554 		is_update = true;
555 		*igi_new = 0x20;
556 		for (i = 0; i < NHM_TH_NUM; i++)
557 			nhm_th[i] = IGI_2_NHM_TH(nhm_igi_th_11k_low[i]);
558 		break;
559 
560 	case INTEL_XBOX:
561 		is_update = true;
562 		*igi_new = 0x36;
563 		for (i = 0; i < NHM_TH_NUM; i++)
564 			nhm_th[i] = IGI_2_NHM_TH(nhm_igi_th_xbox[i]);
565 		break;
566 
567 	case NHM_DBG: /*@Get IGI form register*/
568 		igi_curr = phydm_get_igi(dm, BB_PATH_A);
569 		if (ccx->nhm_igi != igi_curr || ccx->nhm_app != nhm_app) {
570 			is_update = true;
571 			*igi_new = (u32)igi_curr;
572 			if (en_1db_mode) {
573 				nhm_th[0] = (u8)IGI_2_NHM_TH(nhm_th0_manual +
574 							     10);
575 				th_step = 1;
576 			} else {
577 				nhm_th[0] = (u8)IGI_2_NHM_TH(igi_curr -
578 							     CCA_CAP);
579 			}
580 
581 			for (i = 1; i <= 10; i++)
582 				nhm_th[i] = nhm_th[0] + IGI_2_NHM_TH(th_step *
583 					    i);
584 		}
585 		break;
586 	}
587 
588 	if (is_update) {
589 		PHYDM_DBG(dm, DBG_ENV_MNTR, "[Update NHM_TH] igi_RSSI=%d\n",
590 			  IGI_2_RSSI(*igi_new));
591 
592 		for (i = 0; i < NHM_TH_NUM; i++) {
593 			PHYDM_DBG(dm, DBG_ENV_MNTR, "NHM_th[%d](RSSI) = %d\n",
594 				  i, NTH_TH_2_RSSI(nhm_th[i]));
595 		}
596 	} else {
597 		PHYDM_DBG(dm, DBG_ENV_MNTR, "No need to update NHM_TH\n");
598 	}
599 	return is_update;
600 }
601 
phydm_nhm_set(void * dm_void,enum nhm_option_txon_all include_tx,enum nhm_option_cca_all include_cca,enum nhm_divider_opt_all divi_opt,enum nhm_application nhm_app,u16 period,boolean en_1db_mode,u8 nhm_th0_manual)602 void phydm_nhm_set(void *dm_void, enum nhm_option_txon_all include_tx,
603 		   enum nhm_option_cca_all include_cca,
604 		   enum nhm_divider_opt_all divi_opt,
605 		   enum nhm_application nhm_app, u16 period,
606 		   boolean en_1db_mode, u8 nhm_th0_manual)
607 {
608 	struct dm_struct *dm = (struct dm_struct *)dm_void;
609 	struct ccx_info *ccx = &dm->dm_ccx_info;
610 	u8 nhm_th[NHM_TH_NUM] = {0};
611 	u32 igi = 0x20;
612 	u32 reg1 = 0, reg2 = 0;
613 	u32 val_tmp = 0;
614 
615 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
616 
617 	PHYDM_DBG(dm, DBG_ENV_MNTR,
618 		  "incld{tx, cca}={%d, %d}, divi_opt=%d, period=%d\n",
619 		  include_tx, include_cca, divi_opt, period);
620 
621 	if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
622 		reg1 = R_0x994;
623 		reg2 = R_0x990;
624 	#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
625 	} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {
626 		reg1 = R_0x1e60;
627 		reg2 = R_0x1e40;
628 	#endif
629 	} else {
630 		reg1 = R_0x890;
631 		reg2 = R_0x894;
632 	}
633 
634 	/*Set disable_ignore_cca, disable_ignore_txon, ccx_en*/
635 	if (include_tx != ccx->nhm_include_txon ||
636 	    include_cca != ccx->nhm_include_cca ||
637 	    divi_opt != ccx->nhm_divider_opt) {
638 	    /* some old ic is not supported on NHM divider option */
639 		if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8723B |
640 		    ODM_RTL8195A | ODM_RTL8192E)) {
641 			val_tmp = (u32)((include_tx << 2) |
642 				  (include_cca << 1) | 1);
643 			pdm_set_reg(dm, reg1, 0x700, val_tmp);
644 		} else {
645 			val_tmp = (u32)BIT_2_BYTE(divi_opt, include_tx,
646 				  include_cca, 1);
647 			pdm_set_reg(dm, reg1, 0xf00, val_tmp);
648 		}
649 		ccx->nhm_include_txon = include_tx;
650 		ccx->nhm_include_cca = include_cca;
651 		ccx->nhm_divider_opt = divi_opt;
652 	}
653 
654 	/*Set NHM period*/
655 	if (period != ccx->nhm_period) {
656 		pdm_set_reg(dm, reg2, MASKHWORD, period);
657 		PHYDM_DBG(dm, DBG_ENV_MNTR,
658 			  "Update NHM period ((%d)) -> ((%d))\n",
659 			  ccx->nhm_period, period);
660 
661 		ccx->nhm_period = period;
662 	}
663 
664 	/*Set NHM threshold*/
665 	if (phydm_nhm_th_update_chk(dm, nhm_app, &nhm_th[0], &igi,
666 				    en_1db_mode, nhm_th0_manual)) {
667 		/*Pause IGI*/
668 		if (nhm_app == NHM_BACKGROUND || nhm_app == NHM_ACS) {
669 			PHYDM_DBG(dm, DBG_ENV_MNTR, "DIG Free Run\n");
670 		} else if (phydm_pause_func(dm, F00_DIG, PHYDM_PAUSE,
671 					    PHYDM_PAUSE_LEVEL_1, 1, &igi)
672 					    == PAUSE_FAIL) {
673 			PHYDM_DBG(dm, DBG_ENV_MNTR, "pause DIG Fail\n");
674 			return;
675 		} else {
676 			PHYDM_DBG(dm, DBG_ENV_MNTR, "pause DIG=0x%x\n", igi);
677 		}
678 		ccx->nhm_app = nhm_app;
679 		ccx->nhm_igi = (u8)igi;
680 		odm_move_memory(dm, &ccx->nhm_th[0], &nhm_th, NHM_TH_NUM);
681 
682 		/*Set NHM th*/
683 		phydm_nhm_set_th_reg(dm);
684 	}
685 }
686 
687 boolean
phydm_nhm_mntr_set(void * dm_void,struct nhm_para_info * nhm_para)688 phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para)
689 {
690 	struct dm_struct *dm = (struct dm_struct *)dm_void;
691 	u16 nhm_time = 0; /*unit: 4us*/
692 
693 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
694 
695 	if (nhm_para->mntr_time == 0)
696 		return false;
697 
698 	if (nhm_para->nhm_lv >= NHM_MAX_NUM) {
699 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Wrong LV=%d\n", nhm_para->nhm_lv);
700 		return false;
701 	}
702 
703 	if (phydm_nhm_racing_ctrl(dm, nhm_para->nhm_lv) == PHYDM_SET_FAIL)
704 		return false;
705 
706 	if (nhm_para->mntr_time >= 262)
707 		nhm_time = NHM_PERIOD_MAX;
708 	else
709 		nhm_time = nhm_para->mntr_time * MS_TO_4US_RATIO;
710 
711 	phydm_nhm_set(dm, nhm_para->incld_txon, nhm_para->incld_cca,
712 		      nhm_para->div_opt, nhm_para->nhm_app, nhm_time,
713 		      nhm_para->en_1db_mode, nhm_para->nhm_th0_manual);
714 
715 	return true;
716 }
717 
718 #ifdef NHM_DYM_PW_TH_SUPPORT
719 void
phydm_nhm_restore_pw_th(void * dm_void)720 phydm_nhm_restore_pw_th(void *dm_void)
721 {
722 	struct dm_struct *dm = (struct dm_struct *)dm_void;
723 	struct ccx_info *ccx = &dm->dm_ccx_info;
724 
725 	odm_set_bb_reg(dm, R_0x82c, 0x3f, ccx->pw_th_rf20_ori);
726 }
727 
728 void
phydm_nhm_set_pw_th(void * dm_void,u8 noise,boolean chk_succ)729 phydm_nhm_set_pw_th(void *dm_void, u8 noise, boolean chk_succ)
730 {
731 	struct dm_struct *dm = (struct dm_struct *)dm_void;
732 	struct ccx_info *ccx = &dm->dm_ccx_info;
733 	boolean not_update = false;
734 	u8 pw_th_rf20_new = 0;
735 	u8 pw_th_u_bnd = 0;
736 	s8 noise_diff = 0;
737 	u8 point_mean = 15;
738 
739 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
740 
741 	if (*dm->band_width != CHANNEL_WIDTH_20 ||
742 	    *dm->band_type == ODM_BAND_5G) {
743 		PHYDM_DBG(dm, DBG_ENV_MNTR,  "bandwidth=((%d)), band=((%d))\n",
744 			  *dm->band_width, *dm->band_type);
745 		phydm_nhm_restore_pw_th(dm);
746 		return;
747 	}
748 
749 	if (chk_succ) {
750 		noise_diff = noise - (ccx->nhm_igi - 10);
751 		pw_th_u_bnd = (u8)(noise_diff + 32 + point_mean);
752 
753 		pw_th_u_bnd = MIN_2(pw_th_u_bnd, ccx->nhm_pw_th_max);
754 
755 		PHYDM_DBG(dm, DBG_ENV_MNTR,
756 			  "noise_diff=((%d)), max=((%d)), pw_th_u_bnd=((%d))\n",
757 			  noise_diff, ccx->nhm_pw_th_max, pw_th_u_bnd);
758 
759 		if (pw_th_u_bnd > ccx->pw_th_rf20_cur) {
760 			pw_th_rf20_new = ccx->pw_th_rf20_cur + 1;
761 		} else if (pw_th_u_bnd < ccx->pw_th_rf20_cur) {
762 			if (ccx->pw_th_rf20_cur > ccx->pw_th_rf20_ori)
763 				pw_th_rf20_new = ccx->pw_th_rf20_cur - 1;
764 			else /*ccx->pw_th_rf20_cur == ccx->pw_th_ori*/
765 				not_update = true;
766 		} else {/*pw_th_u_bnd == ccx->pw_th_rf20_cur*/
767 			not_update = true;
768 		}
769 	} else {
770 		if (ccx->pw_th_rf20_cur > ccx->pw_th_rf20_ori)
771 			pw_th_rf20_new = ccx->pw_th_rf20_cur - 1;
772 		else /*ccx->pw_th_rf20_cur == ccx->pw_th_ori*/
773 			not_update = true;
774 	}
775 
776 	PHYDM_DBG(dm, DBG_ENV_MNTR, "pw_th_cur=((%d)), pw_th_new=((%d))\n",
777 		  ccx->pw_th_rf20_cur, pw_th_rf20_new);
778 
779 	if (!not_update) {
780 		odm_set_bb_reg(dm, R_0x82c, 0x3f, pw_th_rf20_new);
781 		ccx->pw_th_rf20_cur = pw_th_rf20_new;
782 	}
783 }
784 
785 void
phydm_nhm_dym_pw_th(void * dm_void)786 phydm_nhm_dym_pw_th(void *dm_void)
787 {
788 	struct dm_struct *dm = (struct dm_struct *)dm_void;
789 	struct ccx_info *ccx = &dm->dm_ccx_info;
790 	u8 i = 0;
791 	u8 n_sum = 0;
792 	u8 noise = 0;
793 	boolean chk_succ = false;
794 
795 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
796 
797 	for (i = 0; i < NHM_RPT_NUM - 3; i++) {
798 		n_sum = ccx->nhm_result[i] + ccx->nhm_result[i + 1] +
799 			ccx->nhm_result[i + 2] + ccx->nhm_result[i + 3];
800 		if (n_sum >= ccx->nhm_sl_pw_th) {
801 			PHYDM_DBG(dm, DBG_ENV_MNTR, "Do sl[%d:%d]\n", i, i + 3);
802 			chk_succ = true;
803 			noise = phydm_nhm_cal_wgt_avg(dm, i, i + 3, n_sum);
804 			break;
805 		}
806 	}
807 
808 	if (!chk_succ)
809 		PHYDM_DBG(dm, DBG_ENV_MNTR, "SL method failed!\n");
810 
811 	phydm_nhm_set_pw_th(dm, noise, chk_succ);
812 }
813 
814 boolean
phydm_nhm_dym_pw_th_en(void * dm_void)815 phydm_nhm_dym_pw_th_en(void *dm_void)
816 {
817 	struct dm_struct *dm = (struct dm_struct *)dm_void;
818 	struct ccx_info *ccx = &dm->dm_ccx_info;
819 	struct phydm_iot_center	*iot_table = &dm->iot_table;
820 
821 	if (!(dm->support_ic_type & ODM_RTL8822C))
822 		return false;
823 
824 	if (ccx->dym_pwth_manual_ctrl)
825 		return true;
826 
827 	if (dm->iot_table.phydm_patch_id == 0x100f0401 ||
828 	    iot_table->patch_id_100f0401) {
829 		return true;
830 	} else if (ccx->nhm_dym_pw_th_en) {
831 		phydm_nhm_restore_pw_th(dm);
832 		return false;
833 	} else {
834 		return false;
835 	}
836 }
837 #endif
838 
839 /*Environment Monitor*/
840 boolean
phydm_nhm_mntr_racing_chk(void * dm_void)841 phydm_nhm_mntr_racing_chk(void *dm_void)
842 {
843 	struct dm_struct *dm = (struct dm_struct *)dm_void;
844 	struct ccx_info *ccx = &dm->dm_ccx_info;
845 	u32 sys_return_time = 0;
846 
847 	if (ccx->nhm_manual_ctrl) {
848 		PHYDM_DBG(dm, DBG_ENV_MNTR, "NHM in manual ctrl\n");
849 		return true;
850 	}
851 
852 	sys_return_time = ccx->nhm_trigger_time + MAX_ENV_MNTR_TIME;
853 
854 	if (ccx->nhm_app != NHM_BACKGROUND &&
855 	    (sys_return_time > dm->phydm_sys_up_time)) {
856 		PHYDM_DBG(dm, DBG_ENV_MNTR,
857 			  "nhm_app=%d, trigger_time %d, sys_time=%d\n",
858 			  ccx->nhm_app, ccx->nhm_trigger_time,
859 			  dm->phydm_sys_up_time);
860 
861 		return true;
862 	}
863 
864 	return false;
865 }
866 
867 boolean
phydm_nhm_mntr_chk(void * dm_void,u16 monitor_time)868 phydm_nhm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/)
869 {
870 	struct dm_struct *dm = (struct dm_struct *)dm_void;
871 	struct ccx_info *ccx = &dm->dm_ccx_info;
872 	struct nhm_para_info nhm_para = {0};
873 	boolean nhm_chk_result = false;
874 
875 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
876 
877 	if (phydm_nhm_mntr_racing_chk(dm))
878 		return nhm_chk_result;
879 
880 	/*[NHM trigger setting]------------------------------------------*/
881 	nhm_para.incld_txon = NHM_EXCLUDE_TXON;
882 	nhm_para.incld_cca = NHM_EXCLUDE_CCA;
883 	nhm_para.div_opt = NHM_CNT_ALL;
884 	nhm_para.nhm_app = NHM_BACKGROUND;
885 	nhm_para.nhm_lv = NHM_LV_1;
886 	nhm_para.en_1db_mode = false;
887 	nhm_para.mntr_time = monitor_time;
888 
889 	#ifdef NHM_DYM_PW_TH_SUPPORT
890 	if (ccx->nhm_dym_pw_th_en) {
891 		nhm_para.div_opt = NHM_VALID;
892 		nhm_para.mntr_time = monitor_time >> ccx->nhm_period_decre;
893 	}
894 	#endif
895 
896 	nhm_chk_result = phydm_nhm_mntr_set(dm, &nhm_para);
897 
898 	return nhm_chk_result;
899 }
900 
901 boolean
phydm_nhm_mntr_result(void * dm_void)902 phydm_nhm_mntr_result(void *dm_void)
903 {
904 	struct dm_struct *dm = (struct dm_struct *)dm_void;
905 	struct ccx_info *ccx = &dm->dm_ccx_info;
906 	boolean nhm_chk_result = false;
907 
908 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
909 
910 	if (phydm_nhm_mntr_racing_chk(dm))
911 		return nhm_chk_result;
912 
913 	/*[NHM get result & calculate Utility]---------------------------*/
914 	if (phydm_nhm_get_result(dm)) {
915 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM_rpt success\n");
916 		phydm_nhm_get_utility(dm);
917 		nhm_chk_result = true;
918 	}
919 
920 	#ifdef NHM_DYM_PW_TH_SUPPORT
921 	ccx->nhm_dym_pw_th_en = phydm_nhm_dym_pw_th_en(dm);
922 	if (ccx->nhm_dym_pw_th_en) {
923 		if (nhm_chk_result)
924 			phydm_nhm_dym_pw_th(dm);
925 		else
926 			phydm_nhm_set_pw_th(dm, 0x0, false);
927 	}
928 	#endif
929 
930 	return nhm_chk_result;
931 }
932 
phydm_nhm_init(void * dm_void)933 void phydm_nhm_init(void *dm_void)
934 {
935 	struct dm_struct *dm = (struct dm_struct *)dm_void;
936 	struct ccx_info *ccx = &dm->dm_ccx_info;
937 
938 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
939 	PHYDM_DBG(dm, DBG_ENV_MNTR, "cur_igi=0x%x\n",
940 		  dm->dm_dig_table.cur_ig_value);
941 
942 	ccx->nhm_app = NHM_BACKGROUND;
943 	ccx->nhm_igi = 0xff;
944 
945 	/*Set NHM threshold*/
946 	ccx->nhm_ongoing = false;
947 	ccx->nhm_set_lv = NHM_RELEASE;
948 
949 	if (phydm_nhm_th_update_chk(dm, ccx->nhm_app, &ccx->nhm_th[0],
950 				    (u32 *)&ccx->nhm_igi, false, 0))
951 		phydm_nhm_set_th_reg(dm);
952 
953 	ccx->nhm_period = 0;
954 
955 	ccx->nhm_include_cca = NHM_CCA_INIT;
956 	ccx->nhm_include_txon = NHM_TXON_INIT;
957 	ccx->nhm_divider_opt = NHM_CNT_INIT;
958 
959 	ccx->nhm_manual_ctrl = 0;
960 	ccx->nhm_rpt_stamp = 0;
961 
962 	#ifdef NHM_DYM_PW_TH_SUPPORT
963 	if (dm->support_ic_type & ODM_RTL8822C) {
964 		ccx->nhm_dym_pw_th_en = false;
965 		ccx->pw_th_rf20_ori = (u8)odm_get_bb_reg(dm, R_0x82c, 0x3f);
966 		ccx->pw_th_rf20_cur = ccx->pw_th_rf20_ori;
967 		ccx->nhm_pw_th_max = 63;
968 		ccx->nhm_sl_pw_th = 100; /*39%*/
969 		ccx->nhm_period_decre = 1;
970 		ccx->dym_pwth_manual_ctrl = false;
971 	}
972 	#endif
973 }
974 
phydm_nhm_dbg(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)975 void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output,
976 		   u32 *_out_len)
977 {
978 	struct dm_struct *dm = (struct dm_struct *)dm_void;
979 	struct ccx_info *ccx = &dm->dm_ccx_info;
980 	struct nhm_para_info nhm_para = {0};
981 	char help[] = "-h";
982 	u32 var1[10] = {0};
983 	u32 used = *_used;
984 	u32 out_len = *_out_len;
985 	u8 result_tmp = 0;
986 	u8 i = 0;
987 
988 	PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
989 
990 	if ((strcmp(input[1], help) == 0)) {
991 		PDM_SNPF(out_len, used, output + used, out_len - used,
992 			 "NHM Basic-Trigger 262ms: {1}\n");
993 
994 		PDM_SNPF(out_len, used, output + used, out_len - used,
995 			 "NHM Adv-Trigger: {2} {Include TXON} {Include CCA}\n{0:Cnt_all, 1:Cnt valid} {App:5 for dbg} {LV:1~4} {0~262ms}, 1dB mode :{en} {t[0](RSSI)}\n");
996 		#ifdef NHM_DYM_PW_TH_SUPPORT
997 		if (dm->support_ic_type & ODM_RTL8822C) {
998 			PDM_SNPF(out_len, used, output + used, out_len - used,
999 				 "NHM dym_pw_th: {3} {0:off}\n");
1000 			PDM_SNPF(out_len, used, output + used, out_len - used,
1001 				 "NHM dym_pw_th: {3} {1:on} {max} {period_decre} {sl_th}\n");
1002 			PDM_SNPF(out_len, used, output + used, out_len - used,
1003 				 "NHM dym_pw_th: {3} {2:fast on}\n");
1004 		}
1005 		#endif
1006 
1007 		PDM_SNPF(out_len, used, output + used, out_len - used,
1008 			 "NHM Get Result: {100}\n");
1009 	} else if (var1[0] == 100) { /*Get NHM results*/
1010 
1011 		PDM_SNPF(out_len, used, output + used, out_len - used,
1012 			 "IGI=0x%x, rpt_stamp=%d\n", ccx->nhm_igi,
1013 			 ccx->nhm_rpt_stamp);
1014 
1015 		if (phydm_nhm_get_result(dm)) {
1016 			for (i = 0; i < NHM_RPT_NUM; i++) {
1017 				result_tmp = ccx->nhm_result[i];
1018 				PDM_SNPF(out_len, used, output + used,
1019 					 out_len - used,
1020 					 "nhm_rpt[%d] = %d (%d percent)\n",
1021 					 i, result_tmp,
1022 					 (((result_tmp * 100) + 128) >> 8));
1023 			}
1024 			phydm_nhm_get_utility(dm);
1025 
1026 			PDM_SNPF(out_len, used, output + used, out_len - used,
1027 				 "NHM_noise: valid: %d percent, noise(RSSI) = %d\n",
1028 				 ccx->nhm_level_valid, ccx->nhm_level);
1029 			PDM_SNPF(out_len, used, output + used, out_len - used,
1030 				 "NHM_pwr: nhm_pwr (RSSI) = %d\n", ccx->nhm_pwr);
1031 			PDM_SNPF(out_len, used, output + used, out_len - used,
1032 				 "ratio: nhm_ratio=%d, nhm_env_ratio=%d\n",
1033 				 ccx->nhm_ratio, ccx->nhm_env_ratio);
1034 		} else {
1035 			PDM_SNPF(out_len, used, output + used, out_len - used,
1036 				 "Get NHM_rpt Fail\n");
1037 		}
1038 		ccx->nhm_manual_ctrl = 0;
1039 	#ifdef NHM_DYM_PW_TH_SUPPORT
1040 	} else if (var1[0] == 3) { /*NMH dym_pw_th*/
1041 		if (dm->support_ic_type & ODM_RTL8822C) {
1042 			for (i = 1; i < 7; i++) {
1043 				PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
1044 					     &var1[i]);
1045 			}
1046 
1047 			if (var1[1] == 1) {
1048 				ccx->nhm_dym_pw_th_en = true;
1049 				ccx->nhm_pw_th_max = (u8)var1[2];
1050 				ccx->nhm_period_decre = (u8)var1[3];
1051 				ccx->nhm_sl_pw_th = (u8)var1[4];
1052 				ccx->dym_pwth_manual_ctrl = true;
1053 			} else if (var1[1] == 2) {
1054 				ccx->nhm_dym_pw_th_en = true;
1055 				ccx->nhm_pw_th_max = 63;
1056 				ccx->nhm_period_decre = 1;
1057 				ccx->nhm_sl_pw_th = 100;
1058 				ccx->dym_pwth_manual_ctrl = true;
1059 			} else {
1060 				ccx->nhm_dym_pw_th_en = false;
1061 				phydm_nhm_restore_pw_th(dm);
1062 				ccx->dym_pwth_manual_ctrl = false;
1063 			}
1064 		}
1065 	#endif
1066 	} else { /*NMH trigger*/
1067 		ccx->nhm_manual_ctrl = 1;
1068 
1069 		for (i = 1; i < 9; i++) {
1070 			PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
1071 				     &var1[i]);
1072 		}
1073 
1074 		if (var1[0] == 1) {
1075 			nhm_para.incld_txon = NHM_EXCLUDE_TXON;
1076 			nhm_para.incld_cca = NHM_EXCLUDE_CCA;
1077 			nhm_para.div_opt = NHM_CNT_ALL;
1078 			nhm_para.nhm_app = NHM_DBG;
1079 			nhm_para.nhm_lv = NHM_LV_4;
1080 			nhm_para.mntr_time = 262;
1081 			nhm_para.en_1db_mode = false;
1082 			nhm_para.nhm_th0_manual = 0;
1083 		} else {
1084 			nhm_para.incld_txon = (enum nhm_option_txon_all)var1[1];
1085 			nhm_para.incld_cca = (enum nhm_option_cca_all)var1[2];
1086 			nhm_para.div_opt = (enum nhm_divider_opt_all)var1[3];
1087 			nhm_para.nhm_app = (enum nhm_application)var1[4];
1088 			nhm_para.nhm_lv = (enum phydm_nhm_level)var1[5];
1089 			nhm_para.mntr_time = (u16)var1[6];
1090 			nhm_para.en_1db_mode = (boolean)var1[7];
1091 			nhm_para.nhm_th0_manual = (u8)var1[8];
1092 
1093 			/*some old ic is not supported on NHM divider option */
1094 			if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8723B |
1095 			    ODM_RTL8195A | ODM_RTL8192E)) {
1096 				nhm_para.div_opt = NHM_CNT_ALL;
1097 			}
1098 		}
1099 
1100 		PDM_SNPF(out_len, used, output + used, out_len - used,
1101 			 "txon=%d, cca=%d, dev=%d, app=%d, lv=%d, time=%d ms\n",
1102 			 nhm_para.incld_txon, nhm_para.incld_cca,
1103 			 nhm_para.div_opt, nhm_para.nhm_app,
1104 			 nhm_para.nhm_lv, nhm_para.mntr_time);
1105 
1106 		PDM_SNPF(out_len, used, output + used, out_len - used,
1107 			 "en_1db_mode=%d, th0(for 1db mode)=%d\n",
1108 			 nhm_para.en_1db_mode, nhm_para.nhm_th0_manual);
1109 
1110 		if (phydm_nhm_mntr_set(dm, &nhm_para))
1111 			phydm_nhm_trigger(dm);
1112 
1113 		PDM_SNPF(out_len, used, output + used, out_len - used,
1114 			 "IGI=0x%x, rpt_stamp=%d\n", ccx->nhm_igi,
1115 			 ccx->nhm_rpt_stamp);
1116 
1117 		for (i = 0; i < NHM_TH_NUM; i++) {
1118 			PDM_SNPF(out_len, used, output + used, out_len - used,
1119 				 "NHM_th[%d] RSSI = %d\n", i,
1120 				 NTH_TH_2_RSSI(ccx->nhm_th[i]));
1121 		}
1122 	}
1123 
1124 	*_used = used;
1125 	*_out_len = out_len;
1126 }
1127 
1128 #endif /*@#ifdef NHM_SUPPORT*/
1129 
1130 #ifdef CLM_SUPPORT
1131 
phydm_clm_racing_release(void * dm_void)1132 void phydm_clm_racing_release(void *dm_void)
1133 {
1134 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1135 	struct ccx_info *ccx = &dm->dm_ccx_info;
1136 
1137 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
1138 	PHYDM_DBG(dm, DBG_ENV_MNTR, "lv:(%d)->(0)\n", ccx->clm_set_lv);
1139 
1140 	ccx->clm_ongoing = false;
1141 	ccx->clm_set_lv = CLM_RELEASE;
1142 	ccx->clm_app = CLM_BACKGROUND;
1143 }
1144 
phydm_clm_racing_ctrl(void * dm_void,enum phydm_clm_level clm_lv)1145 u8 phydm_clm_racing_ctrl(void *dm_void, enum phydm_clm_level clm_lv)
1146 {
1147 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1148 	struct ccx_info *ccx = &dm->dm_ccx_info;
1149 	u8 set_result = PHYDM_SET_SUCCESS;
1150 	/*@acquire to control CLM API*/
1151 
1152 	PHYDM_DBG(dm, DBG_ENV_MNTR, "clm_ongoing=%d, lv:(%d)->(%d)\n",
1153 		  ccx->clm_ongoing, ccx->clm_set_lv, clm_lv);
1154 	if (ccx->clm_ongoing) {
1155 		if (clm_lv <= ccx->clm_set_lv) {
1156 			set_result = PHYDM_SET_FAIL;
1157 		} else {
1158 			phydm_ccx_hw_restart(dm);
1159 			ccx->clm_ongoing = false;
1160 		}
1161 	}
1162 
1163 	if (set_result)
1164 		ccx->clm_set_lv = clm_lv;
1165 
1166 	PHYDM_DBG(dm, DBG_ENV_MNTR, "clm racing success=%d\n", set_result);
1167 	return set_result;
1168 }
1169 
phydm_clm_c2h_report_handler(void * dm_void,u8 * cmd_buf,u8 cmd_len)1170 void phydm_clm_c2h_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len)
1171 {
1172 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1173 	struct ccx_info *ccx_info = &dm->dm_ccx_info;
1174 	u8 clm_report = cmd_buf[0];
1175 	/*@u8 clm_report_idx = cmd_buf[1];*/
1176 
1177 	if (cmd_len >= 12)
1178 		return;
1179 
1180 	ccx_info->clm_fw_result_acc += clm_report;
1181 	ccx_info->clm_fw_result_cnt++;
1182 
1183 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%d] clm_report= %d\n",
1184 		  ccx_info->clm_fw_result_cnt, clm_report);
1185 }
1186 
phydm_clm_h2c(void * dm_void,u16 obs_time,u8 fw_clm_en)1187 void phydm_clm_h2c(void *dm_void, u16 obs_time, u8 fw_clm_en)
1188 {
1189 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1190 	u8 h2c_val[H2C_MAX_LENGTH] = {0};
1191 	u8 i = 0;
1192 	u8 obs_time_idx = 0;
1193 
1194 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__);
1195 	PHYDM_DBG(dm, DBG_ENV_MNTR, "obs_time_index=%d *4 us\n", obs_time);
1196 
1197 	for (i = 1; i <= 16; i++) {
1198 		if (obs_time & BIT(16 - i)) {
1199 			obs_time_idx = 16 - i;
1200 			break;
1201 		}
1202 	}
1203 #if 0
1204 	obs_time = (2 ^ 16 - 1)~(2 ^ 15)  => obs_time_idx = 15  (65535 ~32768)
1205 	obs_time = (2 ^ 15 - 1)~(2 ^ 14)  => obs_time_idx = 14
1206 	...
1207 	...
1208 	...
1209 	obs_time = (2 ^ 1 - 1)~(2 ^ 0)  => obs_time_idx = 0
1210 
1211 #endif
1212 
1213 	h2c_val[0] = obs_time_idx | (((fw_clm_en) ? 1 : 0) << 7);
1214 	h2c_val[1] = CLM_MAX_REPORT_TIME;
1215 
1216 	PHYDM_DBG(dm, DBG_ENV_MNTR, "PHYDM h2c[0x4d]=0x%x %x %x %x %x %x %x\n",
1217 		  h2c_val[6], h2c_val[5], h2c_val[4], h2c_val[3], h2c_val[2],
1218 		  h2c_val[1], h2c_val[0]);
1219 
1220 	odm_fill_h2c_cmd(dm, PHYDM_H2C_FW_CLM_MNTR, H2C_MAX_LENGTH, h2c_val);
1221 }
1222 
phydm_clm_setting(void * dm_void,u16 clm_period)1223 void phydm_clm_setting(void *dm_void, u16 clm_period /*@4us sample 1 time*/)
1224 {
1225 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1226 	struct ccx_info *ccx = &dm->dm_ccx_info;
1227 
1228 	if (ccx->clm_period != clm_period) {
1229 		if (dm->support_ic_type & ODM_IC_11AC_SERIES)
1230 			odm_set_bb_reg(dm, R_0x990, MASKLWORD, clm_period);
1231 		#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
1232 		else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)
1233 			odm_set_bb_reg(dm, R_0x1e40, MASKLWORD, clm_period);
1234 		#endif
1235 		else if (dm->support_ic_type & ODM_IC_11N_SERIES)
1236 			odm_set_bb_reg(dm, R_0x894, MASKLWORD, clm_period);
1237 
1238 		ccx->clm_period = clm_period;
1239 		PHYDM_DBG(dm, DBG_ENV_MNTR,
1240 			  "Update CLM period ((%d)) -> ((%d))\n",
1241 			  ccx->clm_period, clm_period);
1242 	}
1243 
1244 	PHYDM_DBG(dm, DBG_ENV_MNTR, "Set CLM period=%d * 4us\n",
1245 		  ccx->clm_period);
1246 }
1247 
phydm_clm_trigger(void * dm_void)1248 void phydm_clm_trigger(void *dm_void)
1249 {
1250 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1251 	struct ccx_info *ccx = &dm->dm_ccx_info;
1252 	u32 reg1 = 0;
1253 
1254 	if (dm->support_ic_type & ODM_IC_11AC_SERIES)
1255 		reg1 = R_0x994;
1256 	#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
1257 	else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)
1258 		reg1 = R_0x1e60;
1259 	#endif
1260 	else
1261 		reg1 = R_0x890;
1262 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
1263 
1264 	odm_set_bb_reg(dm, reg1, BIT(0), 0x0);
1265 	odm_set_bb_reg(dm, reg1, BIT(0), 0x1);
1266 
1267 	ccx->clm_trigger_time = dm->phydm_sys_up_time;
1268 	ccx->clm_rpt_stamp++;
1269 	ccx->clm_ongoing = true;
1270 }
1271 
1272 boolean
phydm_clm_check_rdy(void * dm_void)1273 phydm_clm_check_rdy(void *dm_void)
1274 {
1275 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1276 	boolean is_ready = false;
1277 	u32 reg1 = 0, reg1_bit = 0;
1278 
1279 	if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1280 		reg1 = R_0xfa4;
1281 		reg1_bit = 16;
1282 	#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
1283 	} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {
1284 		reg1 = R_0x2d88;
1285 		reg1_bit = 16;
1286 	#endif
1287 	} else if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1288 		if (dm->support_ic_type & (ODM_RTL8710B | ODM_RTL8721D |
1289 					ODM_RTL8710C)) {
1290 			reg1 = R_0x8b4;
1291 			reg1_bit = 24;
1292 		} else {
1293 			reg1 = R_0x8b4;
1294 			reg1_bit = 16;
1295 		}
1296 	}
1297 	if (odm_get_bb_reg(dm, reg1, BIT(reg1_bit)))
1298 		is_ready = true;
1299 
1300 	PHYDM_DBG(dm, DBG_ENV_MNTR, "CLM rdy=%d\n", is_ready);
1301 
1302 	return is_ready;
1303 }
1304 
phydm_clm_get_utility(void * dm_void)1305 void phydm_clm_get_utility(void *dm_void)
1306 {
1307 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1308 	struct ccx_info *ccx = &dm->dm_ccx_info;
1309 
1310 	if (ccx->clm_period == 0) {
1311 		PHYDM_DBG(dm, DBG_ENV_MNTR, "[warning] clm_period = 0\n");
1312 		ccx->clm_ratio = 0;
1313 	} else {
1314 		ccx->clm_ratio = phydm_ccx_get_rpt_ratio(dm, ccx->clm_result,
1315 							 ccx->clm_period);
1316 	}
1317 }
1318 
1319 boolean
phydm_clm_get_result(void * dm_void)1320 phydm_clm_get_result(void *dm_void)
1321 {
1322 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1323 	struct ccx_info *ccx_info = &dm->dm_ccx_info;
1324 	u32 reg1 = 0;
1325 	u32 val = 0;
1326 
1327 	if (dm->support_ic_type & ODM_IC_11AC_SERIES)
1328 		reg1 = R_0x994;
1329 	#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
1330 	else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)
1331 		reg1 = R_0x1e60;
1332 	#endif
1333 	else
1334 		reg1 = R_0x890;
1335 	if ((dm->support_ic_type & ODM_IC_11N_SERIES) ||
1336 	    (dm->support_ic_type & ODM_IC_11AC_SERIES) ||
1337 	    (dm->support_ic_type & ODM_RTL8198F) ||
1338 	    (dm->support_ic_type & ODM_RTL8814B))
1339 		odm_set_bb_reg(dm, reg1, BIT(0), 0x0);
1340 
1341 	if (!(phydm_clm_check_rdy(dm))) {
1342 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM report Fail\n");
1343 		phydm_clm_racing_release(dm);
1344 		return false;
1345 	}
1346 
1347 	if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1348 		val = odm_get_bb_reg(dm, R_0xfa4, MASKLWORD);
1349 		ccx_info->clm_result = (u16)val;
1350 	#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
1351 	} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {
1352 		val = odm_get_bb_reg(dm, R_0x2d88, MASKLWORD);
1353 		ccx_info->clm_result = (u16)val;
1354 	#endif
1355 	} else if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1356 		val = odm_get_bb_reg(dm, R_0x8d0, MASKLWORD);
1357 		ccx_info->clm_result = (u16)val;
1358 	}
1359 
1360 	PHYDM_DBG(dm, DBG_ENV_MNTR, "CLM result = %d *4 us\n",
1361 		  ccx_info->clm_result);
1362 	phydm_clm_racing_release(dm);
1363 	return true;
1364 }
1365 
1366 boolean
phydm_clm_mntr_set(void * dm_void,struct clm_para_info * clm_para)1367 phydm_clm_mntr_set(void *dm_void, struct clm_para_info *clm_para)
1368 {
1369 	/*@Driver Monitor CLM*/
1370 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1371 	struct ccx_info *ccx = &dm->dm_ccx_info;
1372 	u16 clm_period = 0;
1373 
1374 	if (clm_para->mntr_time == 0)
1375 		return false;
1376 
1377 	if (clm_para->clm_lv >= CLM_MAX_NUM) {
1378 		PHYDM_DBG(dm, DBG_ENV_MNTR, "[WARNING] Wrong LV=%d\n",
1379 			  clm_para->clm_lv);
1380 		return false;
1381 	}
1382 
1383 	if (phydm_clm_racing_ctrl(dm, clm_para->clm_lv) == PHYDM_SET_FAIL)
1384 		return false;
1385 
1386 	if (clm_para->mntr_time >= 262)
1387 		clm_period = CLM_PERIOD_MAX;
1388 	else
1389 		clm_period = clm_para->mntr_time * MS_TO_4US_RATIO;
1390 
1391 	ccx->clm_app = clm_para->clm_app;
1392 	phydm_clm_setting(dm, clm_period);
1393 
1394 	return true;
1395 }
1396 
1397 boolean
phydm_clm_mntr_racing_chk(void * dm_void)1398 phydm_clm_mntr_racing_chk(void *dm_void)
1399 {
1400 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1401 	struct ccx_info *ccx = &dm->dm_ccx_info;
1402 	u32 sys_return_time = 0;
1403 
1404 	if (ccx->clm_manual_ctrl) {
1405 		PHYDM_DBG(dm, DBG_ENV_MNTR, "CLM in manual ctrl\n");
1406 		return true;
1407 	}
1408 
1409 	sys_return_time = ccx->clm_trigger_time + MAX_ENV_MNTR_TIME;
1410 
1411 	if (ccx->clm_app != CLM_BACKGROUND &&
1412 	    (sys_return_time > dm->phydm_sys_up_time)) {
1413 		PHYDM_DBG(dm, DBG_ENV_MNTR,
1414 			  "clm_app=%d, trigger_time %d, sys_time=%d\n",
1415 			  ccx->clm_app, ccx->clm_trigger_time,
1416 			  dm->phydm_sys_up_time);
1417 
1418 		return true;
1419 	}
1420 
1421 	return false;
1422 }
1423 
1424 boolean
phydm_clm_mntr_chk(void * dm_void,u16 monitor_time)1425 phydm_clm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/)
1426 {
1427 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1428 	struct ccx_info *ccx = &dm->dm_ccx_info;
1429 	struct clm_para_info clm_para = {0};
1430 	boolean clm_chk_result = false;
1431 
1432 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__);
1433 
1434 	if (phydm_clm_mntr_racing_chk(dm))
1435 		return clm_chk_result;
1436 
1437 	clm_para.clm_app = CLM_BACKGROUND;
1438 	clm_para.clm_lv = CLM_LV_1;
1439 	clm_para.mntr_time = monitor_time;
1440 	if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) {
1441 		if (phydm_clm_mntr_set(dm, &clm_para))
1442 			clm_chk_result = true;
1443 	} else {
1444 		if (monitor_time >= 262)
1445 			ccx->clm_period = 65535;
1446 		else
1447 			ccx->clm_period = monitor_time * MS_TO_4US_RATIO;
1448 
1449 		phydm_clm_h2c(dm, ccx->clm_period, true);
1450 	}
1451 
1452 	return clm_chk_result;
1453 }
1454 
1455 boolean
phydm_clm_mntr_result(void * dm_void)1456 phydm_clm_mntr_result(void *dm_void)
1457 {
1458 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1459 	struct ccx_info *ccx = &dm->dm_ccx_info;
1460 	boolean clm_chk_result = false;
1461 	u32 val = 0;
1462 
1463 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__);
1464 
1465 	if (phydm_clm_mntr_racing_chk(dm))
1466 		return clm_chk_result;
1467 
1468 	if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) {
1469 		if (phydm_clm_get_result(dm)) {
1470 			PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM_rpt success\n");
1471 			phydm_clm_get_utility(dm);
1472 			clm_chk_result = true;
1473 		}
1474 	} else {
1475 		if (ccx->clm_fw_result_cnt != 0) {
1476 			val = ccx->clm_fw_result_acc / ccx->clm_fw_result_cnt;
1477 			ccx->clm_ratio = (u8)val;
1478 			clm_chk_result = true;
1479 		} else {
1480 			ccx->clm_ratio = 0;
1481 		}
1482 
1483 		PHYDM_DBG(dm, DBG_ENV_MNTR,
1484 			  "clm_fw_result_acc=%d, clm_fw_result_cnt=%d\n",
1485 			  ccx->clm_fw_result_acc, ccx->clm_fw_result_cnt);
1486 
1487 		ccx->clm_fw_result_acc = 0;
1488 		ccx->clm_fw_result_cnt = 0;
1489 	}
1490 
1491 	PHYDM_DBG(dm, DBG_ENV_MNTR, "clm_ratio=%d\n", ccx->clm_ratio);
1492 
1493 	return clm_chk_result;
1494 }
1495 
phydm_set_clm_mntr_mode(void * dm_void,enum clm_monitor_mode mode)1496 void phydm_set_clm_mntr_mode(void *dm_void, enum clm_monitor_mode mode)
1497 {
1498 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1499 	struct ccx_info *ccx_info = &dm->dm_ccx_info;
1500 
1501 	if (ccx_info->clm_mntr_mode != mode) {
1502 		ccx_info->clm_mntr_mode = mode;
1503 		phydm_ccx_hw_restart(dm);
1504 
1505 		if (mode == CLM_DRIVER_MNTR)
1506 			phydm_clm_h2c(dm, CLM_PERIOD_MAX, 0);
1507 	}
1508 }
1509 
phydm_clm_init(void * dm_void)1510 void phydm_clm_init(void *dm_void)
1511 {
1512 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1513 	struct ccx_info *ccx = &dm->dm_ccx_info;
1514 
1515 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
1516 	ccx->clm_ongoing = false;
1517 	ccx->clm_manual_ctrl = 0;
1518 	ccx->clm_mntr_mode = CLM_DRIVER_MNTR;
1519 	ccx->clm_period = 0;
1520 	ccx->clm_rpt_stamp = 0;
1521 	phydm_clm_setting(dm, 65535);
1522 }
1523 
phydm_clm_dbg(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)1524 void phydm_clm_dbg(void *dm_void, char input[][16], u32 *_used, char *output,
1525 		   u32 *_out_len)
1526 {
1527 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1528 	struct ccx_info *ccx = &dm->dm_ccx_info;
1529 	char help[] = "-h";
1530 	u32 var1[10] = {0};
1531 	u32 used = *_used;
1532 	u32 out_len = *_out_len;
1533 	struct clm_para_info clm_para = {0};
1534 	u32 i;
1535 
1536 	for (i = 0; i < 4; i++) {
1537 		PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
1538 	}
1539 
1540 	if ((strcmp(input[1], help) == 0)) {
1541 		PDM_SNPF(out_len, used, output + used, out_len - used,
1542 			 "CLM Driver Basic-Trigger 262ms: {1}\n");
1543 		PDM_SNPF(out_len, used, output + used, out_len - used,
1544 			 "CLM Driver Adv-Trigger: {2} {app} {LV} {0~262ms}\n");
1545 		PDM_SNPF(out_len, used, output + used, out_len - used,
1546 			 "CLM FW Trigger: {3} {1:drv, 2:fw}\n");
1547 		PDM_SNPF(out_len, used, output + used, out_len - used,
1548 			 "CLM Get Result: {100}\n");
1549 	} else if (var1[0] == 100) { /* @Get CLM results */
1550 
1551 		if (phydm_clm_get_result(dm))
1552 			phydm_clm_get_utility(dm);
1553 
1554 		PDM_SNPF(out_len, used, output + used, out_len - used,
1555 			 "clm_rpt_stamp=%d\n", ccx->clm_rpt_stamp);
1556 
1557 		PDM_SNPF(out_len, used, output + used, out_len - used,
1558 			 "clm_ratio:((%d percent)) = (%d us/ %d us)\n",
1559 			 ccx->clm_ratio, ccx->clm_result << 2,
1560 			 ccx->clm_period << 2);
1561 
1562 		ccx->clm_manual_ctrl = 0;
1563 	} else if (var1[0] == 3) {
1564 		phydm_set_clm_mntr_mode(dm, (enum clm_monitor_mode)var1[1]);
1565 		PDM_SNPF(out_len, used, output + used, out_len - used,
1566 			 "CLM mode: %s mode\n",
1567 			 ((ccx->clm_mntr_mode == CLM_FW_MNTR) ? "FW" : "Drv"));
1568 	} else { /* Set & trigger CLM */
1569 		ccx->clm_manual_ctrl = 1;
1570 
1571 		if (var1[0] == 1) {
1572 			clm_para.clm_app = CLM_BACKGROUND;
1573 			clm_para.clm_lv = CLM_LV_4;
1574 			clm_para.mntr_time = 262;
1575 			ccx->clm_mntr_mode = CLM_DRIVER_MNTR;
1576 		} else if (var1[0] == 2) {
1577 			clm_para.clm_app = (enum clm_application)var1[1];
1578 			clm_para.clm_lv = (enum phydm_clm_level)var1[2];
1579 			ccx->clm_mntr_mode = CLM_DRIVER_MNTR;
1580 			clm_para.mntr_time = (u16)var1[3];
1581 		}
1582 
1583 		PDM_SNPF(out_len, used, output + used, out_len - used,
1584 			 "app=%d, lv=%d, mode=%s, time=%d ms\n",
1585 			 clm_para.clm_app, clm_para.clm_lv,
1586 			 ((ccx->clm_mntr_mode == CLM_FW_MNTR) ? "FW" :
1587 			 "driver"), clm_para.mntr_time);
1588 
1589 		if (phydm_clm_mntr_set(dm, &clm_para))
1590 			phydm_clm_trigger(dm);
1591 
1592 		PDM_SNPF(out_len, used, output + used, out_len - used,
1593 			 "clm_rpt_stamp=%d\n", ccx->clm_rpt_stamp);
1594 	}
1595 
1596 	*_used = used;
1597 	*_out_len = out_len;
1598 }
1599 
1600 #endif /*@#ifdef CLM_SUPPORT*/
1601 
phydm_env_mntr_trigger(void * dm_void,struct nhm_para_info * nhm_para,struct clm_para_info * clm_para,struct env_trig_rpt * trig_rpt)1602 u8 phydm_env_mntr_trigger(void *dm_void, struct nhm_para_info *nhm_para,
1603 			  struct clm_para_info *clm_para,
1604 			  struct env_trig_rpt *trig_rpt)
1605 {
1606 	u8 trigger_result = 0;
1607 #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT))
1608 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1609 	struct ccx_info *ccx = &dm->dm_ccx_info;
1610 	boolean nhm_set_ok = false;
1611 	boolean clm_set_ok = false;
1612 
1613 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__);
1614 
1615 	/*@[NHM]*/
1616 	nhm_set_ok = phydm_nhm_mntr_set(dm, nhm_para);
1617 
1618 	/*@[CLM]*/
1619 	if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) {
1620 		clm_set_ok = phydm_clm_mntr_set(dm, clm_para);
1621 	} else if (ccx->clm_mntr_mode == CLM_FW_MNTR) {
1622 		phydm_clm_h2c(dm, CLM_PERIOD_MAX, true);
1623 		trigger_result |= CLM_SUCCESS;
1624 	}
1625 
1626 	if (nhm_set_ok) {
1627 		phydm_nhm_trigger(dm);
1628 		trigger_result |= NHM_SUCCESS;
1629 	}
1630 
1631 	if (clm_set_ok) {
1632 		phydm_clm_trigger(dm);
1633 		trigger_result |= CLM_SUCCESS;
1634 	}
1635 
1636 	/*@monitor for the test duration*/
1637 	ccx->start_time = odm_get_current_time(dm);
1638 
1639 	trig_rpt->nhm_rpt_stamp = ccx->nhm_rpt_stamp;
1640 	trig_rpt->clm_rpt_stamp = ccx->clm_rpt_stamp;
1641 
1642 	PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_rpt_stamp=%d, clm_rpt_stamp=%d,\n\n",
1643 		  trig_rpt->nhm_rpt_stamp, trig_rpt->clm_rpt_stamp);
1644 #endif
1645 	return trigger_result;
1646 }
1647 
phydm_env_mntr_result(void * dm_void,struct env_mntr_rpt * rpt)1648 u8 phydm_env_mntr_result(void *dm_void, struct env_mntr_rpt *rpt)
1649 {
1650 	u8 env_mntr_rpt = 0;
1651 #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT))
1652 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1653 	struct ccx_info *ccx = &dm->dm_ccx_info;
1654 	u64 progressing_time = 0;
1655 	u32 val_tmp = 0;
1656 
1657 	/*@monitor for the test duration*/
1658 	progressing_time = odm_get_progressing_time(dm, ccx->start_time);
1659 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__);
1660 	PHYDM_DBG(dm, DBG_ENV_MNTR, "env_time=%lld\n", progressing_time);
1661 
1662 	/*@Get NHM result*/
1663 	if (phydm_nhm_get_result(dm)) {
1664 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM_rpt success\n");
1665 		phydm_nhm_get_utility(dm);
1666 		rpt->nhm_ratio = ccx->nhm_ratio;
1667 		rpt->nhm_env_ratio = ccx->nhm_env_ratio;
1668 		rpt->nhm_noise_pwr = ccx->nhm_level;
1669 		rpt->nhm_pwr = ccx->nhm_pwr;
1670 		env_mntr_rpt |= NHM_SUCCESS;
1671 
1672 		odm_move_memory(dm, &rpt->nhm_result[0],
1673 				&ccx->nhm_result[0], NHM_RPT_NUM);
1674 	} else {
1675 		rpt->nhm_ratio = ENV_MNTR_FAIL;
1676 		rpt->nhm_env_ratio = ENV_MNTR_FAIL;
1677 	}
1678 
1679 	/*@Get CLM result*/
1680 	if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) {
1681 		if (phydm_clm_get_result(dm)) {
1682 			PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM_rpt success\n");
1683 			phydm_clm_get_utility(dm);
1684 			env_mntr_rpt |= CLM_SUCCESS;
1685 			rpt->clm_ratio = ccx->clm_ratio;
1686 		} else {
1687 			rpt->clm_ratio = ENV_MNTR_FAIL;
1688 		}
1689 
1690 	} else {
1691 		if (ccx->clm_fw_result_cnt != 0) {
1692 			val_tmp = ccx->clm_fw_result_acc
1693 			/ ccx->clm_fw_result_cnt;
1694 			ccx->clm_ratio = (u8)val_tmp;
1695 		} else {
1696 			ccx->clm_ratio = 0;
1697 		}
1698 
1699 		rpt->clm_ratio = ccx->clm_ratio;
1700 		PHYDM_DBG(dm, DBG_ENV_MNTR,
1701 			  "clm_fw_result_acc=%d, clm_fw_result_cnt=%d\n",
1702 			  ccx->clm_fw_result_acc, ccx->clm_fw_result_cnt);
1703 
1704 		ccx->clm_fw_result_acc = 0;
1705 		ccx->clm_fw_result_cnt = 0;
1706 		env_mntr_rpt |= CLM_SUCCESS;
1707 	}
1708 
1709 	rpt->nhm_rpt_stamp = ccx->nhm_rpt_stamp;
1710 	rpt->clm_rpt_stamp = ccx->clm_rpt_stamp;
1711 
1712 	PHYDM_DBG(dm, DBG_ENV_MNTR,
1713 		  "IGI=0x%x, nhm_ratio=%d, nhm_env_ratio=%d, clm_ratio=%d, nhm_rpt_stamp=%d, clm_rpt_stamp=%d\n\n",
1714 		  ccx->nhm_igi, rpt->nhm_ratio, rpt->nhm_env_ratio,
1715 		  rpt->clm_ratio, rpt->nhm_rpt_stamp, rpt->clm_rpt_stamp);
1716 #endif
1717 	return env_mntr_rpt;
1718 }
1719 
phydm_env_mntr_dbg(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)1720 void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used,
1721 			char *output, u32 *_out_len)
1722 {
1723 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1724 	char help[] = "-h";
1725 	u32 var1[10] = {0};
1726 	u32 used = *_used;
1727 	u32 out_len = *_out_len;
1728 	struct clm_para_info clm_para = {0};
1729 	struct nhm_para_info nhm_para = {0};
1730 	struct env_mntr_rpt rpt = {0};
1731 	struct env_trig_rpt trig_rpt = {0};
1732 	struct ccx_info *ccx = &dm->dm_ccx_info;
1733 	u8 set_result = 0;
1734 	u8 i = 0;
1735 
1736 	PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
1737 
1738 	if ((strcmp(input[1], help) == 0)) {
1739 		PDM_SNPF(out_len, used, output + used, out_len - used,
1740 			 "Basic-Trigger 262ms: {1}\n");
1741 		PDM_SNPF(out_len, used, output + used, out_len - used,
1742 			 "Get Result: {100}\n");
1743 	} else if (var1[0] == 100) { /* Get results */
1744 		set_result = phydm_env_mntr_result(dm, &rpt);
1745 
1746 		PDM_SNPF(out_len, used, output + used, out_len - used,
1747 			 "Set Result=%d\n nhm_ratio=%d nhm_env_ratio=%d clm_ratio=%d\n nhm_rpt_stamp=%d, clm_rpt_stamp=%d,\n",
1748 			 set_result, rpt.nhm_ratio, rpt.nhm_env_ratio,
1749 			 rpt.clm_ratio, rpt.nhm_rpt_stamp, rpt.clm_rpt_stamp);
1750 
1751 		for (i = 0; i <= 11; i++) {
1752 			PDM_SNPF(out_len, used, output + used, out_len - used,
1753 				 "nhm_rpt[%d] = %d (%d percent)\n", i,
1754 				 rpt.nhm_result[i],
1755 				 (((rpt.nhm_result[i] * 100) + 128) >> 8));
1756 		}
1757 		PDM_SNPF(out_len, used, output + used, out_len - used,
1758 			 "[NHM] valid: %d percent, noise(RSSI) = %d\n",
1759 			 ccx->nhm_level_valid, ccx->nhm_level);
1760 	} else { /* Set & trigger*/
1761 		/*nhm para*/
1762 		nhm_para.incld_txon = NHM_EXCLUDE_TXON;
1763 		nhm_para.incld_cca = NHM_EXCLUDE_CCA;
1764 		nhm_para.div_opt = NHM_CNT_ALL;
1765 		nhm_para.nhm_app = NHM_ACS;
1766 		nhm_para.nhm_lv = NHM_LV_2;
1767 		nhm_para.mntr_time = 262;
1768 		nhm_para.en_1db_mode = false;
1769 
1770 		/*clm para*/
1771 		clm_para.clm_app = CLM_ACS;
1772 		clm_para.clm_lv = CLM_LV_2;
1773 		clm_para.mntr_time = 262;
1774 
1775 		set_result = phydm_env_mntr_trigger(dm, &nhm_para,
1776 						    &clm_para, &trig_rpt);
1777 
1778 		PDM_SNPF(out_len, used, output + used, out_len - used,
1779 			 "Set Result=%d, nhm_rpt_stamp=%d, clm_rpt_stamp=%d\n",
1780 			 set_result, trig_rpt.nhm_rpt_stamp,
1781 			 trig_rpt.clm_rpt_stamp);
1782 	}
1783 
1784 	*_used = used;
1785 	*_out_len = out_len;
1786 }
1787 
1788 #ifdef FAHM_SUPPORT
1789 
phydm_fahm_racing_release(void * dm_void)1790 void phydm_fahm_racing_release(void *dm_void)
1791 {
1792 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1793 	struct ccx_info *ccx = &dm->dm_ccx_info;
1794 	u32 value32 = 0;
1795 
1796 	PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_racing_release : lv:(%d)->(0)\n",
1797 		  ccx->fahm_set_lv);
1798 
1799 	ccx->fahm_ongoing = false;
1800 	ccx->fahm_set_lv = FAHM_RELEASE;
1801 
1802 	if (!(ccx->fahm_app == FAHM_BACKGROUND || ccx->fahm_app == FAHM_ACS))
1803 		phydm_pause_func(dm, F00_DIG, PHYDM_RESUME,
1804 				 PHYDM_PAUSE_LEVEL_1, 1, &value32);
1805 
1806 	ccx->fahm_app = FAHM_BACKGROUND;
1807 }
1808 
phydm_fahm_racing_ctrl(void * dm_void,enum phydm_fahm_level lv)1809 u8 phydm_fahm_racing_ctrl(void *dm_void, enum phydm_fahm_level lv)
1810 {
1811 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1812 	struct ccx_info *ccx = &dm->dm_ccx_info;
1813 	u8 set_result = PHYDM_SET_SUCCESS;
1814 	/*acquire to control FAHM API*/
1815 
1816 	PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_ongoing=%d, lv:(%d)->(%d)\n",
1817 		  ccx->fahm_ongoing, ccx->fahm_set_lv, lv);
1818 	if (ccx->fahm_ongoing) {
1819 		if (lv <= ccx->fahm_set_lv) {
1820 			set_result = PHYDM_SET_FAIL;
1821 		} else {
1822 			phydm_ccx_hw_restart(dm);
1823 			ccx->fahm_ongoing = false;
1824 		}
1825 	}
1826 
1827 	if (set_result)
1828 		ccx->fahm_set_lv = lv;
1829 
1830 	PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm racing success=%d\n", set_result);
1831 	return set_result;
1832 }
1833 
phydm_fahm_trigger(void * dm_void)1834 void phydm_fahm_trigger(void *dm_void)
1835 { /*@unit (4us)*/
1836 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1837 	struct ccx_info *ccx = &dm->dm_ccx_info;
1838 	u32 reg = 0;
1839 
1840 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
1841 
1842 	switch (dm->ic_ip_series) {
1843 	case PHYDM_IC_JGR3:
1844 		reg = R_0x1e60;
1845 		break;
1846 	case PHYDM_IC_AC:
1847 		reg = R_0x994;
1848 		break;
1849 	case PHYDM_IC_N:
1850 		reg = R_0x890;
1851 		break;
1852 	default:
1853 		break;
1854 	}
1855 
1856 	odm_set_bb_reg(dm, reg, BIT(2), 0);
1857 	odm_set_bb_reg(dm, reg, BIT(2), 1);
1858 
1859 	ccx->fahm_trigger_time = dm->phydm_sys_up_time;
1860 	ccx->fahm_rpt_stamp++;
1861 	ccx->fahm_ongoing = true;
1862 }
1863 
1864 boolean
phydm_fahm_check_rdy(void * dm_void)1865 phydm_fahm_check_rdy(void *dm_void)
1866 {
1867 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1868 	boolean is_ready = false;
1869 	u32 reg = 0, reg_bit = 0;
1870 
1871 	switch (dm->ic_ip_series) {
1872 	case PHYDM_IC_JGR3:
1873 		reg = R_0x2d84;
1874 		reg_bit = 31;
1875 		break;
1876 	case PHYDM_IC_AC:
1877 		reg = R_0x1f98;
1878 		reg_bit = 31;
1879 		break;
1880 	case PHYDM_IC_N:
1881 		reg = R_0x9f0;
1882 		reg_bit = 31;
1883 		break;
1884 	default:
1885 		break;
1886 	}
1887 
1888 	if (odm_get_bb_reg(dm, reg, BIT(reg_bit)))
1889 		is_ready = true;
1890 
1891 	PHYDM_DBG(dm, DBG_ENV_MNTR, "FAHM rdy=%d\n", is_ready);
1892 
1893 	return is_ready;
1894 }
1895 
phydm_fahm_cal_wgt_avg(void * dm_void,u8 start_i,u8 end_i,u16 r_sum,u16 period)1896 u8 phydm_fahm_cal_wgt_avg(void *dm_void, u8 start_i, u8 end_i, u16 r_sum,
1897 			  u16 period)
1898 {
1899 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1900 	struct ccx_info *ccx = &dm->dm_ccx_info;
1901 	u8 i = 0;
1902 	u32 pwr_tmp = 0;
1903 	u8 pwr = 0;
1904 	u32 fahm_valid = 0;
1905 
1906 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
1907 
1908 	if (r_sum == 0) {
1909 		PHYDM_DBG(dm, DBG_ENV_MNTR,
1910 			  "rpt_sum = 0, don't need to update\n");
1911 		return 0x0;
1912 	} else if (end_i > FAHM_RPT_NUM - 1) {
1913 		PHYDM_DBG(dm, DBG_ENV_MNTR,
1914 			  "[WARNING]end_i is larger than 11!!\n");
1915 		return 0x0;
1916 	}
1917 
1918 	for (i = start_i; i <= end_i; i++) {
1919 		if (i == 0)
1920 			pwr_tmp += ccx->fahm_result[0] *
1921 				   MAX_2(ccx->fahm_th[0] - 2, 0);
1922 		else if (i == (FAHM_RPT_NUM - 1))
1923 			pwr_tmp += ccx->fahm_result[FAHM_RPT_NUM - 1] *
1924 				   (ccx->fahm_th[FAHM_TH_NUM - 1] + 2);
1925 		else
1926 			pwr_tmp += ccx->fahm_result[i] *
1927 				   (ccx->fahm_th[i - 1] + ccx->fahm_th[i]) >> 1;
1928 	}
1929 
1930 	/* protection for the case of minus pwr(RSSI)*/
1931 	pwr = (u8)(NTH_TH_2_RSSI(MAX_2(PHYDM_DIV(pwr_tmp, r_sum), 20)));
1932 	fahm_valid = PHYDM_DIV(r_sum * 100, period);
1933 	PHYDM_DBG(dm, DBG_ENV_MNTR,
1934 		  "valid: ((%d)) percent, pwr(RSSI)=((%d))\n",
1935 		  fahm_valid, pwr);
1936 
1937 	return pwr;
1938 }
1939 
phydm_fahm_get_utility(void * dm_void)1940 void phydm_fahm_get_utility(void *dm_void)
1941 {
1942 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1943 	struct ccx_info *ccx = &dm->dm_ccx_info;
1944 
1945 	if (ccx->fahm_result_sum >= ccx->fahm_result[0]) {
1946 		ccx->fahm_pwr = phydm_fahm_cal_wgt_avg(dm, 0, FAHM_RPT_NUM - 1,
1947 						       ccx->fahm_result_sum,
1948 						       ccx->fahm_period);
1949 		ccx->fahm_ratio = phydm_ccx_get_rpt_ratio(dm,
1950 				  ccx->fahm_result_sum, ccx->fahm_period);
1951 		ccx->fahm_denom_ratio = phydm_ccx_get_rpt_ratio(dm,
1952 					ccx->fahm_denom_result,
1953 					ccx->fahm_period);
1954 	} else {
1955 		PHYDM_DBG(dm, DBG_ENV_MNTR,
1956 			  "[warning] fahm_result_sum invalid\n");
1957 		ccx->fahm_pwr = 0;
1958 		ccx->fahm_ratio = 0;
1959 		ccx->fahm_denom_ratio = 0;
1960 	}
1961 
1962 	PHYDM_DBG(dm, DBG_ENV_MNTR,
1963 		  "fahm_pwr=%d, fahm_ratio=%d, fahm_denom_ratio=%d\n",
1964 		  ccx->fahm_pwr, ccx->fahm_ratio, ccx->fahm_denom_ratio);
1965 }
1966 
1967 boolean
phydm_fahm_get_result(void * dm_void)1968 phydm_fahm_get_result(void *dm_void)
1969 {
1970 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1971 	struct ccx_info *ccx = &dm->dm_ccx_info;
1972 	u32 value32 = 0;
1973 	u32 reg1 = 0;
1974 	u32 reg2 = 0;
1975 	u8 i = 0;
1976 	u32 fahm_rpt_sum_tmp = 0;
1977 
1978 	switch (dm->ic_ip_series) {
1979 	case PHYDM_IC_JGR3:
1980 		reg1 = R_0x2d6c;
1981 		reg2 = R_0x2d84;
1982 		break;
1983 	case PHYDM_IC_AC:
1984 		reg1 = R_0x1f80;
1985 		reg2 = R_0x1f98;
1986 		break;
1987 	case PHYDM_IC_N:
1988 		reg1 = R_0x9d8;
1989 		reg2 = R_0x9f0;
1990 		break;
1991 	default:
1992 		break;
1993 	}
1994 
1995 	if (!(phydm_fahm_check_rdy(dm))) {
1996 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Get FAHM report Fail\n");
1997 		phydm_fahm_racing_release(dm);
1998 		return false;
1999 	}
2000 
2001 	/*Get FAHM numerator and sum all fahm_result*/
2002 	for (i = 0; i < 6; i++) {
2003 		value32 = odm_get_bb_reg(dm, reg1 + (i << 2), MASKDWORD);
2004 		ccx->fahm_result[i * 2] = (u16)(value32 & MASKLWORD);
2005 		ccx->fahm_result[i * 2 + 1] = (u16)((value32 & MASKHWORD) >> 16);
2006 		fahm_rpt_sum_tmp = (u32)(fahm_rpt_sum_tmp +
2007 					 ccx->fahm_result[i * 2] +
2008 					 ccx->fahm_result[i * 2 + 1]);
2009 	}
2010 	ccx->fahm_result_sum = (u16)fahm_rpt_sum_tmp;
2011 
2012 	/*Get FAHM Denominator*/
2013 	ccx->fahm_denom_result = (u16)odm_get_bb_reg(dm, reg2, MASKLWORD);
2014 
2015 	if (!(ccx->fahm_inclu_cck))
2016 		PHYDM_DBG(dm, DBG_ENV_MNTR,
2017 			  "===>The following fahm report does not count CCK pkt\n");
2018 
2019 	PHYDM_DBG(dm, DBG_ENV_MNTR,
2020 		  "fahm_result_sum=%d, fahm_denom_result = %d\n",
2021 		  ccx->fahm_result_sum, ccx->fahm_denom_result);
2022 
2023 	PHYDM_DBG(dm, DBG_ENV_MNTR,
2024 		  "FAHM_Rpt[%d](H->L)[%d %d %d %d %d %d %d %d %d %d %d %d]\n",
2025 		  ccx->fahm_rpt_stamp, ccx->fahm_result[11],
2026 		  ccx->fahm_result[10], ccx->fahm_result[9],
2027 		  ccx->fahm_result[8], ccx->fahm_result[7], ccx->fahm_result[6],
2028 		  ccx->fahm_result[5], ccx->fahm_result[4], ccx->fahm_result[3],
2029 		  ccx->fahm_result[2], ccx->fahm_result[1],
2030 		  ccx->fahm_result[0]);
2031 
2032 	phydm_fahm_racing_release(dm);
2033 
2034 	if (fahm_rpt_sum_tmp > 0xffff) {
2035 		PHYDM_DBG(dm, DBG_ENV_MNTR,
2036 			  "[Warning] Invalid FAHM RPT, total=%d\n",
2037 			  fahm_rpt_sum_tmp);
2038 		return false;
2039 	}
2040 
2041 	return true;
2042 }
2043 
phydm_fahm_set_th_reg(void * dm_void)2044 void phydm_fahm_set_th_reg(void *dm_void)
2045 {
2046 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2047 	struct ccx_info *ccx = &dm->dm_ccx_info;
2048 	u32 val = 0;
2049 
2050 	/*Set FAHM threshold*/ /*Unit: PWdB U(8,1)*/
2051 	switch (dm->ic_ip_series) {
2052 	case PHYDM_IC_JGR3:
2053 		val = BYTE_2_DWORD(ccx->fahm_th[3], ccx->fahm_th[2],
2054 				   ccx->fahm_th[1], ccx->fahm_th[0]);
2055 		odm_set_bb_reg(dm, R_0x1e50, MASKDWORD, val);
2056 		val = BYTE_2_DWORD(ccx->fahm_th[7], ccx->fahm_th[6],
2057 				   ccx->fahm_th[5], ccx->fahm_th[4]);
2058 		odm_set_bb_reg(dm, R_0x1e54, MASKDWORD, val);
2059 		val = BYTE_2_DWORD(0, ccx->fahm_th[10], ccx->fahm_th[9],
2060 				   ccx->fahm_th[8]);
2061 		odm_set_bb_reg(dm, R_0x1e58, 0xffffff, val);
2062 		break;
2063 	case PHYDM_IC_AC:
2064 		val = BYTE_2_DWORD(0, ccx->fahm_th[2], ccx->fahm_th[1],
2065 				   ccx->fahm_th[0]);
2066 		odm_set_bb_reg(dm, R_0x1c38, 0xffffff00, val);
2067 		val = BYTE_2_DWORD(0, ccx->fahm_th[5], ccx->fahm_th[4],
2068 				   ccx->fahm_th[3]);
2069 		odm_set_bb_reg(dm, R_0x1c78, 0xffffff00, val);
2070 		val = BYTE_2_DWORD(0, 0, ccx->fahm_th[7], ccx->fahm_th[6]);
2071 		odm_set_bb_reg(dm, R_0x1c7c, 0xffff0000, val);
2072 		val = BYTE_2_DWORD(0, ccx->fahm_th[10], ccx->fahm_th[9],
2073 				   ccx->fahm_th[8]);
2074 		odm_set_bb_reg(dm, R_0x1cb8, 0xffffff00, val);
2075 		break;
2076 	case PHYDM_IC_N:
2077 		val = BYTE_2_DWORD(ccx->fahm_th[3], ccx->fahm_th[2],
2078 				   ccx->fahm_th[1], ccx->fahm_th[0]);
2079 		odm_set_bb_reg(dm, R_0x970, MASKDWORD, val);
2080 		val = BYTE_2_DWORD(ccx->fahm_th[7], ccx->fahm_th[6],
2081 				   ccx->fahm_th[5], ccx->fahm_th[4]);
2082 		odm_set_bb_reg(dm, R_0x974, MASKDWORD, val);
2083 		val = BYTE_2_DWORD(0, ccx->fahm_th[10], ccx->fahm_th[9],
2084 				   ccx->fahm_th[8]);
2085 		odm_set_bb_reg(dm, R_0x978, 0xffffff, val);
2086 		break;
2087 	default:
2088 		break;
2089 	}
2090 
2091 	PHYDM_DBG(dm, DBG_ENV_MNTR,
2092 		  "Update FAHM_th[H->L]=[%d %d %d %d %d %d %d %d %d %d %d]\n",
2093 		  ccx->fahm_th[10], ccx->fahm_th[9], ccx->fahm_th[8],
2094 		  ccx->fahm_th[7], ccx->fahm_th[6], ccx->fahm_th[5],
2095 		  ccx->fahm_th[4], ccx->fahm_th[3], ccx->fahm_th[2],
2096 		  ccx->fahm_th[1], ccx->fahm_th[0]);
2097 }
2098 
2099 boolean
phydm_fahm_th_update_chk(void * dm_void,enum fahm_application fahm_app,u8 * fahm_th,u32 * igi_new,boolean en_1db_mode,u8 fahm_th0_manual)2100 phydm_fahm_th_update_chk(void *dm_void, enum fahm_application fahm_app,
2101 			 u8 *fahm_th, u32 *igi_new, boolean en_1db_mode,
2102 			 u8 fahm_th0_manual)
2103 {
2104 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2105 	struct ccx_info *ccx = &dm->dm_ccx_info;
2106 	boolean is_update = false;
2107 	u8 igi_curr = phydm_get_igi(dm, BB_PATH_A);
2108 	u8 i = 0;
2109 	u8 th_tmp = igi_curr - CCA_CAP;
2110 	u8 th_step = 2;
2111 	u8 fahm_igi_th_11k[NHM_TH_NUM] = {0x12, 0x15, 0x18, 0x1b, 0x1e, 0x23,
2112 					  0x28, 0x2d, 0x32, 0x37, 0x3c};
2113 	/*11k_dbm : {-92, -89, -86, -83, -80, -75, -70, -65, -60, -55, -50};*/
2114 	/*11k_gain_idx : {18, 21, 24, 27, 30, 35, 40, 45, 50, 55, 60};*/
2115 
2116 	PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_th_update_chk : App=%d, fahm_igi=0x%x, igi_curr=0x%x\n",
2117 		  fahm_app, ccx->fahm_igi, igi_curr);
2118 
2119 	if (igi_curr < 0x10) /* Protect for invalid IGI*/
2120 		return false;
2121 
2122 	switch (fahm_app) {
2123 	case FAHM_BACKGROUND: /*Get IGI from driver parameter(cur_ig_value)*/
2124 		if (ccx->fahm_igi != igi_curr || ccx->fahm_app != fahm_app) {
2125 			is_update = true;
2126 			*igi_new = (u32)igi_curr;
2127 
2128 			fahm_th[0] = (u8)IGI_2_NHM_TH(th_tmp);
2129 
2130 			for (i = 1; i <= 10; i++)
2131 				fahm_th[i] = fahm_th[0] +
2132 					    IGI_2_NHM_TH(th_step * i);
2133 
2134 		}
2135 		break;
2136 	case FAHM_ACS:
2137 		if (ccx->fahm_igi != igi_curr || ccx->fahm_app != fahm_app) {
2138 			is_update = true;
2139 			*igi_new = (u32)igi_curr;
2140 			for (i = 0; i < FAHM_TH_NUM; i++)
2141 				fahm_th[i] = IGI_2_NHM_TH(fahm_igi_th_11k[i]);
2142 		}
2143 		break;
2144 	case FAHM_DBG: /*Get IGI from register*/
2145 		igi_curr = phydm_get_igi(dm, BB_PATH_A);
2146 		if (ccx->fahm_igi != igi_curr || ccx->fahm_app != fahm_app) {
2147 			is_update = true;
2148 			*igi_new = (u32)igi_curr;
2149 			if (en_1db_mode) {
2150 				fahm_th[0] = (u8)IGI_2_NHM_TH(fahm_th0_manual +
2151 							      10);
2152 				th_step = 1;
2153 			} else {
2154 				fahm_th[0] = (u8)IGI_2_NHM_TH(igi_curr -
2155 							      CCA_CAP);
2156 			}
2157 
2158 			for (i = 1; i <= 10; i++)
2159 				fahm_th[i] = fahm_th[0] +
2160 					     IGI_2_NHM_TH(th_step * i);
2161 		}
2162 		break;
2163 	}
2164 
2165 	if (is_update) {
2166 		PHYDM_DBG(dm, DBG_ENV_MNTR, "[Update FAHM_TH] igi_RSSI=%d\n",
2167 			  IGI_2_RSSI(*igi_new));
2168 
2169 		for (i = 0; i < FAHM_TH_NUM; i++)
2170 			PHYDM_DBG(dm, DBG_ENV_MNTR, "FAHM_th[%d](RSSI) = %d\n",
2171 				  i, NTH_TH_2_RSSI(fahm_th[i]));
2172 	} else {
2173 		PHYDM_DBG(dm, DBG_ENV_MNTR, "No need to update FAHM_TH\n");
2174 	}
2175 	return is_update;
2176 }
2177 
phydm_fahm_set(void * dm_void,u8 numer_opt,u8 denom_opt,enum fahm_application app,u16 period,boolean en_1db_mode,u8 th0_manual)2178 void phydm_fahm_set(void *dm_void, u8 numer_opt, u8 denom_opt,
2179 		    enum fahm_application app, u16 period, boolean en_1db_mode,
2180 		    u8 th0_manual)
2181 {
2182 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2183 	struct ccx_info *ccx = &dm->dm_ccx_info;
2184 	u8 fahm_th[FAHM_TH_NUM] = {0};
2185 	u32 igi = 0x20;
2186 	u32 reg1 = 0, reg2 = 0, reg3 = 0;
2187 	u32 val_tmp = 0;
2188 
2189 	PHYDM_DBG(dm, DBG_ENV_MNTR, "numer_opt=%d, denom_opt=%d, period=%d\n",
2190 		  numer_opt, denom_opt, period);
2191 
2192 	switch (dm->ic_ip_series) {
2193 	case PHYDM_IC_JGR3:
2194 		reg1 = R_0x1e60;
2195 		reg2 = R_0x1e58;
2196 		reg3 = R_0x1e5c;
2197 		break;
2198 	case PHYDM_IC_AC:
2199 		reg1 = R_0x994;
2200 		reg2 = R_0x1cf8;
2201 		break;
2202 	case PHYDM_IC_N:
2203 		reg1 = R_0x890;
2204 		reg2 = R_0x978;
2205 		reg3 = R_0x97c;
2206 		break;
2207 	default:
2208 		 break;
2209 	}
2210 
2211 	/*Set enable fa, ignore crc32 ok, ignore crc32 err*/
2212 	if (numer_opt != ccx->fahm_numer_opt ||
2213 	    denom_opt != ccx->fahm_denom_opt) {
2214 		odm_set_bb_reg(dm, reg1, 0xe0, numer_opt);
2215 		odm_set_bb_reg(dm, reg1, 0x7000, denom_opt);
2216 		ccx->fahm_numer_opt = numer_opt;
2217 		ccx->fahm_denom_opt = denom_opt;
2218 
2219 		/*[PHYDM-400]*/
2220 		/*Counting B mode pkt for new B mode IP or fahm_opt is non-FA*/
2221 		if ((dm->support_ic_type & ODM_RTL8723F) ||
2222 		    (((numer_opt | denom_opt) & FAHM_INCLU_FA) == 0))
2223 			ccx->fahm_inclu_cck = true;
2224 		else
2225 			ccx->fahm_inclu_cck = false;
2226 
2227 		odm_set_bb_reg(dm, reg1, BIT(4), ccx->fahm_inclu_cck);
2228 		PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_inclu_cck=%d\n",
2229 			  ccx->fahm_inclu_cck);
2230 	}
2231 
2232 	/*Set FAHM period*/
2233 	if (period != ccx->fahm_period) {
2234 		switch (dm->ic_ip_series) {
2235 		case PHYDM_IC_AC:
2236 			odm_set_bb_reg(dm, reg2, 0xffff00, period);
2237 			break;
2238 		case PHYDM_IC_JGR3:
2239 		case PHYDM_IC_N:
2240 			odm_set_bb_reg(dm, reg2, 0xff000000, (period & 0xff));
2241 			odm_set_bb_reg(dm, reg3, 0xff, (period & 0xff00) >> 8);
2242 			break;
2243 		default:
2244 			break;
2245 		}
2246 
2247 		PHYDM_DBG(dm, DBG_ENV_MNTR,
2248 			  "Update FAHM period ((%d)) -> ((%d))\n",
2249 			  ccx->fahm_period, period);
2250 
2251 		ccx->fahm_period = period;
2252 	}
2253 
2254 	/*Set FAHM threshold*/
2255 	if (phydm_fahm_th_update_chk(dm, app, &fahm_th[0], &igi, en_1db_mode,
2256 				     th0_manual)) {
2257 		/*Pause IGI*/
2258 		if (app == FAHM_BACKGROUND || app == FAHM_ACS) {
2259 			PHYDM_DBG(dm, DBG_ENV_MNTR, "DIG Free Run\n");
2260 		} else if (phydm_pause_func(dm, F00_DIG, PHYDM_PAUSE,
2261 					    PHYDM_PAUSE_LEVEL_1, 1, &igi)
2262 					    == PAUSE_FAIL) {
2263 			PHYDM_DBG(dm, DBG_ENV_MNTR, "pause DIG Fail\n");
2264 			return;
2265 		} else {
2266 			PHYDM_DBG(dm, DBG_ENV_MNTR, "pause DIG=0x%x\n", igi);
2267 		}
2268 		ccx->fahm_app = app;
2269 		ccx->fahm_igi = (u8)igi;
2270 		odm_move_memory(dm, &ccx->fahm_th[0], &fahm_th, FAHM_TH_NUM);
2271 
2272 		/*Set FAHM th*/
2273 		phydm_fahm_set_th_reg(dm);
2274 	}
2275 }
2276 
2277 boolean
phydm_fahm_mntr_set(void * dm_void,struct fahm_para_info * para)2278 phydm_fahm_mntr_set(void *dm_void, struct fahm_para_info *para)
2279 {
2280 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2281 	u16 fahm_time = 0; /*unit: 4us*/
2282 
2283 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2284 
2285 	if (para->mntr_time == 0)
2286 		return false;
2287 
2288 	if (para->lv >= FAHM_MAX_NUM) {
2289 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Wrong LV=%d\n", para->lv);
2290 		return false;
2291 	}
2292 
2293 	if (phydm_fahm_racing_ctrl(dm, para->lv) == PHYDM_SET_FAIL)
2294 		return false;
2295 
2296 	if (para->mntr_time >= 262)
2297 		fahm_time = FAHM_PERIOD_MAX;
2298 	else
2299 		fahm_time = para->mntr_time * MS_TO_4US_RATIO;
2300 
2301 	phydm_fahm_set(dm, para->numer_opt, para->denom_opt, para->app,
2302 		       fahm_time, para->en_1db_mode, para->th0_manual);
2303 
2304 	return true;
2305 }
2306 
2307 boolean
phydm_fahm_mntr_racing_chk(void * dm_void)2308 phydm_fahm_mntr_racing_chk(void *dm_void)
2309 {
2310 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2311 	struct ccx_info *ccx = &dm->dm_ccx_info;
2312 	u32 sys_return_time = 0;
2313 
2314 	if (ccx->fahm_manual_ctrl) {
2315 		PHYDM_DBG(dm, DBG_ENV_MNTR, "FAHM in manual ctrl\n");
2316 		return true;
2317 	}
2318 
2319 	sys_return_time = ccx->fahm_trigger_time + MAX_ENV_MNTR_TIME;
2320 
2321 	if (ccx->fahm_app != FAHM_BACKGROUND &&
2322 	    (sys_return_time > dm->phydm_sys_up_time)) {
2323 		PHYDM_DBG(dm, DBG_ENV_MNTR,
2324 			  "fahm_app=%d, trigger_time %d, sys_time=%d\n",
2325 			  ccx->fahm_app, ccx->fahm_trigger_time,
2326 			  dm->phydm_sys_up_time);
2327 
2328 		return true;
2329 	}
2330 
2331 	return false;
2332 }
2333 
2334 boolean
phydm_fahm_mntr_chk(void * dm_void,u16 monitor_time)2335 phydm_fahm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/)
2336 {
2337 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2338 	struct ccx_info *ccx = &dm->dm_ccx_info;
2339 	struct fahm_para_info para = {0};
2340 	boolean fahm_chk_result = false;
2341 
2342 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2343 
2344 	if (phydm_fahm_mntr_racing_chk(dm))
2345 		return fahm_chk_result;
2346 
2347 	/*[FAHM trigger setting]------------------------------------------*/
2348 	para.numer_opt = FAHM_INCLU_FA;
2349 	para.denom_opt = FAHM_INCLU_CRC_ERR;
2350 	para.app = FAHM_BACKGROUND;
2351 	para.lv = FAHM_LV_1;
2352 	para.en_1db_mode = false;
2353 	para.mntr_time = monitor_time;
2354 
2355 	fahm_chk_result = phydm_fahm_mntr_set(dm, &para);
2356 
2357 	return fahm_chk_result;
2358 }
2359 
2360 boolean
phydm_fahm_mntr_result(void * dm_void)2361 phydm_fahm_mntr_result(void *dm_void)
2362 {
2363 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2364 	struct ccx_info *ccx = &dm->dm_ccx_info;
2365 	boolean fahm_chk_result = false;
2366 
2367 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2368 
2369 	if (phydm_fahm_mntr_racing_chk(dm))
2370 		return fahm_chk_result;
2371 
2372 	/*[FAHM get result & calculate Utility]---------------------------*/
2373 	if (phydm_fahm_get_result(dm)) {
2374 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Get FAHM_rpt success\n");
2375 		phydm_fahm_get_utility(dm);
2376 		fahm_chk_result = true;
2377 	}
2378 
2379 	return fahm_chk_result;
2380 }
2381 
phydm_fahm_init(void * dm_void)2382 void phydm_fahm_init(void *dm_void)
2383 {
2384 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2385 	struct ccx_info *ccx = &dm->dm_ccx_info;
2386 	u32 reg = 0;
2387 
2388 	if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM))
2389 		return;
2390 
2391 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2392 
2393 	ccx->fahm_app = FAHM_BACKGROUND;
2394 	ccx->fahm_igi = 0xff;
2395 
2396 	/*Set FAHM threshold*/
2397 	ccx->fahm_ongoing = false;
2398 	ccx->fahm_set_lv = FAHM_RELEASE;
2399 
2400 	if (phydm_fahm_th_update_chk(dm, ccx->fahm_app, &ccx->fahm_th[0],
2401 				    (u32 *)&ccx->fahm_igi, false, 0))
2402 		phydm_fahm_set_th_reg(dm);
2403 
2404 	ccx->fahm_period = 0;
2405 	ccx->fahm_numer_opt = 0;
2406 	ccx->fahm_denom_opt = 0;
2407 	ccx->fahm_manual_ctrl = 0;
2408 	ccx->fahm_rpt_stamp = 0;
2409 	ccx->fahm_inclu_cck = false;
2410 
2411 	switch (dm->ic_ip_series) {
2412 	case PHYDM_IC_JGR3:
2413 		reg = R_0x1e60;
2414 		break;
2415 	case PHYDM_IC_AC:
2416 		reg = R_0x994;
2417 		break;
2418 	case PHYDM_IC_N:
2419 		reg = R_0x890;
2420 		break;
2421 	default:
2422 		break;
2423 	}
2424 
2425 	/*Counting OFDM pkt*/
2426 	odm_set_bb_reg(dm, reg, BIT(3), 1);
2427 }
2428 
phydm_fahm_dbg(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)2429 void phydm_fahm_dbg(void *dm_void, char input[][16], u32 *_used, char *output,
2430 		    u32 *_out_len)
2431 {
2432 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2433 	struct ccx_info *ccx = &dm->dm_ccx_info;
2434 	struct fahm_para_info para = {0};
2435 	char help[] = "-h";
2436 	u32 var1[10] = {0};
2437 	u32 used = *_used;
2438 	u32 out_len = *_out_len;
2439 	u16 result_tmp = 0;
2440 	u8 i = 0;
2441 
2442 	if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM))
2443 		return;
2444 
2445 	PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
2446 
2447 	if ((strcmp(input[1], help) == 0)) {
2448 		PDM_SNPF(out_len, used, output + used, out_len - used,
2449 			 "FAHM Basic-Trigger 262ms: {1}\n");
2450 		PDM_SNPF(out_len, used, output + used, out_len - used,
2451 			 "FAHM Adv-Trigger: {2} {numer_opt} {denom_opt}\n {App:1 for dbg} {LV:1~4} {0~262ms}, 1dB mode :{en} {t[0](RSSI)}\n");
2452 		PDM_SNPF(out_len, used, output + used, out_len - used,
2453 			 "FAHM Get Result: {100}\n");
2454 		PDM_SNPF(out_len, used, output + used, out_len - used,
2455 			 "numer_opt/denom_opt: {BIT 0/1/2} = {FA/CRC32_OK/CRC32_ERR}\n");
2456 	} else if (var1[0] == 100) { /*Get FAHM results*/
2457 		PDM_SNPF(out_len, used, output + used, out_len - used,
2458 			 "IGI=0x%x, rpt_stamp=%d\n", ccx->fahm_igi,
2459 			 ccx->fahm_rpt_stamp);
2460 
2461 		if (phydm_fahm_get_result(dm)) {
2462 			if (!(ccx->fahm_inclu_cck))
2463 				PDM_SNPF(out_len, used, output + used,
2464 					 out_len - used,
2465 					 "===>The following fahm report does not count CCK pkt\n");
2466 
2467 			for (i = 0; i < FAHM_RPT_NUM; i++) {
2468 				result_tmp = ccx->fahm_result[i];
2469 				PDM_SNPF(out_len, used, output + used,
2470 					 out_len - used,
2471 					 "fahm_rpt[%d] = %d (%d percent)\n",
2472 					 i, result_tmp,
2473 					 (((result_tmp * 100) + 32768) >> 16));
2474 			}
2475 			phydm_fahm_get_utility(dm);
2476 
2477 			PDM_SNPF(out_len, used, output + used, out_len - used,
2478 				 "fahm_pwr=%d, fahm_ratio=%d, fahm_denom_ratio=%d\n",
2479 				 ccx->fahm_pwr, ccx->fahm_ratio,
2480 				 ccx->fahm_denom_ratio);
2481 		} else {
2482 			PDM_SNPF(out_len, used, output + used, out_len - used,
2483 				 "Get FAHM_rpt Fail\n");
2484 		}
2485 		ccx->fahm_manual_ctrl = 0;
2486 	} else { /*FAMH trigger*/
2487 		ccx->fahm_manual_ctrl = 1;
2488 
2489 		for (i = 1; i < 9; i++)
2490 			PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
2491 
2492 		if (var1[0] == 1) {
2493 			para.numer_opt = FAHM_INCLU_FA;
2494 			para.denom_opt = FAHM_INCLU_CRC_ERR;
2495 			para.app = FAHM_DBG;
2496 			para.lv = FAHM_LV_4;
2497 			para.mntr_time = 262;
2498 			para.en_1db_mode = false;
2499 			para.th0_manual = 0;
2500 		} else {
2501 			para.numer_opt = (u8)var1[1];
2502 			para.denom_opt = (u8)var1[2];
2503 			para.app = (enum fahm_application)var1[3];
2504 			para.lv = (enum phydm_fahm_level)var1[4];
2505 			para.mntr_time = (u16)var1[5];
2506 			para.en_1db_mode = (boolean)var1[6];
2507 			para.th0_manual = (u8)var1[7];
2508 		}
2509 
2510 		PDM_SNPF(out_len, used, output + used, out_len - used,
2511 			 "numer_opt=%d, denom_opt=%d, app=%d, lv=%d, time=%d ms\n",
2512 			 para.numer_opt, para.denom_opt,para.app, para.lv,
2513 			 para.mntr_time);
2514 
2515 		PDM_SNPF(out_len, used, output + used, out_len - used,
2516 			 "en_1db_mode=%d, th0(for 1db mode)=%d\n",
2517 			 para.en_1db_mode, para.th0_manual);
2518 
2519 		if (phydm_fahm_mntr_set(dm, &para))
2520 			phydm_fahm_trigger(dm);
2521 
2522 		PDM_SNPF(out_len, used, output + used, out_len - used,
2523 			 "IGI=0x%x, rpt_stamp=%d\n", ccx->fahm_igi,
2524 			 ccx->fahm_rpt_stamp);
2525 
2526 		for (i = 0; i < FAHM_TH_NUM; i++)
2527 			PDM_SNPF(out_len, used, output + used, out_len - used,
2528 				 "FAHM_th[%d] RSSI = %d\n", i,
2529 				 NTH_TH_2_RSSI(ccx->fahm_th[i]));
2530 	}
2531 
2532 	*_used = used;
2533 	*_out_len = out_len;
2534 }
2535 
2536 #endif /*#ifdef FAHM_SUPPORT*/
2537 
2538 #ifdef IFS_CLM_SUPPORT
phydm_ifs_clm_restart(void * dm_void)2539 void phydm_ifs_clm_restart(void *dm_void)
2540 {
2541 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2542 
2543 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2544 
2545 	/*restart IFS_CLM*/
2546 	odm_set_bb_reg(dm, R_0x1ee4, BIT(29), 0x0);
2547 	odm_set_bb_reg(dm, R_0x1ee4, BIT(29), 0x1);
2548 }
2549 
phydm_ifs_clm_racing_release(void * dm_void)2550 void phydm_ifs_clm_racing_release(void *dm_void)
2551 {
2552 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2553 	struct ccx_info *ccx = &dm->dm_ccx_info;
2554 
2555 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2556 	PHYDM_DBG(dm, DBG_ENV_MNTR, "ifs clm lv:(%d)->(0)\n",
2557 		  ccx->ifs_clm_set_lv);
2558 
2559 	ccx->ifs_clm_ongoing = false;
2560 	ccx->ifs_clm_set_lv = IFS_CLM_RELEASE;
2561 	ccx->ifs_clm_app = IFS_CLM_BACKGROUND;
2562 }
2563 
phydm_ifs_clm_racing_ctrl(void * dm_void,enum phydm_ifs_clm_level ifs_clm_lv)2564 u8 phydm_ifs_clm_racing_ctrl(void *dm_void, enum phydm_ifs_clm_level ifs_clm_lv)
2565 {
2566 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2567 	struct ccx_info *ccx = &dm->dm_ccx_info;
2568 	u8 set_result = PHYDM_SET_SUCCESS;
2569 	/*acquire to control IFS CLM API*/
2570 
2571 	PHYDM_DBG(dm, DBG_ENV_MNTR, "ifs clm_ongoing=%d, lv:(%d)->(%d)\n",
2572 		  ccx->ifs_clm_ongoing, ccx->ifs_clm_set_lv, ifs_clm_lv);
2573 	if (ccx->ifs_clm_ongoing) {
2574 		if (ifs_clm_lv <= ccx->ifs_clm_set_lv) {
2575 			set_result = PHYDM_SET_FAIL;
2576 		} else {
2577 			phydm_ifs_clm_restart(dm);
2578 			ccx->ifs_clm_ongoing = false;
2579 		}
2580 	}
2581 
2582 	if (set_result)
2583 		ccx->ifs_clm_set_lv = ifs_clm_lv;
2584 
2585 	PHYDM_DBG(dm, DBG_ENV_MNTR, "ifs clm racing success=%d\n", set_result);
2586 	return set_result;
2587 }
2588 
phydm_ifs_clm_trigger(void * dm_void)2589 void phydm_ifs_clm_trigger(void *dm_void)
2590 {
2591 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2592 	struct ccx_info *ccx = &dm->dm_ccx_info;
2593 
2594 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2595 
2596 	/*Trigger IFS_CLM*/
2597 	pdm_set_reg(dm, R_0x1ee4, BIT(29), 0);
2598 	pdm_set_reg(dm, R_0x1ee4, BIT(29), 1);
2599 	ccx->ifs_clm_trigger_time = dm->phydm_sys_up_time;
2600 	ccx->ifs_clm_rpt_stamp++;
2601 	ccx->ifs_clm_ongoing = true;
2602 }
2603 
phydm_ifs_clm_get_utility(void * dm_void)2604 void phydm_ifs_clm_get_utility(void *dm_void)
2605 {
2606 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2607 	struct ccx_info *ccx = &dm->dm_ccx_info;
2608 	u16 denom = 0;
2609 
2610 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2611 
2612 	denom = ccx->ifs_clm_period;
2613 	ccx->ifs_clm_tx_ratio = phydm_ccx_get_rpt_ratio(dm, ccx->ifs_clm_tx,
2614 				denom);
2615 	ccx->ifs_clm_edcca_excl_cca_ratio = phydm_ccx_get_rpt_ratio(dm,
2616 					    ccx->ifs_clm_edcca_excl_cca,
2617 					    denom);
2618 	ccx->ifs_clm_cck_fa_ratio = phydm_ccx_get_rpt_ratio(dm,
2619 				    ccx->ifs_clm_cckfa, denom);
2620 	ccx->ifs_clm_ofdm_fa_ratio = phydm_ccx_get_rpt_ratio(dm,
2621 				     ccx->ifs_clm_ofdmfa, denom);
2622 	ccx->ifs_clm_cck_cca_excl_fa_ratio = phydm_ccx_get_rpt_ratio(dm,
2623 					     ccx->ifs_clm_cckcca_excl_fa,
2624 					     denom);
2625 	ccx->ifs_clm_ofdm_cca_excl_fa_ratio = phydm_ccx_get_rpt_ratio(dm,
2626 					      ccx->ifs_clm_ofdmcca_excl_fa,
2627 					      denom);
2628 
2629 	PHYDM_DBG(dm, DBG_ENV_MNTR,
2630 		  "Tx_ratio = %d, EDCCA_exclude_CCA_ratio = %d \n",
2631 		  ccx->ifs_clm_tx_ratio, ccx->ifs_clm_edcca_excl_cca_ratio);
2632 	PHYDM_DBG(dm, DBG_ENV_MNTR,
2633 		  "CCK : FA_ratio = %d, CCA_exclude_FA_ratio = %d \n",
2634 		  ccx->ifs_clm_cck_fa_ratio,
2635 		  ccx->ifs_clm_cck_cca_excl_fa_ratio);
2636 	PHYDM_DBG(dm, DBG_ENV_MNTR,
2637 		  "OFDM : FA_ratio = %d, CCA_exclude_FA_ratio = %d \n",
2638 		  ccx->ifs_clm_ofdm_fa_ratio,
2639 		  ccx->ifs_clm_ofdm_cca_excl_fa_ratio);
2640 }
2641 
phydm_ifs_clm_get_result(void * dm_void)2642 void phydm_ifs_clm_get_result(void *dm_void)
2643 {
2644 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2645 	struct ccx_info *ccx = &dm->dm_ccx_info;
2646 	u32 value32 = 0;
2647 	u8 i = 0;
2648 
2649 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2650 
2651 	/*Enhance CLM result*/
2652 	value32 = odm_get_bb_reg(dm, R_0x2e60, MASKDWORD);
2653 	ccx->ifs_clm_tx = (u16)(value32 & MASKLWORD);
2654 	ccx->ifs_clm_edcca_excl_cca = (u16)((value32 & MASKHWORD) >> 16);
2655 	value32 = odm_get_bb_reg(dm, R_0x2e64, MASKDWORD);
2656 	ccx->ifs_clm_ofdmfa = (u16)(value32 & MASKLWORD);
2657 	ccx->ifs_clm_ofdmcca_excl_fa = (u16)((value32 & MASKHWORD) >> 16);
2658 	value32 = odm_get_bb_reg(dm, R_0x2e68, MASKDWORD);
2659 	ccx->ifs_clm_cckfa = (u16)(value32 & MASKLWORD);
2660 	ccx->ifs_clm_cckcca_excl_fa = (u16)((value32 & MASKHWORD) >> 16);
2661 	value32 = odm_get_bb_reg(dm, R_0x2e6c, MASKDWORD);
2662 	ccx->ifs_clm_total_cca = (u16)(value32 & MASKLWORD);
2663 
2664 	/* IFS result */
2665 	value32 = odm_get_bb_reg(dm, R_0x2e70, MASKDWORD);
2666 	value32 = odm_convert_to_le32(value32);
2667 	odm_move_memory(dm, &ccx->ifs_clm_his[0], &value32, 4);
2668 	value32 = odm_get_bb_reg(dm, R_0x2e74, MASKDWORD);
2669 	ccx->ifs_clm_avg[0] = (u16)(value32 & MASKLWORD);
2670 	ccx->ifs_clm_avg[1] = (u16)((value32 & MASKHWORD) >> 16);
2671 	value32 = odm_get_bb_reg(dm, R_0x2e78, MASKDWORD);
2672 	ccx->ifs_clm_avg[2] = (u16)(value32 & MASKLWORD);
2673 	ccx->ifs_clm_avg[3] = (u16)((value32 & MASKHWORD) >> 16);
2674 	value32 = odm_get_bb_reg(dm, R_0x2e7c, MASKDWORD);
2675 	ccx->ifs_clm_avg_cca[0] = (u16)(value32 & MASKLWORD);
2676 	ccx->ifs_clm_avg_cca[1] = (u16)((value32 & MASKHWORD) >> 16);
2677 	value32 = odm_get_bb_reg(dm, R_0x2e80, MASKDWORD);
2678 	ccx->ifs_clm_avg_cca[2] = (u16)(value32 & MASKLWORD);
2679 	ccx->ifs_clm_avg_cca[3] = (u16)((value32 & MASKHWORD) >> 16);
2680 
2681 	/* Print Result */
2682 	PHYDM_DBG(dm, DBG_ENV_MNTR,
2683 		  "ECLM_Rpt[%d]: \nTx = %d, EDCCA_exclude_CCA = %d \n",
2684 		  ccx->ifs_clm_rpt_stamp, ccx->ifs_clm_tx,
2685 		  ccx->ifs_clm_edcca_excl_cca);
2686 	PHYDM_DBG(dm, DBG_ENV_MNTR,
2687 		  "[FA_cnt] {CCK, OFDM} = {%d, %d}\n",
2688 		  ccx->ifs_clm_cckfa, ccx->ifs_clm_ofdmfa);
2689 	PHYDM_DBG(dm, DBG_ENV_MNTR,
2690 		  "[CCA_exclude_FA_cnt] {CCK, OFDM} = {%d, %d}\n",
2691 		  ccx->ifs_clm_cckcca_excl_fa, ccx->ifs_clm_ofdmcca_excl_fa);
2692 	PHYDM_DBG(dm, DBG_ENV_MNTR, "CCATotal = %d\n", ccx->ifs_clm_total_cca);
2693 	PHYDM_DBG(dm, DBG_ENV_MNTR, "Time:[his, avg, avg_cca]\n");
2694 	for (i = 0; i < IFS_CLM_NUM; i++)
2695 		PHYDM_DBG(dm, DBG_ENV_MNTR,
2696 			  "T%d:[%d, %d, %d]\n", i + 1,
2697 			  ccx->ifs_clm_his[i], ccx->ifs_clm_avg[i],
2698 			  ccx->ifs_clm_avg_cca[i]);
2699 
2700 	phydm_ifs_clm_racing_release(dm);
2701 
2702 	return;
2703 }
2704 
phydm_ifs_clm_set_th_reg(void * dm_void)2705 void phydm_ifs_clm_set_th_reg(void *dm_void)
2706 {
2707 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2708 	struct ccx_info *ccx = &dm->dm_ccx_info;
2709 	u8 i = 0;
2710 
2711 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2712 
2713 	/*Set IFS period TH*/
2714 	odm_set_bb_reg(dm, R_0x1ed4, BIT(31), ccx->ifs_clm_th_en[0]);
2715 	odm_set_bb_reg(dm, R_0x1ed8, BIT(31), ccx->ifs_clm_th_en[1]);
2716 	odm_set_bb_reg(dm, R_0x1edc, BIT(31), ccx->ifs_clm_th_en[2]);
2717 	odm_set_bb_reg(dm, R_0x1ee0, BIT(31), ccx->ifs_clm_th_en[3]);
2718 	odm_set_bb_reg(dm, R_0x1ed4, 0x7fff0000, ccx->ifs_clm_th_low[0]);
2719 	odm_set_bb_reg(dm, R_0x1ed8, 0x7fff0000, ccx->ifs_clm_th_low[1]);
2720 	odm_set_bb_reg(dm, R_0x1edc, 0x7fff0000, ccx->ifs_clm_th_low[2]);
2721 	odm_set_bb_reg(dm, R_0x1ee0, 0x7fff0000, ccx->ifs_clm_th_low[3]);
2722 	odm_set_bb_reg(dm, R_0x1ed4, MASKLWORD, ccx->ifs_clm_th_high[0]);
2723 	odm_set_bb_reg(dm, R_0x1ed8, MASKLWORD, ccx->ifs_clm_th_high[1]);
2724 	odm_set_bb_reg(dm, R_0x1edc, MASKLWORD, ccx->ifs_clm_th_high[2]);
2725 	odm_set_bb_reg(dm, R_0x1ee0, MASKLWORD, ccx->ifs_clm_th_high[3]);
2726 
2727 	for (i = 0; i < IFS_CLM_NUM; i++)
2728 		PHYDM_DBG(dm, DBG_ENV_MNTR,
2729 			  "Update IFS_CLM_th%d[High Low] : [%d %d]\n", i + 1,
2730 		  	  ccx->ifs_clm_th_high[i], ccx->ifs_clm_th_low[i]);
2731 }
2732 
phydm_ifs_clm_th_update_chk(void * dm_void,enum ifs_clm_application ifs_clm_app,boolean * ifs_clm_th_en,u16 * ifs_clm_th_low,u16 * ifs_clm_th_high,s16 th_shift)2733 boolean phydm_ifs_clm_th_update_chk(void *dm_void,
2734 				    enum ifs_clm_application ifs_clm_app,
2735 				    boolean *ifs_clm_th_en, u16 *ifs_clm_th_low,
2736 				    u16 *ifs_clm_th_high, s16 th_shift)
2737 {
2738 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2739 	struct ccx_info *ccx = &dm->dm_ccx_info;
2740 	boolean is_update = false;
2741 	u16 ifs_clm_th_low_bg[IFS_CLM_NUM] = {12, 5, 2, 0};
2742 	u16 ifs_clm_th_high_bg[IFS_CLM_NUM] = {64, 12, 5, 2};
2743 	u8 i = 0;
2744 
2745 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2746 	PHYDM_DBG(dm, DBG_ENV_MNTR, "App=%d, th_shift=%d\n", ifs_clm_app,
2747 		  th_shift);
2748 
2749 	switch (ifs_clm_app) {
2750 	case IFS_CLM_BACKGROUND:
2751 	case IFS_CLM_ACS:
2752 	case IFS_CLM_HP_TAS:
2753 		if (ccx->ifs_clm_app != ifs_clm_app || th_shift != 0) {
2754 			is_update = true;
2755 
2756 			for (i = 0; i < IFS_CLM_NUM; i++) {
2757 				ifs_clm_th_en[i] = true;
2758 				ifs_clm_th_low[i] = ifs_clm_th_low_bg[i];
2759 				ifs_clm_th_high[i] = ifs_clm_th_high_bg[i];
2760 			}
2761 		}
2762 		break;
2763 	case IFS_CLM_DBG:
2764 		if (ccx->ifs_clm_app != ifs_clm_app || th_shift != 0) {
2765 			is_update = true;
2766 
2767 			for (i = 0; i < IFS_CLM_NUM; i++) {
2768 				ifs_clm_th_en[i] = true;
2769 				ifs_clm_th_low[i] = MAX_2(ccx->ifs_clm_th_low[i] +
2770 						    th_shift, 0);
2771 				ifs_clm_th_high[i] = MAX_2(ccx->ifs_clm_th_high[i] +
2772 						     th_shift, 0);
2773 			}
2774 		}
2775 		break;
2776 	default:
2777 		break;
2778 	}
2779 
2780 	if (is_update)
2781 		PHYDM_DBG(dm, DBG_ENV_MNTR, "[Update IFS_TH]\n");
2782 	else
2783 		PHYDM_DBG(dm, DBG_ENV_MNTR, "No need to update IFS_TH\n");
2784 
2785 	return is_update;
2786 }
2787 
phydm_ifs_clm_set(void * dm_void,enum ifs_clm_application ifs_clm_app,u16 period,u8 ctrl_unit,s16 th_shift)2788 void phydm_ifs_clm_set(void *dm_void, enum ifs_clm_application ifs_clm_app,
2789 		       u16 period, u8 ctrl_unit, s16 th_shift)
2790 {
2791 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2792 	struct ccx_info *ccx = &dm->dm_ccx_info;
2793 	boolean ifs_clm_th_en[IFS_CLM_NUM] =  {0};
2794 	u16 ifs_clm_th_low[IFS_CLM_NUM] =  {0};
2795 	u16 ifs_clm_th_high[IFS_CLM_NUM] =  {0};
2796 
2797 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2798 	PHYDM_DBG(dm, DBG_ENV_MNTR, "period=%d, ctrl_unit=%d\n", period,
2799 		  ctrl_unit);
2800 
2801 	/*Set Unit*/
2802 	if (ctrl_unit != ccx->ifs_clm_ctrl_unit) {
2803 		odm_set_bb_reg(dm, R_0x1ee4, 0xc0000000, ctrl_unit);
2804 		PHYDM_DBG(dm, DBG_ENV_MNTR,
2805 			  "Update IFS_CLM unit ((%d)) -> ((%d))\n",
2806 			  ccx->ifs_clm_ctrl_unit, ctrl_unit);
2807 		ccx->ifs_clm_ctrl_unit = ctrl_unit;
2808 	}
2809 
2810 	/*Set Duration*/
2811 	if (period != ccx->ifs_clm_period) {
2812 		odm_set_bb_reg(dm, R_0x1eec, 0xc0000000, (period & 0x3));
2813 		odm_set_bb_reg(dm, R_0x1ef0, 0xfe000000, ((period >> 2) &
2814 			       0x7f));
2815 		odm_set_bb_reg(dm, R_0x1ef4, 0xc0000000, ((period >> 9) &
2816 			       0x3));
2817 		odm_set_bb_reg(dm, R_0x1ef8, 0x3e000000, ((period >> 11) &
2818 			       0x1f));
2819 		PHYDM_DBG(dm, DBG_ENV_MNTR,
2820 			  "Update IFS_CLM period ((%d)) -> ((%d))\n",
2821 			  ccx->ifs_clm_period, period);
2822 		ccx->ifs_clm_period = period;
2823 	}
2824 
2825 	/*Set IFS CLM threshold*/
2826 	if (phydm_ifs_clm_th_update_chk(dm, ifs_clm_app, &ifs_clm_th_en[0],
2827 					&ifs_clm_th_low[0], &ifs_clm_th_high[0],
2828 					th_shift)) {
2829 
2830 		ccx->ifs_clm_app = ifs_clm_app;
2831 		odm_move_memory(dm, &ccx->ifs_clm_th_en[0], &ifs_clm_th_en,
2832 				IFS_CLM_NUM);
2833 		odm_move_memory(dm, &ccx->ifs_clm_th_low[0], &ifs_clm_th_low,
2834 				IFS_CLM_NUM);
2835 		odm_move_memory(dm, &ccx->ifs_clm_th_high[0], &ifs_clm_th_high,
2836 				IFS_CLM_NUM);
2837 
2838 		phydm_ifs_clm_set_th_reg(dm);
2839 	}
2840 }
2841 
2842 boolean
phydm_ifs_clm_mntr_set(void * dm_void,struct ifs_clm_para_info * ifs_clm_para)2843 phydm_ifs_clm_mntr_set(void *dm_void, struct ifs_clm_para_info *ifs_clm_para)
2844 {
2845 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2846 	u16 ifs_clm_time = 0; /*unit: 4/8/12/16us*/
2847 	u8 unit = 0;
2848 
2849 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2850 
2851 	if (ifs_clm_para->mntr_time == 0)
2852 		return false;
2853 
2854 	if (ifs_clm_para->ifs_clm_lv >= IFS_CLM_MAX_NUM) {
2855 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Wrong LV=%d\n",
2856 			  ifs_clm_para->ifs_clm_lv);
2857 		return false;
2858 	}
2859 
2860 	if (phydm_ifs_clm_racing_ctrl(dm, ifs_clm_para->ifs_clm_lv) == PHYDM_SET_FAIL)
2861 		return false;
2862 
2863 	if (ifs_clm_para->mntr_time >= 1048) {
2864 		unit = IFS_CLM_16;
2865 		ifs_clm_time = IFS_CLM_PERIOD_MAX; /*65535 * 16us = 1048ms*/
2866 	} else if (ifs_clm_para->mntr_time >= 786) {/*65535 * 12us = 786 ms*/
2867 		unit = IFS_CLM_16;
2868 		ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 16);
2869 	} else if (ifs_clm_para->mntr_time >= 524) {
2870 		unit = IFS_CLM_12;
2871 		ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 12);
2872 	} else if (ifs_clm_para->mntr_time >= 262) {
2873 		unit = IFS_CLM_8;
2874 		ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 8);
2875 	} else {
2876 		unit = IFS_CLM_4;
2877 		ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 4);
2878 	}
2879 
2880 	phydm_ifs_clm_set(dm, ifs_clm_para->ifs_clm_app, ifs_clm_time, unit,
2881 			  ifs_clm_para->th_shift);
2882 
2883 	return true;
2884 }
2885 
2886 boolean
phydm_ifs_clm_mntr_racing_chk(void * dm_void)2887 phydm_ifs_clm_mntr_racing_chk(void *dm_void)
2888 {
2889 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2890 	struct ccx_info *ccx = &dm->dm_ccx_info;
2891 	u32 sys_return_time = 0;
2892 
2893 	if (ccx->ifs_clm_manual_ctrl) {
2894 		PHYDM_DBG(dm, DBG_ENV_MNTR, "IFS_CLM in manual ctrl\n");
2895 		return true;
2896 	}
2897 
2898 	sys_return_time = ccx->ifs_clm_trigger_time + MAX_ENV_MNTR_TIME;
2899 
2900 	if (ccx->ifs_clm_app != IFS_CLM_BACKGROUND &&
2901 	    (sys_return_time > dm->phydm_sys_up_time)) {
2902 		PHYDM_DBG(dm, DBG_ENV_MNTR,
2903 			  "ifs_clm_app=%d, trigger_time %d, sys_time=%d\n",
2904 			  ccx->ifs_clm_app, ccx->ifs_clm_trigger_time,
2905 			  dm->phydm_sys_up_time);
2906 
2907 		return true;
2908 	}
2909 
2910 	return false;
2911 }
2912 
2913 boolean
phydm_ifs_clm_mntr_chk(void * dm_void,u16 monitor_time)2914 phydm_ifs_clm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/)
2915 {
2916 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2917 	struct ccx_info *ccx = &dm->dm_ccx_info;
2918 	struct ifs_clm_para_info ifs_clm_para = {0};
2919 	boolean ifs_clm_chk_result = false;
2920 
2921 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2922 
2923 	if (phydm_ifs_clm_mntr_racing_chk(dm))
2924 		return ifs_clm_chk_result;
2925 
2926 	/*[IFS CLM trigger setting]------------------------------------------*/
2927 	ifs_clm_para.ifs_clm_app = IFS_CLM_BACKGROUND;
2928 	ifs_clm_para.ifs_clm_lv = IFS_CLM_LV_1;
2929 	ifs_clm_para.mntr_time = monitor_time;
2930 	ifs_clm_para.th_shift = 0;
2931 
2932 	ifs_clm_chk_result = phydm_ifs_clm_mntr_set(dm, &ifs_clm_para);
2933 
2934 	return ifs_clm_chk_result;
2935 }
2936 
2937 boolean
phydm_ifs_clm_mntr_result(void * dm_void)2938 phydm_ifs_clm_mntr_result(void *dm_void)
2939 {
2940 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2941 	struct ccx_info *ccx = &dm->dm_ccx_info;
2942 	boolean ifs_clm_chk_result = false;
2943 
2944 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2945 
2946 	if (phydm_ifs_clm_mntr_racing_chk(dm))
2947 		return ifs_clm_chk_result;
2948 
2949 	/*[IFS CLM get result] ------------------------------------]*/
2950 	phydm_ifs_clm_get_result(dm);
2951 	phydm_ifs_clm_get_utility(dm);
2952 	ifs_clm_chk_result = true;
2953 
2954 	return ifs_clm_chk_result;
2955 }
2956 
phydm_ifs_clm_init(void * dm_void)2957 void phydm_ifs_clm_init(void *dm_void)
2958 {
2959 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2960 	struct ccx_info *ccx = &dm->dm_ccx_info;
2961 
2962 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
2963 
2964 	ccx->ifs_clm_app = IFS_CLM_BACKGROUND;
2965 
2966 	/*Set IFS threshold*/
2967 	ccx->ifs_clm_ongoing = false;
2968 	ccx->ifs_clm_set_lv = IFS_CLM_RELEASE;
2969 
2970 	if (phydm_ifs_clm_th_update_chk(dm, ccx->ifs_clm_app,
2971 					&ccx->ifs_clm_th_en[0],
2972 					&ccx->ifs_clm_th_low[0],
2973 					&ccx->ifs_clm_th_high[0], 0xffff))
2974 		phydm_ifs_clm_set_th_reg(dm);
2975 
2976 	ccx->ifs_clm_period = 0;
2977 	ccx->ifs_clm_ctrl_unit = IFS_CLM_INIT;
2978 	ccx->ifs_clm_manual_ctrl = 0;
2979 	ccx->ifs_clm_rpt_stamp = 0;
2980 }
2981 
phydm_ifs_clm_dbg(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)2982 void phydm_ifs_clm_dbg(void *dm_void, char input[][16], u32 *_used,
2983 		       char *output, u32 *_out_len)
2984 {
2985 	struct dm_struct *dm = (struct dm_struct *)dm_void;
2986 	struct ccx_info *ccx = &dm->dm_ccx_info;
2987 	struct ifs_clm_para_info ifs_clm_para;
2988 	char help[] = "-h";
2989 	u32 var1[10] = {0};
2990 	u32 used = *_used;
2991 	u32 out_len = *_out_len;
2992 	u8 result_tmp = 0;
2993 	u8 i = 0;
2994 	u16 th_shift = 0;
2995 
2996 	if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM))
2997 		return;
2998 
2999 	for (i = 0; i < 5; i++) {
3000 		if (input[i + 1])
3001 			PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
3002 				     &var1[i]);
3003 	}
3004 
3005 	if ((strcmp(input[1], help) == 0)) {
3006 		PDM_SNPF(out_len, used, output + used, out_len - used,
3007 			 "IFS_CLM Basic-Trigger 960ms: {1}\n");
3008 		PDM_SNPF(out_len, used, output + used, out_len - used,
3009 			 "IFS_CLM Adv-Trigger: {2} {App:3 for dbg} {LV:1~4} {0~2096ms} {th_shift}\n");
3010 		PDM_SNPF(out_len, used, output + used, out_len - used,
3011 			 "IFS_CLM Get Result: {100}\n");
3012 	} else if (var1[0] == 100) { /*Get IFS_CLM results*/
3013 		phydm_ifs_clm_get_result(dm);
3014 
3015 		PDM_SNPF(out_len, used, output + used, out_len - used,
3016 			  "ECLM_Rpt[%d]: \nTx = %d \nEDCCA_exclude_CCA = %d\n",
3017 			  ccx->ifs_clm_rpt_stamp, ccx->ifs_clm_tx,
3018 			  ccx->ifs_clm_edcca_excl_cca);
3019 		PDM_SNPF(out_len, used, output + used, out_len - used,
3020 			  "[FA_cnt] {CCK, OFDM} = {%d, %d}\n",
3021 			  ccx->ifs_clm_cckfa, ccx->ifs_clm_ofdmfa);
3022 		PDM_SNPF(out_len, used, output + used, out_len - used,
3023 			  "[CCA_exclude_FA_cnt] {CCK, OFDM} = {%d, %d}\n",
3024 			  ccx->ifs_clm_cckcca_excl_fa,
3025 			  ccx->ifs_clm_ofdmcca_excl_fa);
3026 		PDM_SNPF(out_len, used, output + used, out_len - used,
3027 			 "CCATotal = %d\n", ccx->ifs_clm_total_cca);
3028 		PDM_SNPF(out_len, used, output + used, out_len - used,
3029 			 "Time:[his, avg, avg_cca]\n");
3030 		for (i = 0; i < IFS_CLM_NUM; i++)
3031 			PDM_SNPF(out_len, used, output + used, out_len - used,
3032 				  "T%d:[%d, %d, %d]\n", i + 1,
3033 				  ccx->ifs_clm_his[i], ccx->ifs_clm_avg[i],
3034 				  ccx->ifs_clm_avg_cca[i]);
3035 
3036 		phydm_ifs_clm_get_utility(dm);
3037 
3038 		ccx->ifs_clm_manual_ctrl = 0;
3039 	} else { /*IFS_CLM trigger*/
3040 		ccx->ifs_clm_manual_ctrl = 1;
3041 
3042 		if (var1[0] == 1) {
3043 			ifs_clm_para.ifs_clm_app = IFS_CLM_DBG;
3044 			ifs_clm_para.ifs_clm_lv = IFS_CLM_LV_4;
3045 			ifs_clm_para.mntr_time = 960;
3046 			ifs_clm_para.th_shift = 0;
3047 		} else {
3048 			ifs_clm_para.ifs_clm_app = (enum ifs_clm_application)var1[1];
3049 			ifs_clm_para.ifs_clm_lv = (enum phydm_ifs_clm_level)var1[2];
3050 			ifs_clm_para.mntr_time = (u16)var1[3];
3051 			ifs_clm_para.th_shift = (s16)var1[4];
3052 		}
3053 
3054 		PDM_SNPF(out_len, used, output + used, out_len - used,
3055 			 "app=%d, lv=%d, time=%d ms, th_shift=%s%d\n",
3056 			 ifs_clm_para.ifs_clm_app, ifs_clm_para.ifs_clm_lv,
3057 			 ifs_clm_para.mntr_time,
3058 			 (ifs_clm_para.th_shift > 0) ? "+" : "-",
3059 			 ifs_clm_para.th_shift);
3060 
3061 		if (phydm_ifs_clm_mntr_set(dm, &ifs_clm_para) == PHYDM_SET_SUCCESS)
3062 			phydm_ifs_clm_trigger(dm);
3063 
3064 		PDM_SNPF(out_len, used, output + used, out_len - used,
3065 			 "rpt_stamp=%d\n", ccx->ifs_clm_rpt_stamp);
3066 		for (i = 0; i < IFS_CLM_NUM; i++)
3067 			PDM_SNPF(out_len, used, output + used, out_len - used,
3068 				  "IFS_CLM_th%d[High Low] : [%d %d]\n", i + 1,
3069 			  	  ccx->ifs_clm_th_high[i],
3070 			  	  ccx->ifs_clm_th_low[i]);
3071 	}
3072 
3073 	*_used = used;
3074 	*_out_len = out_len;
3075 }
3076 #endif
3077 
phydm_enhance_mntr_trigger(void * dm_void,struct nhm_para_info * nhm_para,struct clm_para_info * clm_para,struct fahm_para_info * fahm_para,struct ifs_clm_para_info * ifs_clm_para,struct enhance_mntr_trig_rpt * trig_rpt)3078 u8 phydm_enhance_mntr_trigger(void *dm_void, struct nhm_para_info *nhm_para,
3079 			     struct clm_para_info *clm_para,
3080 			     struct fahm_para_info *fahm_para,
3081 			     struct ifs_clm_para_info *ifs_clm_para,
3082 			     struct enhance_mntr_trig_rpt *trig_rpt)
3083 {
3084 	u8 trigger_result = 0;
3085 #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT) && defined(FAHM_SUPPORT) && defined(IFS_CLM_SUPPORT))
3086 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3087 	struct ccx_info *ccx = &dm->dm_ccx_info;
3088 	boolean nhm_set_ok = false;
3089 	boolean clm_set_ok = false;
3090 	boolean fahm_set_ok = false;
3091 	boolean ifs_clm_set_ok = false;
3092 
3093 	if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) ||
3094 	    !(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM))
3095 		return trigger_result;
3096 
3097 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__);
3098 
3099 	nhm_set_ok = phydm_nhm_mntr_set(dm, nhm_para);
3100 
3101 	if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) {
3102 		clm_set_ok = phydm_clm_mntr_set(dm, clm_para);
3103 	} else if (ccx->clm_mntr_mode == CLM_FW_MNTR) {
3104 		phydm_clm_h2c(dm, CLM_PERIOD_MAX, true);
3105 		trigger_result |= CLM_SUCCESS;
3106 	}
3107 
3108 	fahm_set_ok = phydm_fahm_mntr_set(dm, fahm_para);
3109 
3110 	ifs_clm_set_ok = phydm_ifs_clm_mntr_set(dm, ifs_clm_para);
3111 
3112 	if (nhm_set_ok) {
3113 		phydm_nhm_trigger(dm);
3114 		trigger_result |= NHM_SUCCESS;
3115 	}
3116 
3117 	if (clm_set_ok) {
3118 		phydm_clm_trigger(dm);
3119 		trigger_result |= CLM_SUCCESS;
3120 	}
3121 
3122 	if (fahm_set_ok) {
3123 		phydm_fahm_trigger(dm);
3124 		trigger_result |= FAHM_SUCCESS;
3125 	}
3126 
3127 	if (ifs_clm_set_ok) {
3128 		phydm_ifs_clm_trigger(dm);
3129 		trigger_result |= IFS_CLM_SUCCESS;
3130 	}
3131 
3132 	/*monitor for the test duration*/
3133 	ccx->start_time = odm_get_current_time(dm);
3134 
3135 	trig_rpt->nhm_rpt_stamp = ccx->nhm_rpt_stamp;
3136 	trig_rpt->clm_rpt_stamp = ccx->clm_rpt_stamp;
3137 	trig_rpt->fahm_rpt_stamp = ccx->fahm_rpt_stamp;
3138 	trig_rpt->ifs_clm_rpt_stamp = ccx->ifs_clm_rpt_stamp;
3139 
3140 	PHYDM_DBG(dm, DBG_ENV_MNTR,
3141 		  "rpt_stamp{NHM, CLM, FAHM, IFS_CLM}={%d, %d, %d, %d}\n\n",
3142 		  trig_rpt->nhm_rpt_stamp, trig_rpt->clm_rpt_stamp,
3143 		  trig_rpt->fahm_rpt_stamp, trig_rpt->ifs_clm_rpt_stamp);
3144 
3145 #endif
3146 	return trigger_result;
3147 }
3148 
phydm_enhance_mntr_result(void * dm_void,struct enhance_mntr_rpt * rpt)3149 u8 phydm_enhance_mntr_result(void *dm_void, struct enhance_mntr_rpt *rpt)
3150 {
3151 	u8 enhance_mntr_rpt = 0;
3152 #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT) && defined(FAHM_SUPPORT) && defined(IFS_CLM_SUPPORT))
3153 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3154 	struct ccx_info *ccx = &dm->dm_ccx_info;
3155 	u64 progressing_time = 0;
3156 	u32 val_tmp = 0;
3157 
3158 	if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) ||
3159 	    !(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM))
3160 		return enhance_mntr_rpt;
3161 
3162 	/*monitor for the test duration*/
3163 	progressing_time = odm_get_progressing_time(dm, ccx->start_time);
3164 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__);
3165 	PHYDM_DBG(dm, DBG_ENV_MNTR, "enhance_mntr_time=%lld\n",
3166 		  progressing_time);
3167 
3168 	/*Get NHM result*/
3169 	if (phydm_nhm_get_result(dm)) {
3170 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM_rpt success\n");
3171 		phydm_nhm_get_utility(dm);
3172 		rpt->nhm_ratio = ccx->nhm_ratio;
3173 		rpt->nhm_env_ratio = ccx->nhm_env_ratio;
3174 		rpt->nhm_noise_pwr = ccx->nhm_level;
3175 		rpt->nhm_pwr = ccx->nhm_pwr;
3176 		enhance_mntr_rpt |= NHM_SUCCESS;
3177 
3178 		odm_move_memory(dm, &rpt->nhm_result[0],
3179 				&ccx->nhm_result[0], NHM_RPT_NUM);
3180 	} else {
3181 		rpt->nhm_ratio = ENV_MNTR_FAIL;
3182 		rpt->nhm_env_ratio = ENV_MNTR_FAIL;
3183 	}
3184 
3185 	PHYDM_DBG(dm, DBG_ENV_MNTR,
3186 		  "[NHM]rpt_stamp=%d, IGI=0x%x, ratio=%d, env_ratio=%d, noise_pwr=%d, pwr=%d\n",
3187 		  rpt->nhm_rpt_stamp, ccx->nhm_igi, rpt->nhm_ratio,
3188 		  rpt->nhm_env_ratio, rpt->nhm_noise_pwr, rpt->nhm_pwr);
3189 
3190 	/*Get CLM result*/
3191 	if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) {
3192 		if (phydm_clm_get_result(dm)) {
3193 			PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM_rpt success\n");
3194 			phydm_clm_get_utility(dm);
3195 			enhance_mntr_rpt |= CLM_SUCCESS;
3196 			rpt->clm_ratio = ccx->clm_ratio;
3197 		} else {
3198 			rpt->clm_ratio = ENV_MNTR_FAIL;
3199 		}
3200 	} else {
3201 		if (ccx->clm_fw_result_cnt != 0) {
3202 			val_tmp = ccx->clm_fw_result_acc
3203 			/ ccx->clm_fw_result_cnt;
3204 			ccx->clm_ratio = (u8)val_tmp;
3205 		} else {
3206 			ccx->clm_ratio = 0;
3207 		}
3208 		rpt->clm_ratio = ccx->clm_ratio;
3209 		PHYDM_DBG(dm, DBG_ENV_MNTR,
3210 			  "clm_fw_result_acc=%d, clm_fw_result_cnt=%d\n",
3211 			  ccx->clm_fw_result_acc, ccx->clm_fw_result_cnt);
3212 
3213 		ccx->clm_fw_result_acc = 0;
3214 		ccx->clm_fw_result_cnt = 0;
3215 		enhance_mntr_rpt |= CLM_SUCCESS;
3216 	}
3217 
3218 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[CLM]rpt_stamp=%d, ratio=%d\n",
3219 		  rpt->clm_rpt_stamp, rpt->clm_ratio);
3220 
3221 	/*Get FAHM result*/
3222 	if (phydm_fahm_get_result(dm)) {
3223 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Get FAHM_rpt success\n");
3224 		phydm_fahm_get_utility(dm);
3225 		rpt->fahm_pwr = ccx->fahm_pwr;
3226 		rpt->fahm_ratio = ccx->fahm_ratio;
3227 		rpt->fahm_denom_ratio = ccx->fahm_denom_ratio;
3228 		rpt->fahm_inclu_cck = ccx->fahm_inclu_cck;
3229 		enhance_mntr_rpt |= FAHM_SUCCESS;
3230 
3231 		odm_move_memory(dm, &rpt->fahm_result[0],
3232 				&ccx->fahm_result[0], FAHM_RPT_NUM * 2);
3233 	} else {
3234 		rpt->fahm_pwr = 0;
3235 		rpt->fahm_ratio = 0;
3236 		rpt->fahm_denom_ratio = 0;
3237 	}
3238 
3239 	PHYDM_DBG(dm, DBG_ENV_MNTR,
3240 		  "[FAHM]stamp=%d, IGI=0x%x, fahm_inclu_cck=%d, fahm_pwr=%d, fahm_ratio=%d, fahm_denom_ratio=%d\n",
3241 		  rpt->fahm_rpt_stamp, ccx->fahm_igi, rpt->fahm_inclu_cck,
3242 		  rpt->fahm_pwr, rpt->fahm_ratio, rpt->fahm_denom_ratio);
3243 
3244 	/*Get IFS_CLM result*/
3245 	phydm_ifs_clm_get_result(dm);
3246 	phydm_ifs_clm_get_utility(dm);
3247 	rpt->ifs_clm_tx_ratio = ccx->ifs_clm_tx_ratio;
3248 	rpt->ifs_clm_edcca_excl_cca_ratio = ccx->ifs_clm_edcca_excl_cca_ratio;
3249 	rpt->ifs_clm_cck_fa_ratio = ccx->ifs_clm_cck_fa_ratio;
3250 	rpt->ifs_clm_cck_cca_excl_fa_ratio = ccx->ifs_clm_cck_cca_excl_fa_ratio;
3251 	rpt->ifs_clm_ofdm_fa_ratio = ccx->ifs_clm_ofdm_fa_ratio;
3252 	rpt->ifs_clm_ofdm_cca_excl_fa_ratio = ccx->ifs_clm_ofdm_cca_excl_fa_ratio;
3253 	rpt->ifs_clm_rpt_stamp = ccx->ifs_clm_rpt_stamp;
3254 	enhance_mntr_rpt |= IFS_CLM_SUCCESS;
3255 
3256 	PHYDM_DBG(dm, DBG_ENV_MNTR,
3257 		  "[IFS_CLM]rpt_stamp = %d, Tx_ratio = %d, EDCCA_exclude_CCA_ratio = %d\n",
3258 		  ccx->ifs_clm_rpt_stamp, ccx->ifs_clm_tx_ratio,
3259 		  ccx->ifs_clm_edcca_excl_cca_ratio);
3260 	PHYDM_DBG(dm, DBG_ENV_MNTR,
3261 		  "CCK : FA_ratio = %d, CCA_exclude_FA_ratio = %d\n",
3262 		  ccx->ifs_clm_cck_fa_ratio, ccx->ifs_clm_cck_cca_excl_fa_ratio);
3263 	PHYDM_DBG(dm, DBG_ENV_MNTR,
3264 		  "OFDM : FA_ratio = %d, CCA_exclude_FA_ratio = %d\n",
3265 		  ccx->ifs_clm_ofdm_fa_ratio,
3266 		  ccx->ifs_clm_ofdm_cca_excl_fa_ratio);
3267 
3268 	rpt->nhm_rpt_stamp = ccx->nhm_rpt_stamp;
3269 	rpt->clm_rpt_stamp = ccx->clm_rpt_stamp;
3270 	rpt->fahm_rpt_stamp = ccx->fahm_rpt_stamp;
3271 	rpt->ifs_clm_rpt_stamp = ccx->ifs_clm_rpt_stamp;
3272 #endif
3273 	return enhance_mntr_rpt;
3274 }
3275 
phydm_enhance_mntr_dbg(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)3276 void phydm_enhance_mntr_dbg(void *dm_void, char input[][16], u32 *_used,
3277 			    char *output, u32 *_out_len)
3278 {
3279 #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT) && defined(FAHM_SUPPORT) && defined(IFS_CLM_SUPPORT))
3280 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3281 	char help[] = "-h";
3282 	u32 var1[10] = {0};
3283 	u32 used = *_used;
3284 	u32 out_len = *_out_len;
3285 	struct nhm_para_info nhm_para = {0};
3286 	struct clm_para_info clm_para = {0};
3287 	struct fahm_para_info fahm_para = {0};
3288 	struct ifs_clm_para_info ifs_clm_para = {0};
3289 	struct enhance_mntr_rpt rpt = {0};
3290 	struct enhance_mntr_trig_rpt trig_rpt = {0};
3291 	struct ccx_info *ccx = &dm->dm_ccx_info;
3292 	u8 set_result = 0;
3293 	u8 i = 0;
3294 
3295 	if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) ||
3296 	    !(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM))
3297 		return;
3298 
3299 	PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
3300 
3301 	if ((strcmp(input[1], help) == 0)) {
3302 		PDM_SNPF(out_len, used, output + used, out_len - used,
3303 			 "Basic-Trigger 960ms for ifs_clm, 262ms for others: {1}\n");
3304 		PDM_SNPF(out_len, used, output + used, out_len - used,
3305 			 "Get Result: {100}\n");
3306 	} else if (var1[0] == 100) { /* Get results */
3307 		set_result = phydm_enhance_mntr_result(dm, &rpt);
3308 
3309 		PDM_SNPF(out_len, used, output + used, out_len - used,
3310 			 "Set Result=%d, rpt_stamp{NHM, CLM, FAHM, IFS_CLM}={%d, %d, %d, %d}\n",
3311 			 set_result, rpt.nhm_rpt_stamp, rpt.clm_rpt_stamp,
3312 			 rpt.fahm_rpt_stamp, rpt.ifs_clm_rpt_stamp);
3313 		PDM_SNPF(out_len, used, output + used, out_len - used,
3314 			 "clm_ratio=%d\n", rpt.clm_ratio);
3315 
3316 		for (i = 0; i < NHM_RPT_NUM; i++) {
3317 			PDM_SNPF(out_len, used, output + used, out_len - used,
3318 				 "nhm_rpt[%d] = %d (%d percent)\n", i,
3319 				 rpt.nhm_result[i],
3320 				 (((rpt.nhm_result[i] * 100) + 128) >> 8));
3321 		}
3322 
3323 		PDM_SNPF(out_len, used, output + used, out_len - used,
3324 			 "nhm_IGI=0x%x, nhm_ratio=%d, nhm_env_ratio=%d, nhm_noise_pwr=%d, nhm_pwr=%d\n",
3325 			 ccx->nhm_igi, rpt.nhm_ratio, rpt.nhm_env_ratio,
3326 			 rpt.nhm_noise_pwr, rpt.nhm_pwr);
3327 
3328 		if (!(rpt.fahm_inclu_cck))
3329 			PDM_SNPF(out_len, used, output + used,
3330 				 out_len - used,
3331 				 "===>The following fahm report does not count CCK pkt\n");
3332 
3333 		for (i = 0; i < FAHM_RPT_NUM; i++) {
3334 			PDM_SNPF(out_len, used, output + used, out_len - used,
3335 				 "fahm_rpt[%d] = %d (%d percent)\n", i,
3336 				 rpt.fahm_result[i],
3337 				 (((rpt.fahm_result[i] * 100) + 32768) >> 16));
3338 		}
3339 
3340 		PDM_SNPF(out_len, used, output + used, out_len - used,
3341 			 "fahm_IGI=0x%x, fahm_pwr=%d, fahm_ratio=%d, fahm_denom_ratio=%d\n",
3342 			 ccx->fahm_igi, rpt.fahm_pwr, rpt.fahm_ratio,
3343 			 rpt.fahm_denom_ratio);
3344 		PDM_SNPF(out_len, used, output + used, out_len - used,
3345 			 "ifs_clm_Tx_ratio = %d, ifs_clm_EDCCA_exclude_CCA_ratio = %d \n",
3346 			 rpt.ifs_clm_tx_ratio,
3347 			 rpt.ifs_clm_edcca_excl_cca_ratio);
3348 		PDM_SNPF(out_len, used, output + used, out_len - used,
3349 			 "ifs_clm_cck_fa_ratio = %d, ifs_clm_cck_cca_exclude_FA_ratio = %d \n",
3350 			 rpt.ifs_clm_cck_fa_ratio,
3351 			 rpt.ifs_clm_cck_cca_excl_fa_ratio);
3352 		PDM_SNPF(out_len, used, output + used, out_len - used,
3353 			 "ifs_clm_ofdm_fa_ratio = %d, ifs_clm_ofdm_cca_exclude_FA_ratio = %d \n",
3354 			 rpt.ifs_clm_ofdm_fa_ratio,
3355 			 rpt.ifs_clm_ofdm_cca_excl_fa_ratio);
3356 	} else { /* Set & trigger*/
3357 		/*nhm para*/
3358 		nhm_para.incld_txon = NHM_EXCLUDE_TXON;
3359 		nhm_para.incld_cca = NHM_EXCLUDE_CCA;
3360 		nhm_para.div_opt = NHM_CNT_ALL;
3361 		nhm_para.nhm_app = NHM_ACS;
3362 		nhm_para.nhm_lv = NHM_LV_2;
3363 		nhm_para.mntr_time = 262;
3364 		nhm_para.en_1db_mode = false;
3365 
3366 		/*clm para*/
3367 		clm_para.clm_app = CLM_ACS;
3368 		clm_para.clm_lv = CLM_LV_2;
3369 		clm_para.mntr_time = 262;
3370 
3371 		/*fahm para*/
3372 		fahm_para.numer_opt = FAHM_INCLU_FA;
3373 		fahm_para.denom_opt = FAHM_INCLU_CRC_ERR;
3374 		fahm_para.app = FAHM_ACS;
3375 		fahm_para.lv = FAHM_LV_2;
3376 		fahm_para.mntr_time = 262;
3377 		fahm_para.en_1db_mode = false;
3378 
3379 		ifs_clm_para.ifs_clm_app = IFS_CLM_ACS;
3380 		ifs_clm_para.ifs_clm_lv = IFS_CLM_LV_2;
3381 		ifs_clm_para.mntr_time = 960;
3382 		ifs_clm_para.th_shift = 0;
3383 
3384 		set_result = phydm_enhance_mntr_trigger(dm, &nhm_para,
3385 							&clm_para, &fahm_para,
3386 							&ifs_clm_para,
3387 							&trig_rpt);
3388 
3389 		PDM_SNPF(out_len, used, output + used, out_len - used,
3390 			 "Set Result=%d, rpt_stamp{NHM, CLM, FAHM, IFS_CLM}={%d, %d ,%d, %d}\n",
3391 			 set_result, trig_rpt.nhm_rpt_stamp,
3392 			 trig_rpt.clm_rpt_stamp, trig_rpt.fahm_rpt_stamp,
3393 			 trig_rpt.ifs_clm_rpt_stamp);
3394 	}
3395 	*_used = used;
3396 	*_out_len = out_len;
3397 #endif
3398 }
3399 
3400 #ifdef EDCCA_CLM_SUPPORT
3401 
phydm_edcca_clm_racing_release(void * dm_void)3402 void phydm_edcca_clm_racing_release(void *dm_void)
3403 {
3404 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3405 	struct ccx_info *ccx = &dm->dm_ccx_info;
3406 
3407 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
3408 	PHYDM_DBG(dm, DBG_ENV_MNTR, "lv:(%d)->(0)\n", ccx->edcca_clm_set_lv);
3409 
3410 	ccx->edcca_clm_ongoing = false;
3411 	ccx->edcca_clm_set_lv = EDCCA_CLM_RELEASE;
3412 	ccx->edcca_clm_app = EDCCA_CLM_BACKGROUND;
3413 }
3414 
phydm_edcca_clm_racing_ctrl(void * dm_void,enum phydm_edcca_clm_level lv)3415 u8 phydm_edcca_clm_racing_ctrl(void *dm_void, enum phydm_edcca_clm_level lv)
3416 {
3417 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3418 	struct ccx_info *ccx = &dm->dm_ccx_info;
3419 	u8 set_result = PHYDM_SET_SUCCESS;
3420 
3421 	PHYDM_DBG(dm, DBG_ENV_MNTR, "edcca_clm_ongoing=%d, lv:(%d)->(%d)\n",
3422 		  ccx->edcca_clm_ongoing, ccx->edcca_clm_set_lv, lv);
3423 	if (ccx->edcca_clm_ongoing) {
3424 		if (lv <= ccx->edcca_clm_set_lv) {
3425 			set_result = PHYDM_SET_FAIL;
3426 		} else {
3427 			phydm_ccx_hw_restart(dm);
3428 			ccx->edcca_clm_ongoing = false;
3429 		}
3430 	}
3431 
3432 	if (set_result)
3433 		ccx->edcca_clm_set_lv = lv;
3434 
3435 	PHYDM_DBG(dm, DBG_ENV_MNTR, "edcca_clm racing success=%d\n",
3436 		  set_result);
3437 	return set_result;
3438 }
3439 
phydm_edcca_clm_trigger(void * dm_void)3440 void phydm_edcca_clm_trigger(void *dm_void)
3441 {
3442 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3443 	struct ccx_info *ccx = &dm->dm_ccx_info;
3444 
3445 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
3446 
3447 	odm_set_bb_reg(dm, R_0x1e5c, BIT(26), 0x0);
3448 	odm_set_bb_reg(dm, R_0x1e5c, BIT(26), 0x1);
3449 
3450 	ccx->edcca_clm_trigger_time = dm->phydm_sys_up_time;
3451 	ccx->edcca_clm_rpt_stamp++;
3452 	ccx->edcca_clm_ongoing = true;
3453 }
3454 
phydm_edcca_clm_get_utility(void * dm_void)3455 void phydm_edcca_clm_get_utility(void *dm_void)
3456 {
3457 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3458 	struct ccx_info *ccx = &dm->dm_ccx_info;
3459 
3460 	ccx->edcca_clm_ratio = phydm_ccx_get_rpt_ratio(dm,
3461 						       ccx->edcca_clm_result,
3462 						       EDCCA_CLM_PERIOD);
3463 }
3464 
3465 boolean
phydm_edcca_clm_get_result(void * dm_void)3466 phydm_edcca_clm_get_result(void *dm_void)
3467 {
3468 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3469 	struct ccx_info *ccx_info = &dm->dm_ccx_info;
3470 	u32 val = 0;
3471 
3472 	if (!(odm_get_bb_reg(dm, R_0x2d8c, BIT(16)))) {
3473 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Get EDCCA_CLM report Fail\n");
3474 		phydm_edcca_clm_racing_release(dm);
3475 		return false;
3476 	}
3477 
3478 	val = odm_get_bb_reg(dm, R_0x2d8c, MASKLWORD);
3479 	ccx_info->edcca_clm_result = (u16)val;
3480 
3481 	PHYDM_DBG(dm, DBG_ENV_MNTR, "EDCCA_CLM result = %d *4 us\n",
3482 		  ccx_info->edcca_clm_result);
3483 	phydm_edcca_clm_racing_release(dm);
3484 	return true;
3485 }
3486 
phydm_edcca_clm_mntr_set(void * dm_void,struct edcca_clm_para_info * para)3487 u8 phydm_edcca_clm_mntr_set(void *dm_void, struct edcca_clm_para_info *para)
3488 {
3489 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3490 	struct ccx_info *ccx = &dm->dm_ccx_info;
3491 
3492 	if (para->edcca_clm_lv >= EDCCA_CLM_MAX_NUM) {
3493 		PHYDM_DBG(dm, DBG_ENV_MNTR, "[WARNING] Wrong LV=%d\n",
3494 			  para->edcca_clm_lv);
3495 		return PHYDM_SET_FAIL;
3496 	}
3497 
3498 	if (phydm_edcca_clm_racing_ctrl(dm, para->edcca_clm_lv) == PHYDM_SET_FAIL)
3499 		return PHYDM_SET_FAIL;
3500 
3501 	ccx->edcca_clm_app = para->edcca_clm_app;
3502 
3503 	return PHYDM_SET_SUCCESS;
3504 }
3505 
3506 boolean
phydm_edcca_clm_mntr_racing_chk(void * dm_void)3507 phydm_edcca_clm_mntr_racing_chk(void *dm_void)
3508 {
3509 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3510 	struct ccx_info *ccx = &dm->dm_ccx_info;
3511 	u32 sys_return_time = 0;
3512 
3513 	if (ccx->edcca_clm_manual_ctrl) {
3514 		PHYDM_DBG(dm, DBG_ENV_MNTR, "EDCCA_CLM in manual ctrl\n");
3515 		return true;
3516 	}
3517 
3518 	sys_return_time = ccx->edcca_clm_trigger_time + MAX_ENV_MNTR_TIME;
3519 
3520 	if (ccx->edcca_clm_app != EDCCA_CLM_BACKGROUND &&
3521 	    (sys_return_time > dm->phydm_sys_up_time)) {
3522 		PHYDM_DBG(dm, DBG_ENV_MNTR,
3523 			  "edcca_clm_app=%d, trigger_time %d, sys_time=%d\n",
3524 			  ccx->edcca_clm_app, ccx->edcca_clm_trigger_time,
3525 			  dm->phydm_sys_up_time);
3526 
3527 		return true;
3528 	}
3529 
3530 	return false;
3531 }
3532 
3533 boolean
phydm_edcca_clm_mntr_chk(void * dm_void)3534 phydm_edcca_clm_mntr_chk(void *dm_void)
3535 {
3536 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3537 	struct ccx_info *ccx = &dm->dm_ccx_info;
3538 	struct edcca_clm_para_info para = {0};
3539 	boolean edcca_clm_chk_result = false;
3540 
3541 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
3542 
3543 	if (phydm_edcca_clm_mntr_racing_chk(dm))
3544 		return edcca_clm_chk_result;
3545 
3546 	/*[EDCCA_CLM trigger setting]----------------------------------------*/
3547 	para.edcca_clm_app = EDCCA_CLM_BACKGROUND;
3548 	para.edcca_clm_lv = EDCCA_CLM_LV_1;
3549 
3550 	edcca_clm_chk_result = phydm_edcca_clm_mntr_set(dm, &para);
3551 
3552 	return edcca_clm_chk_result;
3553 }
3554 
3555 boolean
phydm_edcca_clm_mntr_result(void * dm_void)3556 phydm_edcca_clm_mntr_result(void *dm_void)
3557 {
3558 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3559 	struct ccx_info *ccx = &dm->dm_ccx_info;
3560 	boolean edcca_clm_chk_result = false;
3561 
3562 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
3563 
3564 	if (phydm_edcca_clm_mntr_racing_chk(dm))
3565 		return edcca_clm_chk_result;
3566 
3567 	/*[EDCCA_CLM get result & calculate Utility]-------------------------*/
3568 	if (phydm_edcca_clm_get_result(dm)) {
3569 		PHYDM_DBG(dm, DBG_ENV_MNTR, "Get EDCCA_CLM_rpt success\n");
3570 		phydm_edcca_clm_get_utility(dm);
3571 		edcca_clm_chk_result = true;
3572 	}
3573 
3574 	return edcca_clm_chk_result;
3575 }
3576 
phydm_edcca_clm_init(void * dm_void)3577 void phydm_edcca_clm_init(void *dm_void)
3578 {
3579 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3580 	struct ccx_info *ccx = &dm->dm_ccx_info;
3581 
3582 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
3583 	ccx->edcca_clm_ongoing = false;
3584 	ccx->edcca_clm_manual_ctrl = 0;
3585 	ccx->edcca_clm_rpt_stamp = 0;
3586 }
3587 
phydm_edcca_clm_dbg(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)3588 void phydm_edcca_clm_dbg(void *dm_void, char input[][16], u32 *_used,
3589 			 char *output, u32 *_out_len)
3590 {
3591 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3592 	struct ccx_info *ccx = &dm->dm_ccx_info;
3593 	char help[] = "-h";
3594 	u32 var1[10] = {0};
3595 	u32 used = *_used;
3596 	u32 out_len = *_out_len;
3597 	struct edcca_clm_para_info para = {0};
3598 	u32 i;
3599 
3600 	if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_EDCCA_CLM))
3601 		return;
3602 
3603 	for (i = 0; i < 4; i++) {
3604 		if (input[i + 1])
3605 			PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
3606 	}
3607 
3608 	if ((strcmp(input[1], help) == 0)) {
3609 		PDM_SNPF(out_len, used, output + used, out_len - used,
3610 			 "EDCCA_CLM Basic-Trigger 262ms: {1}\n");
3611 		PDM_SNPF(out_len, used, output + used, out_len - used,
3612 			 "EDCCA_CLM Adv-Trigger 262ms: {2} {app} {LV}\n");
3613 		PDM_SNPF(out_len, used, output + used, out_len - used,
3614 			 "EDCCA_CLM Get Result: {100}\n");
3615 	} else if (var1[0] == 100) {
3616 		if (phydm_edcca_clm_get_result(dm))
3617 			phydm_edcca_clm_get_utility(dm);
3618 
3619 		PDM_SNPF(out_len, used, output + used, out_len - used,
3620 			 "edcca_clm_rpt_stamp=%d\n", ccx->edcca_clm_rpt_stamp);
3621 
3622 		PDM_SNPF(out_len, used, output + used, out_len - used,
3623 			 "edcca_clm_ratio:((%d percent)) = (%d us/ 262140 us)\n",
3624 			 ccx->edcca_clm_ratio, ccx->edcca_clm_result << 2);
3625 
3626 		ccx->edcca_clm_manual_ctrl = 0;
3627 	} else {
3628 		ccx->edcca_clm_manual_ctrl = 1;
3629 
3630 		if (var1[0] == 1) {
3631 			para.edcca_clm_app = EDCCA_CLM_DBG;
3632 			para.edcca_clm_lv = EDCCA_CLM_LV_4;
3633 		} else if (var1[0] == 2) {
3634 			para.edcca_clm_app = (enum edcca_clm_application)var1[1];
3635 			para.edcca_clm_lv = (enum phydm_edcca_clm_level)var1[2];
3636 		}
3637 
3638 		PDM_SNPF(out_len, used, output + used, out_len - used,
3639 			 "app=%d, lv=%d\n", para.edcca_clm_app,
3640 			 para.edcca_clm_lv);
3641 
3642 		if (phydm_edcca_clm_mntr_set(dm, &para) == PHYDM_SET_SUCCESS)
3643 			phydm_edcca_clm_trigger(dm);
3644 
3645 		PDM_SNPF(out_len, used, output + used, out_len - used,
3646 			 "edcca_clm_rpt_stamp=%d\n", ccx->edcca_clm_rpt_stamp);
3647 	}
3648 
3649 	*_used = used;
3650 	*_out_len = out_len;
3651 }
3652 
3653 #endif
3654 
3655 /*Environment Monitor*/
phydm_env_mntr_result_watchdog(void * dm_void)3656 void phydm_env_mntr_result_watchdog(void *dm_void)
3657 {
3658 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3659 	struct ccx_info *ccx = &dm->dm_ccx_info;
3660 
3661 	ccx->ccx_watchdog_result = 0;
3662 
3663 	if (!(dm->support_ability & ODM_BB_ENV_MONITOR))
3664 		return;
3665 
3666 	#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT))
3667 	if (phydm_nhm_mntr_result(dm))
3668 		ccx->ccx_watchdog_result |= NHM_SUCCESS;
3669 
3670 	if (phydm_clm_mntr_result(dm))
3671 		ccx->ccx_watchdog_result |= CLM_SUCCESS;
3672 
3673 	PHYDM_DBG(dm, DBG_ENV_MNTR,
3674 		  "Summary: nhm_ratio=((%d)) clm_ratio=((%d))\n\n",
3675 		  ccx->nhm_ratio, ccx->clm_ratio);
3676 	#endif
3677 
3678 	#ifdef FAHM_SUPPORT
3679 	if (dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) {
3680 		if (phydm_fahm_mntr_result(dm))
3681 			ccx->ccx_watchdog_result |= FAHM_SUCCESS;
3682 	}
3683 	#endif
3684 
3685 	#ifdef IFS_CLM_SUPPORT
3686 	if (dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM) {
3687 		if (phydm_ifs_clm_mntr_result(dm))
3688 			ccx->ccx_watchdog_result |= IFS_CLM_SUCCESS;
3689 	}
3690 	#endif
3691 
3692 	#ifdef EDCCA_CLM_SUPPORT
3693 	if (dm->support_ic_type & PHYDM_IC_SUPPORT_EDCCA_CLM) {
3694 		if (phydm_edcca_clm_mntr_result(dm))
3695 			ccx->ccx_watchdog_result |= EDCCA_CLM_SUCCESS;
3696 	}
3697 	#endif
3698 }
3699 
phydm_env_mntr_set_watchdog(void * dm_void)3700 void phydm_env_mntr_set_watchdog(void *dm_void)
3701 {
3702 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3703 	struct ccx_info *ccx = &dm->dm_ccx_info;
3704 
3705 	if (!(dm->support_ability & ODM_BB_ENV_MONITOR))
3706 		return;
3707 
3708 	PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);
3709 
3710 	#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT))
3711 	if (phydm_nhm_mntr_chk(dm, 262))
3712 		phydm_nhm_trigger(dm);
3713 
3714 	if (phydm_clm_mntr_chk(dm, 262))
3715 		phydm_clm_trigger(dm);
3716 	#endif
3717 
3718 	#ifdef FAHM_SUPPORT
3719 	if (dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) {
3720 		if (phydm_fahm_mntr_chk(dm, 262))
3721 			phydm_fahm_trigger(dm);
3722 	}
3723 	#endif
3724 
3725 	#ifdef IFS_CLM_SUPPORT
3726 	if (dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM) {
3727 		if (phydm_ifs_clm_mntr_chk(dm, 960))
3728 			phydm_ifs_clm_trigger(dm);
3729 	}
3730 	#endif
3731 
3732 	#ifdef EDCCA_CLM_SUPPORT
3733 	if (dm->support_ic_type & PHYDM_IC_SUPPORT_EDCCA_CLM) {
3734 		if (phydm_edcca_clm_mntr_chk(dm))
3735 			phydm_edcca_clm_trigger(dm);
3736 	}
3737 	#endif
3738 }
3739 
phydm_env_monitor_init(void * dm_void)3740 void phydm_env_monitor_init(void *dm_void)
3741 {
3742 	struct dm_struct *dm = (struct dm_struct *)dm_void;
3743 	#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT))
3744 	phydm_ccx_hw_restart(dm);
3745 	phydm_nhm_init(dm);
3746 	phydm_clm_init(dm);
3747 	#endif
3748 
3749 	#ifdef FAHM_SUPPORT
3750 	phydm_fahm_init(dm);
3751 	#endif
3752 
3753 	#ifdef IFS_CLM_SUPPORT
3754 	if (dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM) {
3755 		phydm_ifs_clm_restart(dm);
3756 		phydm_ifs_clm_init(dm);
3757 	}
3758 	#endif
3759 
3760 	#ifdef EDCCA_CLM_SUPPORT
3761 	if (dm->support_ic_type & PHYDM_IC_SUPPORT_EDCCA_CLM)
3762 		phydm_edcca_clm_init(dm);
3763 	#endif
3764 }
3765 
3766