xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8821cs/hal/phydm/phydm_pow_train.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017  Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25 
26 /*************************************************************
27  * include files
28  ************************************************************/
29 
30 #include "mp_precomp.h"
31 #include "phydm_precomp.h"
32 
33 #ifdef PHYDM_POWER_TRAINING_SUPPORT
phydm_reset_pt_para(void * dm_void)34 void phydm_reset_pt_para(void *dm_void)
35 {
36 	struct dm_struct *dm = (struct dm_struct *)dm_void;
37 	struct phydm_pow_train_stuc *pt_t = &dm->pow_train_table;
38 
39 	pt_t->pow_train_score = 0;
40 }
41 
phydm_update_power_training_state(void * dm_void)42 void phydm_update_power_training_state(void *dm_void)
43 {
44 	struct dm_struct *dm = (struct dm_struct *)dm_void;
45 	struct phydm_pow_train_stuc *pt_t = &dm->pow_train_table;
46 	struct phydm_fa_struct *fa_cnt = &dm->false_alm_cnt;
47 	struct ccx_info *ccx = &dm->dm_ccx_info;
48 	u32 pt_score_tmp = ENABLE_PT_SCORE;
49 	u32 crc_ok_cnt = 0;
50 	u32 cca_cnt = 0;
51 
52 	/*@is_disable_power_training is the key to H2C to disable/enable PT*/
53 	/*@if is_disable_power_training == 1, it will use largest power*/
54 	if (!(dm->support_ability & ODM_BB_PWR_TRAIN) || !dm->is_linked) {
55 		dm->is_disable_power_training = true;
56 		phydm_reset_pt_para(dm);
57 		return;
58 	}
59 
60 	PHYDM_DBG(dm, DBG_PWR_TRAIN, "%s ======>\n", __func__);
61 
62 	if (pt_t->pt_state == DISABLE_POW_TRAIN) {
63 		dm->is_disable_power_training = true;
64 		phydm_reset_pt_para(dm);
65 		PHYDM_DBG(dm, DBG_PWR_TRAIN, "Disable PT\n");
66 		return;
67 
68 	} else if (pt_t->pt_state == ENABLE_POW_TRAIN) {
69 		dm->is_disable_power_training = false;
70 		phydm_reset_pt_para(dm);
71 		PHYDM_DBG(dm, DBG_PWR_TRAIN, "Enable PT\n");
72 		return;
73 
74 	} else if (pt_t->pt_state == DYNAMIC_POW_TRAIN) {
75 		PHYDM_DBG(dm, DBG_PWR_TRAIN, "Dynamic PT\n");
76 
77 		/* @Compute score */
78 		crc_ok_cnt = dm->phy_dbg_info.num_qry_phy_status_ofdm +
79 			     dm->phy_dbg_info.num_qry_phy_status_cck;
80 		cca_cnt = fa_cnt->cnt_cca_all;
81 #if 0
82 		if (crc_ok_cnt > cca_cnt) { /*invalid situation*/
83 			pt_score_tmp = KEEP_PRE_PT_SCORE;
84 			return;
85 		} else if ((crc_ok_cnt + (crc_ok_cnt >> 1)) <= cca_cnt) {
86 		/* @???crc_ok <= (2/3)*cca */
87 			pt_score_tmp = DISABLE_PT_SCORE;
88 			dm->is_disable_power_training = true;
89 		} else if ((crc_ok_cnt + (crc_ok_cnt >> 2)) <= cca_cnt) {
90 		/* @???crc_ok <= (4/5)*cca */
91 			pt_score_tmp = KEEP_PRE_PT_SCORE;
92 		} else {
93 		/* @???crc_ok > (4/5)*cca */
94 			pt_score_tmp = ENABLE_PT_SCORE;
95 			dm->is_disable_power_training = false;
96 		}
97 #endif
98 		if (ccx->nhm_ratio > 10) {
99 			pt_score_tmp = DISABLE_PT_SCORE;
100 			dm->is_disable_power_training = true;
101 		} else if (ccx->nhm_ratio < 5) {
102 			pt_score_tmp = ENABLE_PT_SCORE;
103 			dm->is_disable_power_training = false;
104 		} else {
105 			pt_score_tmp = KEEP_PRE_PT_SCORE;
106 		}
107 
108 		PHYDM_DBG(dm, DBG_PWR_TRAIN,
109 			  "pkt_cnt{ofdm,cck,all} = {%d, %d, %d}, cnt_cca_all=%d\n",
110 			  dm->phy_dbg_info.num_qry_phy_status_ofdm,
111 			  dm->phy_dbg_info.num_qry_phy_status_cck,
112 			  crc_ok_cnt, cca_cnt);
113 
114 		PHYDM_DBG(dm, DBG_PWR_TRAIN, "pt_score_tmp=%d\n", pt_score_tmp);
115 
116 		/* smoothing */
117 		pt_t->pow_train_score = (pt_score_tmp << 4) +
118 					(pt_t->pow_train_score >> 1) +
119 					(pt_t->pow_train_score >> 2);
120 
121 		pt_score_tmp = (pt_t->pow_train_score + 32) >> 6;
122 
123 		PHYDM_DBG(dm, DBG_PWR_TRAIN,
124 			  "pow_train_score = %d, score after smoothing = %d, is_disable_PT = %d\n",
125 			  pt_t->pow_train_score, pt_score_tmp,
126 			  dm->is_disable_power_training);
127 	} else {
128 		PHYDM_DBG(dm, DBG_PWR_TRAIN, "[%s]warning\n", __func__);
129 	}
130 }
131 
phydm_pow_train_debug(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)132 void phydm_pow_train_debug(
133 	void *dm_void,
134 	char input[][16],
135 	u32 *_used,
136 	char *output,
137 	u32 *_out_len)
138 {
139 	struct dm_struct *dm = (struct dm_struct *)dm_void;
140 	struct phydm_pow_train_stuc *pt_t = &dm->pow_train_table;
141 	char help[] = "-h";
142 	u32 var1[10] = {0};
143 	u32 used = *_used;
144 	u32 out_len = *_out_len;
145 	u32 i;
146 
147 	if ((strcmp(input[1], help) == 0)) {
148 		PDM_SNPF(out_len, used, output + used, out_len - used,
149 			 "{0: Auto PT, 1:enable, 2: disable}\n");
150 	} else {
151 		for (i = 0; i < 10; i++) {
152 			if (input[i + 1])
153 				PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
154 		}
155 
156 		if (var1[0] == 0)
157 			pt_t->pt_state = DYNAMIC_POW_TRAIN;
158 		else if (var1[0] == 1)
159 			pt_t->pt_state = ENABLE_POW_TRAIN;
160 		else if (var1[0] == 2)
161 			pt_t->pt_state = DISABLE_POW_TRAIN;
162 
163 		PDM_SNPF(out_len, used, output + used, out_len - used,
164 			 "PT state = %d\n", pt_t->pt_state);
165 	}
166 
167 	*_used = used;
168 	*_out_len = out_len;
169 }
170 
171 #endif
172