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