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 *****************************************************************************/
15
16 #include "mp_precomp.h"
17 #include "phydm_precomp.h"
18
19 /*Set NHM period, threshold, disable ignore cca or not, disable ignore txon or not*/
20 void
phydm_nhm_init(void * p_dm_void)21 phydm_nhm_init(
22 void *p_dm_void
23 )
24 {
25 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
26 struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info;
27
28 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__));
29 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("cur_ig_value=0x%x\n", p_dm->dm_dig_table.cur_ig_value));
30
31 phydm_set_nhm_th_by_igi(p_dm, p_dm->dm_dig_table.cur_ig_value);
32
33 ccx_info->nhm_period = 0xC350;
34 ccx_info->nhm_inexclude_cca = NHM_EXCLUDE_CCA;
35 ccx_info->nhm_inexclude_txon = NHM_EXCLUDE_TXON;
36
37 phydm_nhm_setting(p_dm, SET_NHM_SETTING);
38 }
39
40 boolean
phydm_cal_nhm_cnt(void * p_dm_void)41 phydm_cal_nhm_cnt(
42 void *p_dm_void
43 )
44 {
45 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
46 struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info;
47 u8 noisy_nhm_th_index, low_pwr_cnt = 0, high_pwr_cnt = 0;
48 u8 noisy_nhm_th = 0x52;
49 u8 i;
50 boolean noisy = false, clean = true;
51
52 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__));
53
54 if (!(p_dm->support_ability & ODM_BB_ENV_MONITOR))
55 return noisy;
56
57 /*nhm_th = 0x52 means 0x52/2-110 = -69dbm*/
58 /* IGI < 0x14 */
59 if (ccx_info->nhm_th[10] < noisy_nhm_th)
60 return clean;
61 else if (ccx_info->nhm_th[0] > noisy_nhm_th)
62 return (p_dm->noisy_decision) ? noisy : clean;
63 /* 0x14 <= IGI <= 0x37*/
64 else {
65 /* search index */
66 noisy_nhm_th_index = (noisy_nhm_th - ccx_info->nhm_th[0]) << 2;
67
68 for (i = 0; i <= 11; i++) {
69 if (i <= noisy_nhm_th_index)
70 low_pwr_cnt += ccx_info->nhm_result[i];
71 else
72 high_pwr_cnt += ccx_info->nhm_result[i];
73 }
74
75 if (low_pwr_cnt + high_pwr_cnt == 0)
76 return noisy; /* noisy environment */
77 else if (low_pwr_cnt - high_pwr_cnt >= 100)
78 return clean; /* clean environment */
79 else
80 return noisy; /* noisy environment */
81 }
82 }
83
84 void
phydm_nhm_setting(void * p_dm_void,u8 nhm_setting)85 phydm_nhm_setting(
86 void *p_dm_void,
87 u8 nhm_setting
88 )
89 {
90 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
91 struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info;
92
93 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__));
94
95 if (nhm_setting == SET_NHM_SETTING) {
96 PHYDM_DBG(p_dm, DBG_ENV_MNTR,
97 ("nhm_th=(H->L)[0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x]\n",
98 ccx_info->nhm_th[10], ccx_info->nhm_th[9], ccx_info->nhm_th[8],
99 ccx_info->nhm_th[7], ccx_info->nhm_th[6], ccx_info->nhm_th[5],
100 ccx_info->nhm_th[4], ccx_info->nhm_th[3], ccx_info->nhm_th[2],
101 ccx_info->nhm_th[1], ccx_info->nhm_th[0]));
102 }
103
104 if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) {
105
106 if (nhm_setting == SET_NHM_SETTING) {
107
108 /*Set inexclude_cca, inexclude_txon*/
109 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9), ccx_info->nhm_inexclude_cca);
110 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10), ccx_info->nhm_inexclude_txon);
111
112 /*Set NHM period*/
113 odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD, ccx_info->nhm_period);
114
115 /*Set NHM threshold*/ /*Unit: PWdB U(8,1)*/
116 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0, ccx_info->nhm_th[0]);
117 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1, ccx_info->nhm_th[1]);
118 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2, ccx_info->nhm_th[2]);
119 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3, ccx_info->nhm_th[3]);
120 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0, ccx_info->nhm_th[4]);
121 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1, ccx_info->nhm_th[5]);
122 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2, ccx_info->nhm_th[6]);
123 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3, ccx_info->nhm_th[7]);
124 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0, ccx_info->nhm_th[8]);
125 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2, ccx_info->nhm_th[9]);
126 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3, ccx_info->nhm_th[10]);
127
128 /*CCX EN*/
129 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(8), CCX_EN);
130
131 } else if (nhm_setting == STORE_NHM_SETTING) {
132
133 /*Store pervious disable_ignore_cca, disable_ignore_txon*/
134 ccx_info->nhm_inexclude_cca_restore = (enum nhm_inexclude_cca)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9));
135 ccx_info->nhm_inexclude_txon_restore = (enum nhm_inexclude_txon)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10));
136
137 /*Store pervious NHM period*/
138 ccx_info->nhm_period_restore = (u16)odm_get_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD);
139
140 /*Store NHM threshold*/
141 ccx_info->nhm_th_restore[0] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0);
142 ccx_info->nhm_th_restore[1] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1);
143 ccx_info->nhm_th_restore[2] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2);
144 ccx_info->nhm_th_restore[3] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3);
145 ccx_info->nhm_th_restore[4] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0);
146 ccx_info->nhm_th_restore[5] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1);
147 ccx_info->nhm_th_restore[6] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2);
148 ccx_info->nhm_th_restore[7] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3);
149 ccx_info->nhm_th_restore[8] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0);
150 ccx_info->nhm_th_restore[9] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2);
151 ccx_info->nhm_th_restore[10] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3);
152 } else if (nhm_setting == RESTORE_NHM_SETTING) {
153
154 /*Set disable_ignore_cca, disable_ignore_txon*/
155 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9), ccx_info->nhm_inexclude_cca_restore);
156 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10), ccx_info->nhm_inexclude_txon_restore);
157
158 /*Set NHM period*/
159 odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD, ccx_info->nhm_period);
160
161 /*Set NHM threshold*/
162 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0, ccx_info->nhm_th_restore[0]);
163 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1, ccx_info->nhm_th_restore[1]);
164 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2, ccx_info->nhm_th_restore[2]);
165 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3, ccx_info->nhm_th_restore[3]);
166 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0, ccx_info->nhm_th_restore[4]);
167 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1, ccx_info->nhm_th_restore[5]);
168 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2, ccx_info->nhm_th_restore[6]);
169 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3, ccx_info->nhm_th_restore[7]);
170 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0, ccx_info->nhm_th_restore[8]);
171 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2, ccx_info->nhm_th_restore[9]);
172 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3, ccx_info->nhm_th_restore[10]);
173 } else
174 return;
175 }
176
177 else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) {
178
179 if (nhm_setting == SET_NHM_SETTING) {
180
181 /*Set disable_ignore_cca, disable_ignore_txon*/
182 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(9), ccx_info->nhm_inexclude_cca);
183 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(10), ccx_info->nhm_inexclude_txon);
184
185 /*Set NHM period*/
186 odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11N, MASKHWORD, ccx_info->nhm_period);
187
188 /*Set NHM threshold*/
189 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0, ccx_info->nhm_th[0]);
190 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1, ccx_info->nhm_th[1]);
191 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2, ccx_info->nhm_th[2]);
192 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3, ccx_info->nhm_th[3]);
193 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0, ccx_info->nhm_th[4]);
194 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1, ccx_info->nhm_th[5]);
195 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2, ccx_info->nhm_th[6]);
196 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3, ccx_info->nhm_th[7]);
197 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH8_11N, MASKBYTE0, ccx_info->nhm_th[8]);
198 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2, ccx_info->nhm_th[9]);
199 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3, ccx_info->nhm_th[10]);
200
201 /*CCX EN*/
202 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(8), CCX_EN);
203 } else if (nhm_setting == STORE_NHM_SETTING) {
204
205 /*Store pervious disable_ignore_cca, disable_ignore_txon*/
206 ccx_info->nhm_inexclude_cca_restore = (enum nhm_inexclude_cca)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(9));
207 ccx_info->nhm_inexclude_txon_restore = (enum nhm_inexclude_txon)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(10));
208
209 /*Store pervious NHM period*/
210 ccx_info->nhm_period_restore = (u16)odm_get_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11N, MASKHWORD);
211
212 /*Store NHM threshold*/
213 ccx_info->nhm_th_restore[0] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0);
214 ccx_info->nhm_th_restore[1] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1);
215 ccx_info->nhm_th_restore[2] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2);
216 ccx_info->nhm_th_restore[3] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3);
217 ccx_info->nhm_th_restore[4] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0);
218 ccx_info->nhm_th_restore[5] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1);
219 ccx_info->nhm_th_restore[6] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2);
220 ccx_info->nhm_th_restore[7] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3);
221 ccx_info->nhm_th_restore[8] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH8_11N, MASKBYTE0);
222 ccx_info->nhm_th_restore[9] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2);
223 ccx_info->nhm_th_restore[10] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3);
224
225 } else if (nhm_setting == RESTORE_NHM_SETTING) {
226
227 /*Set disable_ignore_cca, disable_ignore_txon*/
228 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(9), ccx_info->nhm_inexclude_cca_restore);
229 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(10), ccx_info->nhm_inexclude_txon_restore);
230
231 /*Set NHM period*/
232 odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11N, MASKHWORD, ccx_info->nhm_period_restore);
233
234 /*Set NHM threshold*/
235 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0, ccx_info->nhm_th_restore[0]);
236 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1, ccx_info->nhm_th_restore[1]);
237 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2, ccx_info->nhm_th_restore[2]);
238 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3, ccx_info->nhm_th_restore[3]);
239 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0, ccx_info->nhm_th_restore[4]);
240 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1, ccx_info->nhm_th_restore[5]);
241 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2, ccx_info->nhm_th_restore[6]);
242 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3, ccx_info->nhm_th_restore[7]);
243 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH8_11N, MASKBYTE0, ccx_info->nhm_th_restore[8]);
244 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2, ccx_info->nhm_th_restore[9]);
245 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3, ccx_info->nhm_th_restore[10]);
246 } else
247 return;
248
249 }
250 }
251
252 void
phydm_nhm_trigger(void * p_dm_void)253 phydm_nhm_trigger(
254 void *p_dm_void
255 )
256 {
257 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
258
259 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__));
260
261 if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) {
262
263 /*Trigger NHM*/
264 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 0);
265 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 1);
266 } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) {
267
268 /*Trigger NHM*/
269 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 0);
270 odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 1);
271 }
272 }
273
274 void
phydm_get_nhm_result(void * p_dm_void)275 phydm_get_nhm_result(
276 void *p_dm_void
277 )
278 {
279 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
280 struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info;
281 u32 value32;
282 u8 i;
283
284 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__));
285
286 if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) {
287
288 value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT_11AC);
289 ccx_info->nhm_result[0] = (u8)(value32 & MASKBYTE0);
290 ccx_info->nhm_result[1] = (u8)((value32 & MASKBYTE1) >> 8);
291 ccx_info->nhm_result[2] = (u8)((value32 & MASKBYTE2) >> 16);
292 ccx_info->nhm_result[3] = (u8)((value32 & MASKBYTE3) >> 24);
293
294 value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT7_TO_CNT4_11AC);
295 ccx_info->nhm_result[4] = (u8)(value32 & MASKBYTE0);
296 ccx_info->nhm_result[5] = (u8)((value32 & MASKBYTE1) >> 8);
297 ccx_info->nhm_result[6] = (u8)((value32 & MASKBYTE2) >> 16);
298 ccx_info->nhm_result[7] = (u8)((value32 & MASKBYTE3) >> 24);
299
300 value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT11_TO_CNT8_11AC);
301 ccx_info->nhm_result[8] = (u8)(value32 & MASKBYTE0);
302 ccx_info->nhm_result[9] = (u8)((value32 & MASKBYTE1) >> 8);
303 ccx_info->nhm_result[10] = (u8)((value32 & MASKBYTE2) >> 16);
304 ccx_info->nhm_result[11] = (u8)((value32 & MASKBYTE3) >> 24);
305
306 /*Get NHM duration*/
307 value32 = odm_read_4byte(p_dm, ODM_REG_NHM_DUR_READY_11AC);
308 ccx_info->nhm_duration = (u16)(value32 & MASKLWORD);
309
310 }
311
312 else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) {
313
314 value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT_11N);
315 ccx_info->nhm_result[0] = (u8)(value32 & MASKBYTE0);
316 ccx_info->nhm_result[1] = (u8)((value32 & MASKBYTE1) >> 8);
317 ccx_info->nhm_result[2] = (u8)((value32 & MASKBYTE2) >> 16);
318 ccx_info->nhm_result[3] = (u8)((value32 & MASKBYTE3) >> 24);
319
320 value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT7_TO_CNT4_11N);
321 ccx_info->nhm_result[4] = (u8)(value32 & MASKBYTE0);
322 ccx_info->nhm_result[5] = (u8)((value32 & MASKBYTE1) >> 8);
323 ccx_info->nhm_result[6] = (u8)((value32 & MASKBYTE2) >> 16);
324 ccx_info->nhm_result[7] = (u8)((value32 & MASKBYTE3) >> 24);
325
326 value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT9_TO_CNT8_11N);
327 ccx_info->nhm_result[8] = (u8)((value32 & MASKBYTE2) >> 16);
328 ccx_info->nhm_result[9] = (u8)((value32 & MASKBYTE3) >> 24);
329
330 value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT10_TO_CNT11_11N);
331 ccx_info->nhm_result[10] = (u8)((value32 & MASKBYTE2) >> 16);
332 ccx_info->nhm_result[11] = (u8)((value32 & MASKBYTE3) >> 24);
333
334 /*Get NHM duration*/
335 value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT10_TO_CNT11_11N);
336 ccx_info->nhm_duration = (u16)(value32 & MASKLWORD);
337
338 }
339
340 /* sum all nhm_result */
341 ccx_info->nhm_result_total = 0;
342 for (i = 0; i <= 11; i++)
343 ccx_info->nhm_result_total += ccx_info->nhm_result[i];
344
345 PHYDM_DBG(p_dm, DBG_ENV_MNTR,
346 ("nhm_result=(H->L)[%d %d %d %d (igi) %d %d %d %d %d %d %d %d]\n",
347 ccx_info->nhm_result[11], ccx_info->nhm_result[10], ccx_info->nhm_result[9],
348 ccx_info->nhm_result[8], ccx_info->nhm_result[7], ccx_info->nhm_result[6],
349 ccx_info->nhm_result[5], ccx_info->nhm_result[4], ccx_info->nhm_result[3],
350 ccx_info->nhm_result[2], ccx_info->nhm_result[1], ccx_info->nhm_result[0]));
351 }
352
353 boolean
phydm_check_nhm_rdy(void * p_dm_void)354 phydm_check_nhm_rdy(
355 void *p_dm_void
356 )
357 {
358 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
359 u8 i;
360 boolean is_ready = false;
361
362 if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) {
363
364 for (i = 0; i < 200; i++) {
365 ODM_delay_ms(1);
366 if (odm_get_bb_reg(p_dm, ODM_REG_NHM_DUR_READY_11AC, BIT(16))) {
367 is_ready = 1;
368 break;
369 }
370 }
371 }
372
373 else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) {
374
375 for (i = 0; i < 200; i++) {
376 ODM_delay_ms(1);
377 if (odm_get_bb_reg(p_dm, ODM_REG_NHM_DUR_READY_11AC, BIT(17))) {
378 is_ready = 1;
379 break;
380 }
381 }
382 }
383 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]NHM rdy=%d\n", __FUNCTION__, is_ready));
384 return is_ready;
385 }
386
387 void
phydm_store_nhm_setting(void * p_dm_void)388 phydm_store_nhm_setting(
389 void *p_dm_void
390 )
391 {
392 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
393
394 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__));
395
396 if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) {
397
398
399 } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) {
400
401
402
403 }
404 }
405
406 void
phydm_clm_setting(void * p_dm_void)407 phydm_clm_setting(
408 void *p_dm_void
409 )
410 {
411 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
412 struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info;
413
414 if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) {
415
416 odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11AC, MASKLWORD, ccx_info->clm_period); /*4us sample 1 time*/
417 odm_set_bb_reg(p_dm, ODM_REG_CLM_11AC, BIT(8), 0x1); /*Enable CCX for CLM*/
418
419 } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) {
420
421 odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11N, MASKLWORD, ccx_info->clm_period);
422 odm_set_bb_reg(p_dm, ODM_REG_CLM_11N, BIT(8), 0x1); /*Enable CCX for CLM*/
423 }
424
425 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]CLM period=%dus\n", __func__, ccx_info->clm_period * 4));
426
427 }
428
429 void
phydm_clm_trigger(void * p_dm_void)430 phydm_clm_trigger(
431 void *p_dm_void
432 )
433 {
434 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
435
436 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__));
437
438 if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) {
439 odm_set_bb_reg(p_dm, ODM_REG_CLM_11AC, BIT(0), 0x0); /*Trigger CLM*/
440 odm_set_bb_reg(p_dm, ODM_REG_CLM_11AC, BIT(0), 0x1);
441 } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) {
442 odm_set_bb_reg(p_dm, ODM_REG_CLM_11N, BIT(0), 0x0); /*Trigger CLM*/
443 odm_set_bb_reg(p_dm, ODM_REG_CLM_11N, BIT(0), 0x1);
444 }
445 }
446
447 boolean
phydm_check_clm_rdy(void * p_dm_void)448 phydm_check_clm_rdy(
449 void *p_dm_void
450 )
451 {
452 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
453 boolean is_ready = false;
454 u8 i;
455
456 if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) {
457 for (i = 0; i < 200; i++) {
458 ODM_delay_ms(1);
459 if (odm_get_bb_reg(p_dm, ODM_REG_CLM_RESULT_11AC, BIT(16))) {
460 is_ready = 1;
461 break;
462 }
463 }
464 } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) {
465 for (i = 0; i < 200; i++) {
466 ODM_delay_ms(1);
467 if (odm_get_bb_reg(p_dm, ODM_REG_CLM_READY_11N, BIT(16))) {
468 is_ready = 1;
469 break;
470 }
471 }
472 }
473 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]CLM rdy=%d\n", __FUNCTION__, is_ready));
474 return is_ready;
475 }
476
477 void
phydm_get_clm_result(void * p_dm_void)478 phydm_get_clm_result(
479 void *p_dm_void
480 )
481 {
482 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
483 struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info;
484
485 u32 value32 = 0;
486
487 if (p_dm->support_ic_type & ODM_IC_11AC_SERIES)
488 value32 = odm_get_bb_reg(p_dm, ODM_REG_CLM_RESULT_11AC, MASKDWORD);
489 else if (p_dm->support_ic_type & ODM_IC_11N_SERIES)
490 value32 = odm_get_bb_reg(p_dm, ODM_REG_CLM_RESULT_11N, MASKDWORD);
491
492 ccx_info->clm_result = (u16)(value32 & MASKLWORD);
493
494 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]CLM result = %dus\n", __func__, ccx_info->clm_result * 4));
495
496 }
497
498 void
phydm_ccx_monitor(void * p_dm_void)499 phydm_ccx_monitor(
500 void *p_dm_void
501 )
502 {
503 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
504
505 if (!(p_dm->support_ability & ODM_BB_ENV_MONITOR))
506 return;
507
508 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__));
509
510 phydm_ccx_monitor_result(p_dm);
511 phydm_ccx_monitor_trigger(p_dm, (u16)0xC350); /*monitor 200ms*/
512 }
513
514 void
phydm_ccx_monitor_trigger(void * p_dm_void,u16 monitor_time)515 phydm_ccx_monitor_trigger(
516 void *p_dm_void,
517 u16 monitor_time /*unit 4us*/
518 )
519 {
520 u8 nhm_th[11], i, igi;
521 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
522 struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info;
523
524 if (!(p_dm->support_ability & ODM_BB_ENV_MONITOR))
525 return;
526
527 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__));
528
529 /* check if NHM threshold is changed */
530 if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) {
531
532 nhm_th[0] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0);
533 nhm_th[1] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1);
534 nhm_th[2] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2);
535 nhm_th[3] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3);
536 nhm_th[4] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0);
537 nhm_th[5] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1);
538 nhm_th[6] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2);
539 nhm_th[7] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3);
540 nhm_th[8] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0);
541 nhm_th[9] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2);
542 nhm_th[10] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3);
543 } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) {
544
545 nhm_th[0] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0);
546 nhm_th[1] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1);
547 nhm_th[2] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2);
548 nhm_th[3] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3);
549 nhm_th[4] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0);
550 nhm_th[5] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1);
551 nhm_th[6] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2);
552 nhm_th[7] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3);
553 nhm_th[8] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH8_11N, MASKBYTE0);
554 nhm_th[9] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2);
555 nhm_th[10] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3);
556 }
557
558 for (i = 0; i <= 10; i++) {
559
560 if (nhm_th[i] != ccx_info->nhm_th[i]) {
561 PHYDM_DBG(p_dm, DBG_ENV_MNTR,
562 ("nhm_th[%d] != ccx_info->nhm_th[%d]!!\n", i, i));
563 }
564 }
565
566 igi = (u8)odm_get_bb_reg(p_dm, 0xC50, MASKBYTE0);
567 phydm_set_nhm_th_by_igi(p_dm, igi);
568
569 ccx_info->nhm_period = monitor_time;
570 ccx_info->nhm_inexclude_cca = NHM_EXCLUDE_CCA;
571 ccx_info->nhm_inexclude_txon = NHM_EXCLUDE_TXON;
572
573 phydm_nhm_setting(p_dm, SET_NHM_SETTING);
574 phydm_nhm_trigger(p_dm);
575
576 ccx_info->echo_clm_en = true;
577 ccx_info->clm_period = monitor_time;
578 phydm_clm_setting(p_dm);
579 phydm_clm_trigger(p_dm);
580
581 }
582
583 void
phydm_ccx_monitor_result(void * p_dm_void)584 phydm_ccx_monitor_result(
585 void *p_dm_void
586 )
587 {
588 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
589 struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info;
590 u32 nhm_ratio = 0, clm_ratio = 0;
591
592 if (!(p_dm->support_ability & ODM_BB_ENV_MONITOR))
593 return;
594
595 if (phydm_check_nhm_rdy(p_dm))
596 phydm_get_nhm_result(p_dm);
597
598 if (phydm_check_clm_rdy(p_dm))
599 phydm_get_clm_result(p_dm);
600
601 if (ccx_info->clm_period != 0)
602 clm_ratio = (ccx_info->clm_result*100) / ccx_info->clm_period;
603
604 if (ccx_info->nhm_result_total != 0)
605 nhm_ratio = ((ccx_info->nhm_result_total - ccx_info->nhm_result[0])*100) >> 8;
606
607 ccx_info->clm_ratio = (u8)clm_ratio;
608 ccx_info->nhm_ratio = (u8)nhm_ratio;
609
610 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]echo_igi=0x%x, nhm_ratio=%d, clm_ratio=%d\n",
611 __FUNCTION__, ccx_info->echo_igi, nhm_ratio, clm_ratio));
612
613 }
614
615 void
phydm_set_nhm_th_by_igi(void * p_dm_void,u8 igi)616 phydm_set_nhm_th_by_igi(
617 void *p_dm_void,
618 u8 igi
619 )
620 {
621 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
622 struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info;
623 u8 i;
624
625 ccx_info->echo_igi = igi;
626 ccx_info->nhm_th[0] = (ccx_info->echo_igi - CCA_CAP) * IGI_TO_NHM_TH_MULTIPLIER;
627 for (i = 1; i <= 10; i++)
628 ccx_info->nhm_th[i] = ccx_info->nhm_th[0] + 2 * IGI_TO_NHM_TH_MULTIPLIER * i;
629
630 PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]echo_igi=0x%x\n", __FUNCTION__, ccx_info->echo_igi));
631 }
632
633