xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8188fu/hal/phydm/phydm_soml.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 CONFIG_ADAPTIVE_SOML
34 
phydm_dynamicsoftmletting(void * dm_void)35 void phydm_dynamicsoftmletting(void *dm_void)
36 {
37 	struct dm_struct *dm = (struct dm_struct *)dm_void;
38 	u32 ret_val;
39 
40 #if (RTL8822B_SUPPORT == 1)
41 	if (!*dm->mp_mode) {
42 		if (dm->support_ic_type & ODM_RTL8822B) {
43 			if (!dm->is_linked | dm->iot_table.is_linked_cmw500)
44 				return;
45 
46 			if (dm->bsomlenabled) {
47 				PHYDM_DBG(dm, ODM_COMP_API,
48 					  "PHYDM_DynamicSoftMLSetting(): SoML has been enable, skip dynamic SoML switch\n");
49 				return;
50 			}
51 
52 			ret_val = odm_get_bb_reg(dm, R_0xf8c, MASKBYTE0);
53 			PHYDM_DBG(dm, ODM_COMP_API,
54 				  "PHYDM_DynamicSoftMLSetting(): Read 0xF8C = 0x%08X\n",
55 				  ret_val);
56 
57 			if (ret_val < 0x16) {
58 				PHYDM_DBG(dm, ODM_COMP_API,
59 					  "PHYDM_DynamicSoftMLSetting(): 0xF8C(== 0x%08X) < 0x16, enable SoML\n",
60 					  ret_val);
61 				phydm_somlrxhp_setting(dm, true);
62 #if 0
63 			/*odm_set_bb_reg(dm, R_0x19a8, MASKDWORD, 0xc10a0000);*/
64 #endif
65 				dm->bsomlenabled = true;
66 			}
67 		}
68 	}
69 #endif
70 }
71 
phydm_soml_on_off(void * dm_void,u8 swch)72 void phydm_soml_on_off(void *dm_void, u8 swch)
73 {
74 	struct dm_struct *dm = (struct dm_struct *)dm_void;
75 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
76 
77 	if (swch == SOML_ON) {
78 		PHYDM_DBG(dm, DBG_ADPTV_SOML, "(( Turn on )) SOML\n");
79 
80 		if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F))
81 			odm_set_bb_reg(dm, R_0x998, BIT(6), swch);
82 #if (RTL8822B_SUPPORT == 1)
83 		else if (dm->support_ic_type == ODM_RTL8822B)
84 			phydm_somlrxhp_setting(dm, true);
85 #endif
86 
87 	} else if (swch == SOML_OFF) {
88 		PHYDM_DBG(dm, DBG_ADPTV_SOML, "(( Turn off )) SOML\n");
89 
90 		if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F))
91 			odm_set_bb_reg(dm, R_0x998, BIT(6), swch);
92 #if (RTL8822B_SUPPORT == 1)
93 		else if (dm->support_ic_type == ODM_RTL8822B)
94 			phydm_somlrxhp_setting(dm, false);
95 #endif
96 	}
97 	soml_tab->soml_on_off = swch;
98 }
99 
100 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
phydm_adaptive_soml_callback(struct phydm_timer_list * timer)101 void phydm_adaptive_soml_callback(struct phydm_timer_list *timer)
102 {
103 	void *adapter = (void *)timer->Adapter;
104 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
105 	struct dm_struct *dm = &hal_data->DM_OutSrc;
106 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
107 
108 	#if DEV_BUS_TYPE == RT_PCI_INTERFACE
109 	#if USE_WORKITEM
110 	odm_schedule_work_item(&soml_tab->phydm_adaptive_soml_workitem);
111 	#else
112 	{
113 #if 0
114 		/*@dbg_print("%s\n",__func__);*/
115 #endif
116 		phydm_adsl(dm);
117 	}
118 	#endif
119 	#else
120 	odm_schedule_work_item(&soml_tab->phydm_adaptive_soml_workitem);
121 	#endif
122 }
123 
phydm_adaptive_soml_workitem_callback(void * context)124 void phydm_adaptive_soml_workitem_callback(void *context)
125 {
126 #ifdef CONFIG_ADAPTIVE_SOML
127 	void *adapter = (void *)context;
128 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
129 	struct dm_struct *dm = &hal_data->DM_OutSrc;
130 
131 #if 0
132 	/*@dbg_print("%s\n",__func__);*/
133 #endif
134 	phydm_adsl(dm);
135 #endif
136 }
137 
138 #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
phydm_adaptive_soml_callback(void * dm_void)139 void phydm_adaptive_soml_callback(void *dm_void)
140 {
141 	struct dm_struct *dm = (struct dm_struct *)dm_void;
142 	void *padapter = dm->adapter;
143 
144 	if (*dm->is_net_closed == true)
145 		return;
146 	if (dm->support_interface == ODM_ITRF_PCIE)
147 		phydm_adsl(dm);
148 	else {
149 		/* @Can't do I/O in timer callback*/
150 		phydm_run_in_thread_cmd(dm,
151 					phydm_adaptive_soml_workitem_callback,
152 					dm);
153 	}
154 }
155 
phydm_adaptive_soml_workitem_callback(void * context)156 void phydm_adaptive_soml_workitem_callback(void *context)
157 {
158 	struct dm_struct *dm = (void *)context;
159 
160 #if 0
161 	/*@dbg_print("%s\n",__func__);*/
162 #endif
163 	phydm_adsl(dm);
164 }
165 
166 #else
phydm_adaptive_soml_callback(void * dm_void)167 void phydm_adaptive_soml_callback(void *dm_void)
168 {
169 	struct dm_struct *dm = (struct dm_struct *)dm_void;
170 
171 	PHYDM_DBG(dm, DBG_ADPTV_SOML, "******SOML_Callback******\n");
172 	phydm_adsl(dm);
173 }
174 #endif
175 
phydm_rx_rate_for_soml(void * dm_void,void * pkt_info_void)176 void phydm_rx_rate_for_soml(void *dm_void, void *pkt_info_void)
177 {
178 	struct dm_struct *dm = (struct dm_struct *)dm_void;
179 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
180 	struct phydm_perpkt_info_struct *pktinfo = NULL;
181 	u8 data_rate;
182 
183 	pktinfo = (struct phydm_perpkt_info_struct *)pkt_info_void;
184 	data_rate = (pktinfo->data_rate & 0x7f);
185 
186 	if (pktinfo->data_rate >= ODM_RATEMCS0 &&
187 	    pktinfo->data_rate <= ODM_RATEMCS31)
188 		soml_tab->ht_cnt[data_rate - ODM_RATEMCS0]++;
189 	else if ((pktinfo->data_rate >= ODM_RATEVHTSS1MCS0) &&
190 		 (pktinfo->data_rate <= ODM_RATEVHTSS4MCS9))
191 		soml_tab->vht_cnt[data_rate - ODM_RATEVHTSS1MCS0]++;
192 }
193 
phydm_rx_qam_for_soml(void * dm_void,void * pkt_info_void)194 void phydm_rx_qam_for_soml(void *dm_void, void *pkt_info_void)
195 {
196 	struct dm_struct *dm = (struct dm_struct *)dm_void;
197 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
198 	struct phydm_perpkt_info_struct *pktinfo = NULL;
199 	u8 date_rate;
200 
201 	pktinfo = (struct phydm_perpkt_info_struct *)pkt_info_void;
202 	date_rate = (pktinfo->data_rate & 0x7f);
203 	if (soml_tab->soml_state_cnt < (soml_tab->soml_train_num << 1)) {
204 		if (soml_tab->soml_on_off == SOML_ON) {
205 			return;
206 		} else if (soml_tab->soml_on_off == SOML_OFF) {
207 			if (date_rate >= ODM_RATEMCS8 &&
208 			    date_rate <= ODM_RATEMCS10)
209 				soml_tab->num_ht_qam[BPSK_QPSK]++;
210 
211 			else if ((date_rate >= ODM_RATEMCS11) &&
212 				 (date_rate <= ODM_RATEMCS12))
213 				soml_tab->num_ht_qam[QAM16]++;
214 
215 			else if ((date_rate >= ODM_RATEMCS13) &&
216 				 (date_rate <= ODM_RATEMCS15))
217 				soml_tab->num_ht_qam[QAM64]++;
218 
219 			else if ((date_rate >= ODM_RATEVHTSS2MCS0) &&
220 				 (date_rate <= ODM_RATEVHTSS2MCS2))
221 				soml_tab->num_vht_qam[BPSK_QPSK]++;
222 
223 			else if ((date_rate >= ODM_RATEVHTSS2MCS3) &&
224 				 (date_rate <= ODM_RATEVHTSS2MCS4))
225 				soml_tab->num_vht_qam[QAM16]++;
226 
227 			else if ((date_rate >= ODM_RATEVHTSS2MCS5) &&
228 				 (date_rate <= ODM_RATEVHTSS2MCS5))
229 				soml_tab->num_vht_qam[QAM64]++;
230 
231 			else if ((date_rate >= ODM_RATEVHTSS2MCS8) &&
232 				 (date_rate <= ODM_RATEVHTSS2MCS9))
233 				soml_tab->num_vht_qam[QAM256]++;
234 		}
235 	}
236 }
237 
phydm_soml_reset_rx_rate(void * dm_void)238 void phydm_soml_reset_rx_rate(void *dm_void)
239 {
240 	struct dm_struct *dm = (struct dm_struct *)dm_void;
241 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
242 	u8 order;
243 
244 	for (order = 0; order < HT_RATE_IDX; order++) {
245 		soml_tab->ht_cnt[order] = 0;
246 		soml_tab->pre_ht_cnt[order] = 0;
247 		soml_tab->ht_cnt_on[order] = 0;
248 		soml_tab->ht_cnt_off[order] = 0;
249 		soml_tab->ht_crc_ok_cnt_on[order] = 0;
250 		soml_tab->ht_crc_fail_cnt_on[order] = 0;
251 		soml_tab->ht_crc_ok_cnt_off[order] = 0;
252 		soml_tab->ht_crc_fail_cnt_off[order] = 0;
253 	}
254 
255 	for (order = 0; order < VHT_RATE_IDX; order++) {
256 		soml_tab->vht_cnt[order] = 0;
257 		soml_tab->pre_vht_cnt[order] = 0;
258 		soml_tab->vht_cnt_on[order] = 0;
259 		soml_tab->vht_cnt_off[order] = 0;
260 		soml_tab->vht_crc_ok_cnt_on[order] = 0;
261 		soml_tab->vht_crc_fail_cnt_on[order] = 0;
262 		soml_tab->vht_crc_ok_cnt_off[order] = 0;
263 		soml_tab->vht_crc_fail_cnt_off[order] = 0;
264 	}
265 }
266 
phydm_soml_reset_qam(void * dm_void)267 void phydm_soml_reset_qam(void *dm_void)
268 {
269 	struct dm_struct *dm = (struct dm_struct *)dm_void;
270 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
271 	u8 order;
272 
273 	for (order = 0; order < HT_ORDER_TYPE; order++)
274 		soml_tab->num_ht_qam[order] = 0;
275 
276 	for (order = 0; order < VHT_ORDER_TYPE; order++)
277 		soml_tab->num_vht_qam[order] = 0;
278 }
279 
phydm_soml_cfo_process(void * dm_void,s32 * diff_a,s32 * diff_b)280 void phydm_soml_cfo_process(void *dm_void, s32 *diff_a, s32 *diff_b)
281 {
282 	struct dm_struct *dm = (struct dm_struct *)dm_void;
283 	u32 value32, value32_1, value32_2, value32_3;
284 	s32 cfo_acq_a, cfo_acq_b, cfo_end_a, cfo_end_b;
285 
286 	value32 = odm_get_bb_reg(dm, R_0xd10, MASKDWORD);
287 	value32_1 = odm_get_bb_reg(dm, R_0xd14, MASKDWORD);
288 	value32_2 = odm_get_bb_reg(dm, R_0xd50, MASKDWORD);
289 	value32_3 = odm_get_bb_reg(dm, R_0xd54, MASKDWORD);
290 
291 	cfo_acq_a = (s32)((value32 & 0x1fff0000) >> 16);
292 	cfo_end_a = (s32)((value32_1 & 0x1fff0000) >> 16);
293 	cfo_acq_b = (s32)((value32_2 & 0x1fff0000) >> 16);
294 	cfo_end_b = (s32)((value32_3 & 0x1fff0000) >> 16);
295 
296 	*diff_a = ((cfo_acq_a >= cfo_end_a) ? (cfo_acq_a - cfo_end_a) :
297 		  (cfo_end_a - cfo_acq_a));
298 	*diff_b = ((cfo_acq_b >= cfo_end_b) ? (cfo_acq_b - cfo_end_b) :
299 		  (cfo_end_b - cfo_acq_b));
300 
301 	*diff_a = ((*diff_a * 312) + (*diff_a >> 1)) >> 12; /* @312.5/2^12 */
302 	*diff_b = ((*diff_b * 312) + (*diff_b >> 1)) >> 12; /* @312.5/2^12 */
303 }
304 
phydm_soml_debug(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)305 void phydm_soml_debug(void *dm_void, char input[][16], u32 *_used,
306 		      char *output, u32 *_out_len)
307 {
308 	struct dm_struct *dm = (struct dm_struct *)dm_void;
309 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
310 	u32 used = *_used;
311 	u32 out_len = *_out_len;
312 	u32 dm_value[10] = {0};
313 	u8 i = 0, input_idx = 0;
314 
315 	if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML))
316 		return;
317 
318 	for (i = 0; i < 5; i++) {
319 		if (input[i + 1]) {
320 			PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &dm_value[i]);
321 			input_idx++;
322 		}
323 	}
324 
325 	if (input_idx == 0)
326 		return;
327 
328 	if (dm_value[0] == 1) { /*Turn on/off SOML*/
329 		soml_tab->soml_select = (u8)dm_value[1];
330 
331 	} else if (dm_value[0] == 2) { /*training number for SOML*/
332 
333 		soml_tab->soml_train_num = (u8)dm_value[1];
334 		PDM_SNPF(out_len, used, output + used, out_len - used,
335 			 "soml_train_num = ((%d))\n",
336 			 soml_tab->soml_train_num);
337 	} else if (dm_value[0] == 3) { /*training interval for SOML*/
338 
339 		soml_tab->soml_intvl = (u8)dm_value[1];
340 		PDM_SNPF(out_len, used, output + used, out_len - used,
341 			 "soml_intvl = ((%d))\n", soml_tab->soml_intvl);
342 	} else if (dm_value[0] == 4) { /*@function period for SOML*/
343 
344 		soml_tab->soml_period = (u8)dm_value[1];
345 		PDM_SNPF(out_len, used, output + used, out_len - used,
346 			 "soml_period = ((%d))\n", soml_tab->soml_period);
347 	} else if (dm_value[0] == 5) { /*@delay_time for SOML*/
348 
349 		soml_tab->soml_delay_time = (u8)dm_value[1];
350 		PDM_SNPF(out_len, used, output + used, out_len - used,
351 			 "soml_delay_time = ((%d))\n",
352 			 soml_tab->soml_delay_time);
353 	} else if (dm_value[0] == 6) { /* @for SOML Rx QAM distribution th*/
354 		if (dm_value[1] == 256) {
355 			soml_tab->qam256_dist_th = (u8)dm_value[2];
356 			PDM_SNPF(out_len, used, output + used, out_len - used,
357 				 "qam256_dist_th = ((%d))\n",
358 				 soml_tab->qam256_dist_th);
359 		} else if (dm_value[1] == 64) {
360 			soml_tab->qam64_dist_th = (u8)dm_value[2];
361 			PDM_SNPF(out_len, used, output + used, out_len - used,
362 				 "qam64_dist_th = ((%d))\n",
363 				 soml_tab->qam64_dist_th);
364 		} else if (dm_value[1] == 16) {
365 			soml_tab->qam16_dist_th = (u8)dm_value[2];
366 			PDM_SNPF(out_len, used, output + used, out_len - used,
367 				 "qam16_dist_th = ((%d))\n",
368 				 soml_tab->qam16_dist_th);
369 		} else if (dm_value[1] == 4) {
370 			soml_tab->bpsk_qpsk_dist_th = (u8)dm_value[2];
371 			PDM_SNPF(out_len, used, output + used, out_len - used,
372 				 "bpsk_qpsk_dist_th = ((%d))\n",
373 				 soml_tab->bpsk_qpsk_dist_th);
374 		}
375 	} else if (dm_value[0] == 7) { /* @for SOML cfo th*/
376 		if (dm_value[1] == 256) {
377 			soml_tab->cfo_qam256_th = (u8)dm_value[2];
378 			PDM_SNPF(out_len, used, output + used, out_len - used,
379 				 "cfo_qam256_th = ((%d KHz))\n",
380 				 soml_tab->cfo_qam256_th);
381 		} else if (dm_value[1] == 64) {
382 			soml_tab->cfo_qam64_th = (u8)dm_value[2];
383 			PDM_SNPF(out_len, used, output + used, out_len - used,
384 				 "cfo_qam64_th = ((%d KHz))\n",
385 				 soml_tab->cfo_qam64_th);
386 		} else if (dm_value[1] == 16) {
387 			soml_tab->cfo_qam16_th = (u8)dm_value[2];
388 			PDM_SNPF(out_len, used, output + used, out_len - used,
389 				 "cfo_qam16_th = ((%d KHz))\n",
390 				 soml_tab->cfo_qam16_th);
391 		} else if (dm_value[1] == 4) {
392 			soml_tab->cfo_qpsk_th = (u8)dm_value[2];
393 			PDM_SNPF(out_len, used, output + used, out_len - used,
394 				 "cfo_qpsk_th = ((%d KHz))\n",
395 				 soml_tab->cfo_qpsk_th);
396 		}
397 	} else if (dm_value[0] == 100) {
398 		/*show parameters*/
399 		PDM_SNPF(out_len, used, output + used, out_len - used,
400 			 "soml_select = ((%d))\n", soml_tab->soml_select);
401 		PDM_SNPF(out_len, used, output + used, out_len - used,
402 			 "soml_train_num = ((%d))\n",
403 			 soml_tab->soml_train_num);
404 		PDM_SNPF(out_len, used, output + used, out_len - used,
405 			 "soml_intvl = ((%d))\n", soml_tab->soml_intvl);
406 		PDM_SNPF(out_len, used, output + used, out_len - used,
407 			 "soml_period = ((%d))\n", soml_tab->soml_period);
408 		PDM_SNPF(out_len, used, output + used, out_len - used,
409 			 "soml_delay_time = ((%d))\n\n",
410 			 soml_tab->soml_delay_time);
411 		PDM_SNPF(out_len, used, output + used, out_len - used,
412 			 "qam256_dist_th = ((%d)),  qam64_dist_th = ((%d)), ",
413 			 soml_tab->qam256_dist_th,
414 			 soml_tab->qam64_dist_th);
415 		PDM_SNPF(out_len, used, output + used, out_len - used,
416 			 "qam16_dist_th = ((%d)),  bpsk_qpsk_dist_th = ((%d))\n",
417 			 soml_tab->qam16_dist_th,
418 			 soml_tab->bpsk_qpsk_dist_th);
419 		PDM_SNPF(out_len, used, output + used, out_len - used,
420 			 "cfo_qam256_th = ((%d KHz)),  cfo_qam64_th = ((%d KHz)), ",
421 			 soml_tab->cfo_qam256_th,
422 			 soml_tab->cfo_qam64_th);
423 		PDM_SNPF(out_len, used, output + used, out_len - used,
424 			 "cfo_qam16_th = ((%d KHz)),  cfo_qpsk_th  = ((%d KHz))\n",
425 			 soml_tab->cfo_qam16_th,
426 			 soml_tab->cfo_qpsk_th);
427 	}
428 	*_used = used;
429 	*_out_len = out_len;
430 }
431 
phydm_soml_stats_ht_on(void * dm_void)432 void phydm_soml_stats_ht_on(void *dm_void)
433 {
434 	struct dm_struct *dm = (struct dm_struct *)dm_void;
435 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
436 	u8 i, mcs0;
437 	u16 num_bytes_diff, num_rate_diff;
438 
439 	mcs0 = ODM_RATEMCS0;
440 	for (i = mcs0; i <= ODM_RATEMCS15; i++) {
441 		num_rate_diff = soml_tab->ht_cnt[i - mcs0] -
442 				soml_tab->pre_ht_cnt[i - mcs0];
443 		soml_tab->ht_cnt_on[i - mcs0] += num_rate_diff;
444 		soml_tab->pre_ht_cnt[i - mcs0] = soml_tab->ht_cnt[i - mcs0];
445 		num_bytes_diff = soml_tab->ht_byte[i - mcs0] -
446 				 soml_tab->pre_ht_byte[i - mcs0];
447 		soml_tab->ht_byte_on[i - mcs0] += num_bytes_diff;
448 		soml_tab->pre_ht_byte[i - mcs0] = soml_tab->ht_byte[i - mcs0];
449 	}
450 }
451 
phydm_soml_stats_ht_off(void * dm_void)452 void phydm_soml_stats_ht_off(void *dm_void)
453 {
454 	struct dm_struct *dm = (struct dm_struct *)dm_void;
455 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
456 	u8 i, mcs0;
457 	u16 num_bytes_diff, num_rate_diff;
458 
459 	mcs0 = ODM_RATEMCS0;
460 	for (i = mcs0; i <= ODM_RATEMCS15; i++) {
461 		num_rate_diff = soml_tab->ht_cnt[i - mcs0] -
462 				soml_tab->pre_ht_cnt[i - mcs0];
463 		soml_tab->ht_cnt_off[i - mcs0] += num_rate_diff;
464 		soml_tab->pre_ht_cnt[i - mcs0] = soml_tab->ht_cnt[i - mcs0];
465 		num_bytes_diff = soml_tab->ht_byte[i - mcs0] -
466 				 soml_tab->pre_ht_byte[i - mcs0];
467 		soml_tab->ht_byte_off[i - mcs0] += num_bytes_diff;
468 		soml_tab->pre_ht_byte[i - mcs0] = soml_tab->ht_byte[i - mcs0];
469 	}
470 }
471 
phydm_soml_stats_vht_on(void * dm_void)472 void phydm_soml_stats_vht_on(void *dm_void)
473 {
474 	struct dm_struct *dm = (struct dm_struct *)dm_void;
475 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
476 	u8 j, vht0;
477 	u16 num_bytes_diff, num_rate_diff;
478 
479 	vht0 = ODM_RATEVHTSS1MCS0;
480 	for (j = vht0; j <= ODM_RATEVHTSS2MCS9; j++) {
481 		num_rate_diff = soml_tab->vht_cnt[j - vht0] -
482 				soml_tab->pre_vht_cnt[j - vht0];
483 		soml_tab->vht_cnt_on[j - vht0] += num_rate_diff;
484 		soml_tab->pre_vht_cnt[j - vht0] = soml_tab->vht_cnt[j - vht0];
485 		num_bytes_diff = soml_tab->vht_byte[j - vht0] -
486 				 soml_tab->pre_vht_byte[j - vht0];
487 		soml_tab->vht_byte_on[j - vht0] += num_bytes_diff;
488 		soml_tab->pre_vht_byte[j - vht0] = soml_tab->vht_byte[j - vht0];
489 	}
490 }
491 
phydm_soml_stats_vht_off(void * dm_void)492 void phydm_soml_stats_vht_off(void *dm_void)
493 {
494 	struct dm_struct *dm = (struct dm_struct *)dm_void;
495 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
496 	u8 j, vht0;
497 	u16 num_bytes_diff, num_rate_diff;
498 
499 	vht0 = ODM_RATEVHTSS1MCS0;
500 	for (j = vht0; j <= ODM_RATEVHTSS2MCS9; j++) {
501 		num_rate_diff = soml_tab->vht_cnt[j - vht0] -
502 				soml_tab->pre_vht_cnt[j - vht0];
503 		soml_tab->vht_cnt_off[j - vht0] += num_rate_diff;
504 		soml_tab->pre_vht_cnt[j - vht0] = soml_tab->vht_cnt[j - vht0];
505 		num_bytes_diff = soml_tab->vht_byte[j - vht0] -
506 				 soml_tab->pre_vht_byte[j - vht0];
507 		soml_tab->vht_byte_off[j - vht0] += num_bytes_diff;
508 		soml_tab->pre_vht_byte[j - vht0] = soml_tab->vht_byte[j - vht0];
509 	}
510 }
511 
phydm_soml_statistics(void * dm_void,u8 on_off_state)512 void phydm_soml_statistics(void *dm_void, u8 on_off_state)
513 {
514 	struct dm_struct *dm = (struct dm_struct *)dm_void;
515 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
516 
517 	if (on_off_state == SOML_ON) {
518 		if (*dm->channel <= 14)
519 			phydm_soml_stats_ht_on(dm);
520 		if (dm->support_ic_type == ODM_RTL8822B)
521 			phydm_soml_stats_vht_on(dm);
522 	} else if (on_off_state == SOML_OFF) {
523 		if (*dm->channel <= 14)
524 			phydm_soml_stats_ht_off(dm);
525 		if (dm->support_ic_type == ODM_RTL8822B)
526 			phydm_soml_stats_vht_off(dm);
527 	}
528 }
529 
phydm_adsl_init_state(void * dm_void)530 void phydm_adsl_init_state(void *dm_void)
531 {
532 	struct dm_struct *dm = (struct dm_struct *)dm_void;
533 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
534 
535 	u8 next_on_off;
536 	u16 ht_reset[HT_RATE_IDX] = {0}, vht_reset[VHT_RATE_IDX] = {0};
537 	u8 size = sizeof(ht_reset[0]);
538 
539 	phydm_soml_reset_rx_rate(dm);
540 	odm_move_memory(dm, soml_tab->ht_byte, ht_reset,
541 			HT_RATE_IDX * size);
542 	odm_move_memory(dm, soml_tab->ht_byte_on, ht_reset,
543 			HT_RATE_IDX * size);
544 	odm_move_memory(dm, soml_tab->ht_byte_off, ht_reset,
545 			HT_RATE_IDX * size);
546 	odm_move_memory(dm, soml_tab->vht_byte, vht_reset,
547 			VHT_RATE_IDX * size);
548 	odm_move_memory(dm, soml_tab->vht_byte_on, vht_reset,
549 			VHT_RATE_IDX * size);
550 	odm_move_memory(dm, soml_tab->vht_byte_off, vht_reset,
551 			VHT_RATE_IDX * size);
552 	if (dm->support_ic_type == ODM_RTL8822B) {
553 		soml_tab->cfo_cnt++;
554 		phydm_soml_cfo_process(dm,
555 				       &soml_tab->cfo_diff_a,
556 				       &soml_tab->cfo_diff_b);
557 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
558 			  "[ (%d) cfo_diff_a = %d KHz; cfo_diff_b = %d KHz ]\n",
559 			  soml_tab->cfo_cnt, soml_tab->cfo_diff_a,
560 			  soml_tab->cfo_diff_b);
561 		soml_tab->cfo_diff_sum_a += soml_tab->cfo_diff_a;
562 		soml_tab->cfo_diff_sum_b += soml_tab->cfo_diff_b;
563 	}
564 
565 	soml_tab->is_soml_method_enable = 1;
566 	soml_tab->get_stats = false;
567 	soml_tab->soml_state_cnt++;
568 	next_on_off = (soml_tab->soml_on_off == SOML_ON) ? SOML_ON : SOML_OFF;
569 	phydm_soml_on_off(dm, next_on_off);
570 	odm_set_timer(dm, &soml_tab->phydm_adaptive_soml_timer,
571 		      soml_tab->soml_delay_time); /*@ms*/
572 }
573 
phydm_adsl_odd_state(void * dm_void)574 void phydm_adsl_odd_state(void *dm_void)
575 {
576 	struct dm_struct *dm = (struct dm_struct *)dm_void;
577 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
578 	u16 ht_reset[HT_RATE_IDX] = {0}, vht_reset[VHT_RATE_IDX] = {0};
579 	u8 size = sizeof(ht_reset[0]);
580 
581 	soml_tab->get_stats = true;
582 	soml_tab->soml_state_cnt++;
583 	odm_move_memory(dm, soml_tab->pre_ht_cnt, soml_tab->ht_cnt,
584 			HT_RATE_IDX * size);
585 	odm_move_memory(dm, soml_tab->pre_vht_cnt, soml_tab->vht_cnt,
586 			VHT_RATE_IDX * size);
587 	odm_move_memory(dm, soml_tab->pre_ht_byte, soml_tab->ht_byte,
588 			HT_RATE_IDX * size);
589 	odm_move_memory(dm, soml_tab->pre_vht_byte, soml_tab->vht_byte,
590 			VHT_RATE_IDX * size);
591 
592 	if (dm->support_ic_type == ODM_RTL8822B) {
593 		soml_tab->cfo_cnt++;
594 		phydm_soml_cfo_process(dm,
595 				       &soml_tab->cfo_diff_a,
596 				       &soml_tab->cfo_diff_b);
597 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
598 			  "[ (%d) cfo_diff_a = %d KHz; cfo_diff_b = %d KHz ]\n",
599 			  soml_tab->cfo_cnt, soml_tab->cfo_diff_a,
600 			  soml_tab->cfo_diff_b);
601 		soml_tab->cfo_diff_sum_a += soml_tab->cfo_diff_a;
602 		soml_tab->cfo_diff_sum_b += soml_tab->cfo_diff_b;
603 	}
604 	odm_set_timer(dm, &soml_tab->phydm_adaptive_soml_timer,
605 		      soml_tab->soml_intvl); /*@ms*/
606 }
607 
phydm_adsl_even_state(void * dm_void)608 void phydm_adsl_even_state(void *dm_void)
609 {
610 	struct dm_struct *dm = (struct dm_struct *)dm_void;
611 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
612 	u8 next_on_off;
613 
614 	soml_tab->get_stats = false;
615 	if (dm->support_ic_type == ODM_RTL8822B) {
616 		soml_tab->cfo_cnt++;
617 		phydm_soml_cfo_process(dm,
618 				       &soml_tab->cfo_diff_a,
619 				       &soml_tab->cfo_diff_b);
620 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
621 			  "[ (%d) cfo_diff_a = %d KHz; cfo_diff_b = %d KHz ]\n",
622 			  soml_tab->cfo_cnt, soml_tab->cfo_diff_a,
623 			  soml_tab->cfo_diff_b);
624 		soml_tab->cfo_diff_sum_a += soml_tab->cfo_diff_a;
625 		soml_tab->cfo_diff_sum_b += soml_tab->cfo_diff_b;
626 	}
627 	soml_tab->soml_state_cnt++;
628 	phydm_soml_statistics(dm, soml_tab->soml_on_off);
629 	next_on_off = (soml_tab->soml_on_off == SOML_ON) ? SOML_OFF : SOML_ON;
630 	phydm_soml_on_off(dm, next_on_off);
631 	odm_set_timer(dm, &soml_tab->phydm_adaptive_soml_timer,
632 		      soml_tab->soml_delay_time); /*@ms*/
633 }
634 
phydm_adsl_decision_state(void * dm_void)635 void phydm_adsl_decision_state(void *dm_void)
636 {
637 	struct dm_struct *dm = (struct dm_struct *)dm_void;
638 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
639 	boolean on_above = false, off_above = false;
640 	u8 i, max_idx_on = 0, max_idx_off = 0;
641 	u8 next_on_off = soml_tab->soml_last_state;
642 	u8 mcs0 = ODM_RATEMCS0, vht0 = ODM_RATEVHTSS1MCS0;
643 	u8 crc_taget = soml_tab->soml_last_state;
644 	u8 rate_num = 1, ss_shift = 0;
645 	u16 ht_ok_max_on = 0, ht_fail_max_on = 0, utility_on = 0;
646 	u16 ht_ok_max_off = 0, ht_fail_max_off = 0, utility_off = 0;
647 	u16 vht_ok_max_on = 0, vht_fail_max_on = 0;
648 	u16 vht_ok_max_off = 0, vht_fail_max_off = 0;
649 	u16 num_total_qam = 0;
650 	u16 cnt_max_on = 0, cnt_max_off = 0;
651 	u32 ht_total_cnt_on = 0, ht_total_cnt_off = 0;
652 	u32 total_ht_rate_on = 0, total_ht_rate_off = 0;
653 	u32 vht_total_cnt_on = 0, vht_total_cnt_off = 0;
654 	u32 total_vht_rate_on = 0, total_vht_rate_off = 0;
655 	u32 rate_per_pkt_on = 0, rate_per_pkt_off = 0;
656 	s32 cfo_diff_avg_a, cfo_diff_avg_b;
657 	u16 vht_phy_rate_table[] = {
658 		/*@20M*/
659 		6, 13, 19, 26, 39, 52, 58, 65, 78, 90, /*@1SS MCS0~9*/
660 		13, 26, 39, 52, 78, 104, 117, 130, 156, 180 /*@2SSMCS0~9*/
661 	};
662 
663 	if (dm->support_ic_type & ODM_IC_1SS)
664 		rate_num = 1;
665 	#ifdef PHYDM_COMPILE_ABOVE_2SS
666 	else if (dm->support_ic_type & ODM_IC_2SS)
667 		rate_num = 2;
668 	#endif
669 	#ifdef PHYDM_COMPILE_ABOVE_3SS
670 	else if (dm->support_ic_type & ODM_IC_3SS)
671 		rate_num = 3;
672 	#endif
673 	#ifdef PHYDM_COMPILE_ABOVE_4SS
674 	else if (dm->support_ic_type & ODM_IC_4SS)
675 		rate_num = 4;
676 	#endif
677 	else
678 		pr_debug("%s: mismatch IC type %x\n", __func__,
679 			 dm->support_ic_type);
680 	soml_tab->get_stats = false;
681 	PHYDM_DBG(dm, DBG_ADPTV_SOML, "[Decisoin state ]\n");
682 	phydm_soml_statistics(dm, soml_tab->soml_on_off);
683 	if (*dm->channel <= 14) {
684 		/* @[Search 1st and 2nd rate by counter] */
685 		for (i = 0; i < rate_num; i++) {
686 			ss_shift = (i << 3);
687 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
688 				  "*ht_cnt_on  HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
689 				  (ss_shift), (ss_shift + 7),
690 				  soml_tab->ht_cnt_on[ss_shift + 0],
691 				  soml_tab->ht_cnt_on[ss_shift + 1],
692 				  soml_tab->ht_cnt_on[ss_shift + 2],
693 				  soml_tab->ht_cnt_on[ss_shift + 3],
694 				  soml_tab->ht_cnt_on[ss_shift + 4],
695 				  soml_tab->ht_cnt_on[ss_shift + 5],
696 				  soml_tab->ht_cnt_on[ss_shift + 6],
697 				  soml_tab->ht_cnt_on[ss_shift + 7]);
698 		}
699 
700 		for (i = 0; i < rate_num; i++) {
701 			ss_shift = (i << 3);
702 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
703 				  "*ht_cnt_off  HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
704 				  (ss_shift), (ss_shift + 7),
705 				  soml_tab->ht_cnt_off[ss_shift + 0],
706 				  soml_tab->ht_cnt_off[ss_shift + 1],
707 				  soml_tab->ht_cnt_off[ss_shift + 2],
708 				  soml_tab->ht_cnt_off[ss_shift + 3],
709 				  soml_tab->ht_cnt_off[ss_shift + 4],
710 				  soml_tab->ht_cnt_off[ss_shift + 5],
711 				  soml_tab->ht_cnt_off[ss_shift + 6],
712 				  soml_tab->ht_cnt_off[ss_shift + 7]);
713 		}
714 
715 		for (i = 0; i < rate_num; i++) {
716 			ss_shift = (i << 3);
717 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
718 				  "*ht_crc_ok_cnt_on  HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
719 				  (ss_shift), (ss_shift + 7),
720 				  soml_tab->ht_crc_ok_cnt_on[ss_shift + 0],
721 				  soml_tab->ht_crc_ok_cnt_on[ss_shift + 1],
722 				  soml_tab->ht_crc_ok_cnt_on[ss_shift + 2],
723 				  soml_tab->ht_crc_ok_cnt_on[ss_shift + 3],
724 				  soml_tab->ht_crc_ok_cnt_on[ss_shift + 4],
725 				  soml_tab->ht_crc_ok_cnt_on[ss_shift + 5],
726 				  soml_tab->ht_crc_ok_cnt_on[ss_shift + 6],
727 				  soml_tab->ht_crc_ok_cnt_on[ss_shift + 7]);
728 		}
729 
730 		for (i = 0; i < rate_num; i++) {
731 			ss_shift = (i << 3);
732 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
733 				  "*ht_crc_fail_cnt_on  HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
734 				  (ss_shift), (ss_shift + 7),
735 				  soml_tab->ht_crc_fail_cnt_on[ss_shift + 0],
736 				  soml_tab->ht_crc_fail_cnt_on[ss_shift + 1],
737 				  soml_tab->ht_crc_fail_cnt_on[ss_shift + 2],
738 				  soml_tab->ht_crc_fail_cnt_on[ss_shift + 3],
739 				  soml_tab->ht_crc_fail_cnt_on[ss_shift + 4],
740 				  soml_tab->ht_crc_fail_cnt_on[ss_shift + 5],
741 				  soml_tab->ht_crc_fail_cnt_on[ss_shift + 6],
742 				  soml_tab->ht_crc_fail_cnt_on[ss_shift + 7]);
743 		}
744 
745 		for (i = 0; i < rate_num; i++) {
746 			ss_shift = (i << 3);
747 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
748 				  "*ht_crc_ok_cnt_off  HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
749 				  (ss_shift), (ss_shift + 7),
750 				  soml_tab->ht_crc_ok_cnt_off[ss_shift + 0],
751 				  soml_tab->ht_crc_ok_cnt_off[ss_shift + 1],
752 				  soml_tab->ht_crc_ok_cnt_off[ss_shift + 2],
753 				  soml_tab->ht_crc_ok_cnt_off[ss_shift + 3],
754 				  soml_tab->ht_crc_ok_cnt_off[ss_shift + 4],
755 				  soml_tab->ht_crc_ok_cnt_off[ss_shift + 5],
756 				  soml_tab->ht_crc_ok_cnt_off[ss_shift + 6],
757 				  soml_tab->ht_crc_ok_cnt_off[ss_shift + 7]);
758 		}
759 
760 		for (i = 0; i < rate_num; i++) {
761 			ss_shift = (i << 3);
762 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
763 				  "*ht_crc_fail_cnt_off  HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
764 				  (ss_shift), (ss_shift + 7),
765 				  soml_tab->ht_crc_fail_cnt_off[ss_shift + 0],
766 				  soml_tab->ht_crc_fail_cnt_off[ss_shift + 1],
767 				  soml_tab->ht_crc_fail_cnt_off[ss_shift + 2],
768 				  soml_tab->ht_crc_fail_cnt_off[ss_shift + 3],
769 				  soml_tab->ht_crc_fail_cnt_off[ss_shift + 4],
770 				  soml_tab->ht_crc_fail_cnt_off[ss_shift + 5],
771 				  soml_tab->ht_crc_fail_cnt_off[ss_shift + 6],
772 				  soml_tab->ht_crc_fail_cnt_off[ss_shift + 7]);
773 		}
774 		for (i = ODM_RATEMCS0; i <= ODM_RATEMCS15; i++) {
775 			ht_total_cnt_on += soml_tab->ht_cnt_on[i - mcs0];
776 			ht_total_cnt_off += soml_tab->ht_cnt_off[i - mcs0];
777 			total_ht_rate_on += (soml_tab->ht_cnt_on[i - mcs0] *
778 					    phy_rate_table[i]);
779 			total_ht_rate_off += (soml_tab->ht_cnt_off[i - mcs0] *
780 					     phy_rate_table[i]);
781 			if (soml_tab->ht_cnt_on[i - mcs0] > cnt_max_on) {
782 				cnt_max_on = soml_tab->ht_cnt_on[i - mcs0];
783 				max_idx_on = i - mcs0;
784 			}
785 
786 			if (soml_tab->ht_cnt_off[i - mcs0] > cnt_max_off) {
787 				cnt_max_off = soml_tab->ht_cnt_off[i - mcs0];
788 				max_idx_off = i - mcs0;
789 			}
790 		}
791 		total_ht_rate_on = total_ht_rate_on << 3;
792 		total_ht_rate_off = total_ht_rate_off << 3;
793 		rate_per_pkt_on = (ht_total_cnt_on != 0) ?
794 				  (total_ht_rate_on / ht_total_cnt_on) : 0;
795 		rate_per_pkt_off = (ht_total_cnt_off != 0) ?
796 				   (total_ht_rate_off / ht_total_cnt_off) : 0;
797 		#if (DM_ODM_SUPPORT_TYPE == ODM_AP)
798 		ht_ok_max_on = soml_tab->ht_crc_ok_cnt_on[max_idx_on];
799 		ht_fail_max_on = soml_tab->ht_crc_fail_cnt_on[max_idx_on];
800 		ht_ok_max_off = soml_tab->ht_crc_ok_cnt_off[max_idx_off];
801 		ht_fail_max_off = soml_tab->ht_crc_fail_cnt_off[max_idx_off];
802 
803 		if (ht_fail_max_on == 0)
804 			ht_fail_max_on = 1;
805 
806 		if (ht_fail_max_off == 0)
807 			ht_fail_max_off = 1;
808 
809 		if (ht_ok_max_on > ht_fail_max_on)
810 			on_above = true;
811 
812 		if (ht_ok_max_off > ht_fail_max_off)
813 			off_above = true;
814 
815 		if (on_above && !off_above) {
816 			crc_taget = SOML_ON;
817 		} else if (!on_above && off_above) {
818 			crc_taget = SOML_OFF;
819 		} else if (on_above && off_above) {
820 			utility_on = (ht_ok_max_on << 7) / ht_fail_max_on;
821 			utility_off = (ht_ok_max_off << 7) / ht_fail_max_off;
822 			crc_taget = (utility_on == utility_off) ?
823 				    (soml_tab->soml_last_state) :
824 				    ((utility_on > utility_off) ? SOML_ON :
825 				    SOML_OFF);
826 
827 		} else if (!on_above && !off_above) {
828 			if (ht_ok_max_on == 0)
829 				ht_ok_max_on = 1;
830 			if (ht_ok_max_off == 0)
831 				ht_ok_max_off = 1;
832 			utility_on = (ht_fail_max_on << 7) / ht_ok_max_on;
833 			utility_off = (ht_fail_max_off << 7) / ht_ok_max_off;
834 			crc_taget = (utility_on == utility_off) ?
835 				    (soml_tab->soml_last_state) :
836 				    ((utility_on < utility_off) ? SOML_ON :
837 				    SOML_OFF);
838 		}
839 		#endif
840 	} else if (dm->support_ic_type == ODM_RTL8822B) {
841 		cfo_diff_avg_a = soml_tab->cfo_diff_sum_a / soml_tab->cfo_cnt;
842 		cfo_diff_avg_b = soml_tab->cfo_diff_sum_b / soml_tab->cfo_cnt;
843 		soml_tab->cfo_diff_avg_a = (soml_tab->cfo_cnt != 0) ?
844 					   cfo_diff_avg_a : 0;
845 		soml_tab->cfo_diff_avg_b = (soml_tab->cfo_cnt != 0) ?
846 					   cfo_diff_avg_b : 0;
847 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
848 			  "[ cfo_diff_avg_a = %d KHz; cfo_diff_avg_b = %d KHz]\n",
849 			  soml_tab->cfo_diff_avg_a,
850 			  soml_tab->cfo_diff_avg_b);
851 		for (i = 0; i < VHT_ORDER_TYPE; i++)
852 			num_total_qam += soml_tab->num_vht_qam[i];
853 
854 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
855 			  "[ ((2SS)) BPSK_QPSK_count = %d ; 16QAM_count = %d ; 64QAM_count = %d ; 256QAM_count = %d ; num_total_qam = %d]\n",
856 			  soml_tab->num_vht_qam[BPSK_QPSK],
857 			  soml_tab->num_vht_qam[QAM16],
858 			  soml_tab->num_vht_qam[QAM64],
859 			  soml_tab->num_vht_qam[QAM256],
860 			  num_total_qam);
861 		if (((soml_tab->num_vht_qam[QAM256] * 100) >
862 		    (num_total_qam * soml_tab->qam256_dist_th)) &&
863 		    cfo_diff_avg_a > soml_tab->cfo_qam256_th &&
864 		    cfo_diff_avg_b > soml_tab->cfo_qam256_th) {
865 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
866 				  "[  QAM256_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n",
867 				  soml_tab->qam256_dist_th,
868 				  soml_tab->cfo_qam256_th);
869 			PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
870 			phydm_soml_on_off(dm, SOML_OFF);
871 			return;
872 		} else if (((soml_tab->num_vht_qam[QAM64] * 100) >
873 			   (num_total_qam * soml_tab->qam64_dist_th)) &&
874 			   (cfo_diff_avg_a > soml_tab->cfo_qam64_th) &&
875 			   (cfo_diff_avg_b > soml_tab->cfo_qam64_th)) {
876 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
877 				  "[  QAM64_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n",
878 				  soml_tab->qam64_dist_th,
879 				  soml_tab->cfo_qam64_th);
880 			PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
881 			phydm_soml_on_off(dm, SOML_OFF);
882 			return;
883 		} else if (((soml_tab->num_vht_qam[QAM16] * 100) >
884 			   (num_total_qam * soml_tab->qam16_dist_th)) &&
885 			   (cfo_diff_avg_a > soml_tab->cfo_qam16_th) &&
886 			   (cfo_diff_avg_b > soml_tab->cfo_qam16_th)) {
887 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
888 				  "[  QAM16_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n",
889 				  soml_tab->qam16_dist_th,
890 				  soml_tab->cfo_qam16_th);
891 			PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
892 			phydm_soml_on_off(dm, SOML_OFF);
893 			return;
894 		} else if (((soml_tab->num_vht_qam[BPSK_QPSK] * 100) >
895 			   (num_total_qam * soml_tab->bpsk_qpsk_dist_th)) &&
896 			   (cfo_diff_avg_a > soml_tab->cfo_qpsk_th) &&
897 			   (cfo_diff_avg_b > soml_tab->cfo_qpsk_th)) {
898 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
899 				  "[  BPSK_QPSK_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n",
900 				  soml_tab->bpsk_qpsk_dist_th,
901 				  soml_tab->cfo_qpsk_th);
902 			PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
903 			phydm_soml_on_off(dm, SOML_OFF);
904 			return;
905 		}
906 
907 		for (i = 0; i < rate_num; i++) {
908 			ss_shift = 10 * i;
909 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
910 				  "[  vht_cnt_on  VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d} ]\n",
911 				  (i + 1),
912 				  soml_tab->vht_cnt_on[ss_shift + 0],
913 				  soml_tab->vht_cnt_on[ss_shift + 1],
914 				  soml_tab->vht_cnt_on[ss_shift + 2],
915 				  soml_tab->vht_cnt_on[ss_shift + 3],
916 				  soml_tab->vht_cnt_on[ss_shift + 4],
917 				  soml_tab->vht_cnt_on[ss_shift + 5],
918 				  soml_tab->vht_cnt_on[ss_shift + 6],
919 				  soml_tab->vht_cnt_on[ss_shift + 7],
920 				  soml_tab->vht_cnt_on[ss_shift + 8],
921 				  soml_tab->vht_cnt_on[ss_shift + 9]);
922 		}
923 
924 		for (i = 0; i < rate_num; i++) {
925 			ss_shift = 10 * i;
926 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
927 				  "[  vht_cnt_off  VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d} ]\n",
928 				  (i + 1),
929 				  soml_tab->vht_cnt_off[ss_shift + 0],
930 				  soml_tab->vht_cnt_off[ss_shift + 1],
931 				  soml_tab->vht_cnt_off[ss_shift + 2],
932 				  soml_tab->vht_cnt_off[ss_shift + 3],
933 				  soml_tab->vht_cnt_off[ss_shift + 4],
934 				  soml_tab->vht_cnt_off[ss_shift + 5],
935 				  soml_tab->vht_cnt_off[ss_shift + 6],
936 				  soml_tab->vht_cnt_off[ss_shift + 7],
937 				  soml_tab->vht_cnt_off[ss_shift + 8],
938 				  soml_tab->vht_cnt_off[ss_shift + 9]);
939 		}
940 
941 		for (i = 0; i < rate_num; i++) {
942 			ss_shift = 10 * i;
943 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
944 				  "*vht_crc_ok_cnt_on  VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n",
945 				  (i + 1),
946 				  soml_tab->vht_crc_ok_cnt_on[ss_shift + 0],
947 				  soml_tab->vht_crc_ok_cnt_on[ss_shift + 1],
948 				  soml_tab->vht_crc_ok_cnt_on[ss_shift + 2],
949 				  soml_tab->vht_crc_ok_cnt_on[ss_shift + 3],
950 				  soml_tab->vht_crc_ok_cnt_on[ss_shift + 4],
951 				  soml_tab->vht_crc_ok_cnt_on[ss_shift + 5],
952 				  soml_tab->vht_crc_ok_cnt_on[ss_shift + 6],
953 				  soml_tab->vht_crc_ok_cnt_on[ss_shift + 7],
954 				  soml_tab->vht_crc_ok_cnt_on[ss_shift + 8],
955 				  soml_tab->vht_crc_ok_cnt_on[ss_shift + 9]);
956 		}
957 		for (i = 0; i < rate_num; i++) {
958 			ss_shift = 10 * i;
959 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
960 				  "*vht_crc_fail_cnt_on  VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n",
961 				  (i + 1),
962 				  soml_tab->vht_crc_fail_cnt_on[ss_shift + 0],
963 				  soml_tab->vht_crc_fail_cnt_on[ss_shift + 1],
964 				  soml_tab->vht_crc_fail_cnt_on[ss_shift + 2],
965 				  soml_tab->vht_crc_fail_cnt_on[ss_shift + 3],
966 				  soml_tab->vht_crc_fail_cnt_on[ss_shift + 4],
967 				  soml_tab->vht_crc_fail_cnt_on[ss_shift + 5],
968 				  soml_tab->vht_crc_fail_cnt_on[ss_shift + 6],
969 				  soml_tab->vht_crc_fail_cnt_on[ss_shift + 7],
970 				  soml_tab->vht_crc_fail_cnt_on[ss_shift + 8],
971 				  soml_tab->vht_crc_fail_cnt_on[ss_shift + 9]);
972 		}
973 		for (i = 0; i < rate_num; i++) {
974 			ss_shift = 10 * i;
975 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
976 				  "*vht_crc_ok_cnt_off  VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n",
977 				  (i + 1),
978 				  soml_tab->vht_crc_ok_cnt_off[ss_shift + 0],
979 				  soml_tab->vht_crc_ok_cnt_off[ss_shift + 1],
980 				  soml_tab->vht_crc_ok_cnt_off[ss_shift + 2],
981 				  soml_tab->vht_crc_ok_cnt_off[ss_shift + 3],
982 				  soml_tab->vht_crc_ok_cnt_off[ss_shift + 4],
983 				  soml_tab->vht_crc_ok_cnt_off[ss_shift + 5],
984 				  soml_tab->vht_crc_ok_cnt_off[ss_shift + 6],
985 				  soml_tab->vht_crc_ok_cnt_off[ss_shift + 7],
986 				  soml_tab->vht_crc_ok_cnt_off[ss_shift + 8],
987 				  soml_tab->vht_crc_ok_cnt_off[ss_shift + 9]);
988 		}
989 		for (i = 0; i < rate_num; i++) {
990 			ss_shift = 10 * i;
991 			PHYDM_DBG(dm, DBG_ADPTV_SOML,
992 				  "*vht_crc_fail_cnt_off  VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n",
993 				  (i + 1),
994 				  soml_tab->vht_crc_fail_cnt_off[ss_shift + 0],
995 				  soml_tab->vht_crc_fail_cnt_off[ss_shift + 1],
996 				  soml_tab->vht_crc_fail_cnt_off[ss_shift + 2],
997 				  soml_tab->vht_crc_fail_cnt_off[ss_shift + 3],
998 				  soml_tab->vht_crc_fail_cnt_off[ss_shift + 4],
999 				  soml_tab->vht_crc_fail_cnt_off[ss_shift + 5],
1000 				  soml_tab->vht_crc_fail_cnt_off[ss_shift + 6],
1001 				  soml_tab->vht_crc_fail_cnt_off[ss_shift + 7],
1002 				  soml_tab->vht_crc_fail_cnt_off[ss_shift + 8],
1003 				  soml_tab->vht_crc_fail_cnt_off[ss_shift + 9]);
1004 		}
1005 
1006 		for (i = ODM_RATEVHTSS2MCS0; i <= ODM_RATEVHTSS2MCS9; i++) {
1007 			vht_total_cnt_on += soml_tab->vht_cnt_on[i - vht0];
1008 			vht_total_cnt_off += soml_tab->vht_cnt_off[i - vht0];
1009 			total_vht_rate_on += (soml_tab->vht_cnt_on[i - vht0] *
1010 					     vht_phy_rate_table[i - vht0]);
1011 			total_vht_rate_off += (soml_tab->vht_cnt_off[i - vht0] *
1012 					      vht_phy_rate_table[i - vht0]);
1013 
1014 			if (soml_tab->vht_cnt_on[i - vht0] > cnt_max_on) {
1015 				cnt_max_on = soml_tab->vht_cnt_on[i - vht0];
1016 				max_idx_on = i - vht0;
1017 			}
1018 
1019 			if (soml_tab->vht_cnt_off[i - vht0] > cnt_max_off) {
1020 				cnt_max_off = soml_tab->vht_cnt_off[i - vht0];
1021 				max_idx_off = i - vht0;
1022 			}
1023 		}
1024 		total_vht_rate_on = total_vht_rate_on << 3;
1025 		total_vht_rate_off = total_vht_rate_off << 3;
1026 		rate_per_pkt_on = (vht_total_cnt_on != 0) ?
1027 				  (total_vht_rate_on / vht_total_cnt_on) : 0;
1028 		rate_per_pkt_off = (vht_total_cnt_off != 0) ?
1029 				   (total_vht_rate_off / vht_total_cnt_off) : 0;
1030 		#if (DM_ODM_SUPPORT_TYPE == ODM_AP)
1031 		vht_ok_max_on = soml_tab->vht_crc_ok_cnt_on[max_idx_on];
1032 		vht_fail_max_on = soml_tab->vht_crc_fail_cnt_on[max_idx_on];
1033 		vht_ok_max_off = soml_tab->vht_crc_ok_cnt_off[max_idx_off];
1034 		vht_fail_max_off = soml_tab->vht_crc_fail_cnt_off[max_idx_off];
1035 
1036 		if (vht_fail_max_on == 0)
1037 			vht_fail_max_on = 1;
1038 
1039 		if (vht_fail_max_off == 0)
1040 			vht_fail_max_off = 1;
1041 
1042 		if (vht_ok_max_on > vht_fail_max_on)
1043 			on_above = true;
1044 
1045 		if (vht_ok_max_off > vht_fail_max_off)
1046 			off_above = true;
1047 
1048 		if (on_above && !off_above) {
1049 			crc_taget = SOML_ON;
1050 		} else if (!on_above && off_above) {
1051 			crc_taget = SOML_OFF;
1052 		} else if (on_above && off_above) {
1053 			utility_on = (vht_ok_max_on << 7) / vht_fail_max_on;
1054 			utility_off = (vht_ok_max_off << 7) / vht_fail_max_off;
1055 			crc_taget = (utility_on == utility_off) ?
1056 				    (soml_tab->soml_last_state) :
1057 				    ((utility_on > utility_off) ? SOML_ON :
1058 				    SOML_OFF);
1059 
1060 		} else if (!on_above && !off_above) {
1061 			if (vht_ok_max_on == 0)
1062 				vht_ok_max_on = 1;
1063 			if (vht_ok_max_off == 0)
1064 				vht_ok_max_off = 1;
1065 			utility_on = (vht_fail_max_on << 7) / vht_ok_max_on;
1066 			utility_off = (vht_fail_max_off << 7) / vht_ok_max_off;
1067 			crc_taget = (utility_on == utility_off) ?
1068 				    (soml_tab->soml_last_state) :
1069 				    ((utility_on < utility_off) ? SOML_ON :
1070 				    SOML_OFF);
1071 		}
1072 		#endif
1073 
1074 	}
1075 
1076 	/* @[Decision] */
1077 	PHYDM_DBG(dm, DBG_ADPTV_SOML,
1078 		  "[  rate_per_pkt_on = %d ; rate_per_pkt_off = %d ]\n",
1079 		  rate_per_pkt_on, rate_per_pkt_off);
1080 	#if (DM_ODM_SUPPORT_TYPE == ODM_AP)
1081 	if (max_idx_on == max_idx_off && max_idx_on != 0) {
1082 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
1083 			  "[ max_idx_on == max_idx_off ]\n");
1084 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
1085 			  "[ max_idx = %d, crc_utility_on = %d, crc_utility_off = %d, crc_target = %d]\n",
1086 			  max_idx_on, utility_on, utility_off,
1087 			  crc_taget);
1088 		next_on_off = crc_taget;
1089 	} else
1090 	#endif
1091 	if (rate_per_pkt_on > rate_per_pkt_off) {
1092 		next_on_off = SOML_ON;
1093 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
1094 			  "[ rate_per_pkt_on > rate_per_pkt_off ==> SOML_ON ]\n");
1095 	} else if (rate_per_pkt_on < rate_per_pkt_off) {
1096 		next_on_off = SOML_OFF;
1097 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
1098 			  "[ rate_per_pkt_on < rate_per_pkt_off ==> SOML_OFF ]\n");
1099 	} else {
1100 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
1101 			  "[ stay at soml_last_state ]\n");
1102 		next_on_off = soml_tab->soml_last_state;
1103 	}
1104 
1105 	PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
1106 	phydm_soml_on_off(dm, next_on_off);
1107 	soml_tab->soml_last_state = next_on_off;
1108 }
1109 
phydm_adsl(void * dm_void)1110 void phydm_adsl(void *dm_void)
1111 {
1112 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1113 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1114 
1115 	if (dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC) {
1116 		PHYDM_DBG(dm, DBG_ADPTV_SOML, "soml_state_cnt =((%d))\n",
1117 			  soml_tab->soml_state_cnt);
1118 		/*Traning state: 0(alt) 1(ori) 2(alt) 3(ori)===============*/
1119 		if (soml_tab->soml_state_cnt <
1120 		    (soml_tab->soml_train_num << 1)) {
1121 			if (soml_tab->soml_state_cnt == 0)
1122 				phydm_adsl_init_state(dm);
1123 			else if ((soml_tab->soml_state_cnt % 2) != 0)
1124 				phydm_adsl_odd_state(dm);
1125 			else if ((soml_tab->soml_state_cnt % 2) == 0)
1126 				phydm_adsl_even_state(dm);
1127 		} else {
1128 			phydm_adsl_decision_state(dm);
1129 		}
1130 	}
1131 }
1132 
phydm_adaptive_soml_reset(void * dm_void)1133 void phydm_adaptive_soml_reset(void *dm_void)
1134 {
1135 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1136 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1137 
1138 	soml_tab->soml_state_cnt = 0;
1139 	soml_tab->is_soml_method_enable = 0;
1140 	soml_tab->soml_counter = 0;
1141 }
1142 
phydm_set_adsl_val(void * dm_void,u32 * val_buf,u8 val_len)1143 void phydm_set_adsl_val(void *dm_void, u32 *val_buf, u8 val_len)
1144 {
1145 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1146 
1147 	if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML))
1148 		return;
1149 
1150 	if (val_len != 1) {
1151 		PHYDM_DBG(dm, ODM_COMP_API, "[Error][ADSL]Need val_len=1\n");
1152 		return;
1153 	}
1154 
1155 	phydm_soml_on_off(dm, (u8)val_buf[1]);
1156 }
1157 
phydm_soml_crc_acq(void * dm_void,u8 rate_id,boolean crc32,u32 length)1158 void phydm_soml_crc_acq(void *dm_void, u8 rate_id, boolean crc32, u32 length)
1159 {
1160 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1161 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1162 	u8 offset = 0;
1163 
1164 	if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML))
1165 		return;
1166 
1167 	if (!soml_tab->get_stats)
1168 		return;
1169 	if (length < 1400)
1170 		return;
1171 
1172 	if (soml_tab->soml_on_off == SOML_ON) {
1173 		if (rate_id >= ODM_RATEMCS0 && rate_id <= ODM_RATEMCS15) {
1174 			offset = rate_id - ODM_RATEMCS0;
1175 			if (crc32 == CRC_OK)
1176 				soml_tab->ht_crc_ok_cnt_on[offset]++;
1177 			else if (crc32 == CRC_FAIL)
1178 				soml_tab->ht_crc_fail_cnt_on[offset]++;
1179 		} else if (rate_id >= ODM_RATEVHTSS1MCS0 &&
1180 			   rate_id <= ODM_RATEVHTSS2MCS9) {
1181 			offset = rate_id - ODM_RATEVHTSS1MCS0;
1182 			if (crc32 == CRC_OK)
1183 				soml_tab->vht_crc_ok_cnt_on[offset]++;
1184 			else if (crc32 == CRC_FAIL)
1185 				soml_tab->vht_crc_fail_cnt_on[offset]++;
1186 		}
1187 	} else if (soml_tab->soml_on_off == SOML_OFF) {
1188 		if (rate_id >= ODM_RATEMCS0 && rate_id <= ODM_RATEMCS15) {
1189 			offset = rate_id - ODM_RATEMCS0;
1190 			if (crc32 == CRC_OK)
1191 				soml_tab->ht_crc_ok_cnt_off[offset]++;
1192 			else if (crc32 == CRC_FAIL)
1193 				soml_tab->ht_crc_fail_cnt_off[offset]++;
1194 		} else if (rate_id >= ODM_RATEVHTSS1MCS0 &&
1195 			   rate_id <= ODM_RATEVHTSS2MCS9) {
1196 			offset = rate_id - ODM_RATEVHTSS1MCS0;
1197 			if (crc32 == CRC_OK)
1198 				soml_tab->vht_crc_ok_cnt_off[offset]++;
1199 			else if (crc32 == CRC_FAIL)
1200 				soml_tab->vht_crc_fail_cnt_off[offset]++;
1201 		}
1202 	}
1203 }
1204 
phydm_soml_bytes_acq(void * dm_void,u8 rate_id,u32 length)1205 void phydm_soml_bytes_acq(void *dm_void, u8 rate_id, u32 length)
1206 {
1207 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1208 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1209 	u8 offset = 0;
1210 
1211 	if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML))
1212 		return;
1213 
1214 	if (rate_id >= ODM_RATEMCS0 && rate_id <= ODM_RATEMCS31) {
1215 		offset = rate_id - ODM_RATEMCS0;
1216 		if (offset > (HT_RATE_IDX - 1))
1217 			offset = HT_RATE_IDX - 1;
1218 
1219 		soml_tab->ht_byte[offset] += (u16)length;
1220 	} else if (rate_id >= ODM_RATEVHTSS1MCS0 &&
1221 		   rate_id <= ODM_RATEVHTSS4MCS9) {
1222 		offset = rate_id - ODM_RATEVHTSS1MCS0;
1223 		if (offset > (VHT_RATE_IDX - 1))
1224 			offset = VHT_RATE_IDX - 1;
1225 
1226 		soml_tab->vht_byte[offset] += (u16)length;
1227 	}
1228 }
1229 
1230 #if defined(CONFIG_RTL_TRIBAND_SUPPORT) && defined(CONFIG_USB_HCI)
pre_phydm_adaptive_soml_callback(unsigned long task_dm)1231 static void pre_phydm_adaptive_soml_callback(unsigned long task_dm)
1232 {
1233 	struct dm_struct *dm = (struct dm_struct *)task_dm;
1234 	struct rtl8192cd_priv *priv = dm->priv;
1235 	struct priv_shared_info *pshare = priv->pshare;
1236 
1237 	if (!(priv->drv_state & DRV_STATE_OPEN))
1238 		return;
1239 	if (pshare->bDriverStopped || pshare->bSurpriseRemoved) {
1240 		printk("[%s] bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
1241 		       __FUNCTION__, pshare->bDriverStopped,
1242 		       pshare->bSurpriseRemoved);
1243 		return;
1244 	}
1245 
1246 	rtw_enqueue_timer_event(priv, &pshare->adaptive_soml_event,
1247 				ENQUEUE_TO_TAIL);
1248 }
1249 
phydm_adaptive_soml_timers_usb(void * dm_void,u8 state)1250 void phydm_adaptive_soml_timers_usb(void *dm_void, u8 state)
1251 {
1252 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1253 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1254 	struct rtl8192cd_priv *priv = dm->priv;
1255 
1256 	if (state == INIT_SOML_TIMMER) {
1257 		init_timer(&soml_tab->phydm_adaptive_soml_timer);
1258 		soml_tab->phydm_adaptive_soml_timer.data = (unsigned long)dm;
1259 		soml_tab->phydm_adaptive_soml_timer.function = pre_phydm_adaptive_soml_callback;
1260 		INIT_TIMER_EVENT_ENTRY(&priv->pshare->adaptive_soml_event,
1261 				       phydm_adaptive_soml_callback,
1262 				       (unsigned long)dm);
1263 	} else if (state == CANCEL_SOML_TIMMER) {
1264 		odm_cancel_timer(dm, &soml_tab->phydm_adaptive_soml_timer);
1265 	} else if (state == RELEASE_SOML_TIMMER) {
1266 		odm_release_timer(dm, &soml_tab->phydm_adaptive_soml_timer);
1267 	}
1268 }
1269 #endif /* defined(CONFIG_RTL_TRIBAND_SUPPORT) && defined(CONFIG_USB_HCI) */
1270 
phydm_adaptive_soml_timers(void * dm_void,u8 state)1271 void phydm_adaptive_soml_timers(void *dm_void, u8 state)
1272 {
1273 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1274 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1275 
1276 	if (!(dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC))
1277 		return;
1278 
1279 #if defined(CONFIG_RTL_TRIBAND_SUPPORT) && defined(CONFIG_USB_HCI)
1280 	struct rtl8192cd_priv *priv = dm->priv;
1281 
1282 	if (priv->hci_type == RTL_HCI_USB) {
1283 		phydm_adaptive_soml_timers_usb(dm_void, state);
1284 	} else
1285 #endif /* defined(CONFIG_RTL_TRIBAND_SUPPORT) && defined(CONFIG_USB_HCI) */
1286 	{
1287 	if (state == INIT_SOML_TIMMER) {
1288 		odm_initialize_timer(dm, &soml_tab->phydm_adaptive_soml_timer,
1289 				     (void *)phydm_adaptive_soml_callback, NULL,
1290 				     "phydm_adaptive_soml_timer");
1291 	} else if (state == CANCEL_SOML_TIMMER) {
1292 		odm_cancel_timer(dm, &soml_tab->phydm_adaptive_soml_timer);
1293 	} else if (state == RELEASE_SOML_TIMMER) {
1294 		odm_release_timer(dm, &soml_tab->phydm_adaptive_soml_timer);
1295 	}
1296 	}
1297 }
1298 
phydm_adaptive_soml_init(void * dm_void)1299 void phydm_adaptive_soml_init(void *dm_void)
1300 {
1301 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1302 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1303 #if 0
1304 	if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) {
1305 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
1306 			  "[Return]   Not Support Adaptive SOML\n");
1307 		return;
1308 	}
1309 #endif
1310 
1311 	if (!(dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC))
1312 		return;
1313 
1314 	PHYDM_DBG(dm, DBG_ADPTV_SOML, "%s\n", __func__);
1315 
1316 	soml_tab->soml_state_cnt = 0;
1317 	soml_tab->soml_delay_time = 40;
1318 	soml_tab->soml_intvl = 150;
1319 	soml_tab->soml_train_num = 4;
1320 	soml_tab->is_soml_method_enable = 0;
1321 	soml_tab->soml_counter = 0;
1322 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
1323 	soml_tab->soml_period = 1;
1324 #else
1325 	soml_tab->soml_period = 4;
1326 #endif
1327 	soml_tab->soml_select = 0;
1328 	soml_tab->cfo_cnt = 0;
1329 	soml_tab->cfo_diff_sum_a = 0;
1330 	soml_tab->cfo_diff_sum_b = 0;
1331 
1332 	soml_tab->cfo_qpsk_th = 94;
1333 	soml_tab->cfo_qam16_th = 38;
1334 	soml_tab->cfo_qam64_th = 17;
1335 	soml_tab->cfo_qam256_th = 7;
1336 
1337 	soml_tab->bpsk_qpsk_dist_th = 20;
1338 	soml_tab->qam16_dist_th = 20;
1339 	soml_tab->qam64_dist_th = 20;
1340 	soml_tab->qam256_dist_th = 20;
1341 
1342 	if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F))
1343 		odm_set_bb_reg(dm, 0x988, BIT(25), 1);
1344 }
1345 
phydm_adaptive_soml(void * dm_void)1346 void phydm_adaptive_soml(void *dm_void)
1347 {
1348 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1349 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1350 
1351 	if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) {
1352 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
1353 			  "[Return!!!] Not Support Adaptive SOML Function\n");
1354 		return;
1355 	}
1356 
1357 	if (dm->pause_ability & ODM_BB_ADAPTIVE_SOML) {
1358 		PHYDM_DBG(dm, DBG_ADPTV_SOML, "Return: Pause ADSL in LV=%d\n",
1359 			  dm->pause_lv_table.lv_adsl);
1360 		return;
1361 	}
1362 
1363 	if (soml_tab->soml_counter < soml_tab->soml_period) {
1364 		soml_tab->soml_counter++;
1365 		return;
1366 	}
1367 	soml_tab->soml_counter = 0;
1368 	soml_tab->soml_state_cnt = 0;
1369 	soml_tab->cfo_cnt = 0;
1370 	soml_tab->cfo_diff_sum_a = 0;
1371 	soml_tab->cfo_diff_sum_b = 0;
1372 
1373 	phydm_soml_reset_qam(dm);
1374 
1375 	if (soml_tab->soml_select == 0) {
1376 		PHYDM_DBG(dm, DBG_ADPTV_SOML,
1377 			  "[ Adaptive SOML Training !!!]\n");
1378 	} else if (soml_tab->soml_select == 1) {
1379 		PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Stop Adaptive SOML !!!]\n");
1380 		phydm_soml_on_off(dm, SOML_ON);
1381 		return;
1382 	} else if (soml_tab->soml_select == 2) {
1383 		PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Stop Adaptive SOML !!!]\n");
1384 		phydm_soml_on_off(dm, SOML_OFF);
1385 		return;
1386 	}
1387 
1388 	if (dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC)
1389 		phydm_adsl(dm);
1390 }
1391 
phydm_enable_adaptive_soml(void * dm_void)1392 void phydm_enable_adaptive_soml(void *dm_void)
1393 {
1394 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1395 
1396 	PHYDM_DBG(dm, DBG_ADPTV_SOML, "[%s]\n", __func__);
1397 	dm->support_ability |= ODM_BB_ADAPTIVE_SOML;
1398 	phydm_soml_on_off(dm, SOML_ON);
1399 }
1400 
phydm_stop_adaptive_soml(void * dm_void)1401 void phydm_stop_adaptive_soml(void *dm_void)
1402 {
1403 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1404 
1405 	PHYDM_DBG(dm, DBG_ADPTV_SOML, "[%s]\n", __func__);
1406 	dm->support_ability &= ~ODM_BB_ADAPTIVE_SOML;
1407 	phydm_soml_on_off(dm, SOML_ON);
1408 }
1409 
phydm_adaptive_soml_para_set(void * dm_void,u8 train_num,u8 intvl,u8 period,u8 delay_time)1410 void phydm_adaptive_soml_para_set(void *dm_void, u8 train_num, u8 intvl,
1411 				  u8 period, u8 delay_time)
1412 {
1413 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1414 	struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1415 
1416 	soml_tab->soml_train_num = train_num;
1417 	soml_tab->soml_intvl = intvl;
1418 	soml_tab->soml_period = period;
1419 	soml_tab->soml_delay_time = delay_time;
1420 }
1421 #endif /* @end of CONFIG_ADAPTIVE_SOML*/
1422 
phydm_init_soft_ml_setting(void * dm_void)1423 void phydm_init_soft_ml_setting(void *dm_void)
1424 {
1425 	struct dm_struct *dm = (struct dm_struct *)dm_void;
1426 	u32 soml_mask = BIT(31) | BIT(30) | BIT(29) | BIT(28);
1427 
1428 #if (RTL8822B_SUPPORT == 1)
1429 	if (!*dm->mp_mode) {
1430 		if (dm->support_ic_type & ODM_RTL8822B) {
1431 #if 0
1432 			/*odm_set_bb_reg(dm, R_0x19a8, MASKDWORD, 0xd10a0000);*/
1433 #endif
1434 			phydm_somlrxhp_setting(dm, true);
1435 			dm->bsomlenabled = true;
1436 		}
1437 	}
1438 #endif
1439 #if (RTL8821C_SUPPORT == 1)
1440 	if (!*dm->mp_mode) {
1441 		if (dm->support_ic_type & ODM_RTL8821C)
1442 			odm_set_bb_reg(dm, R_0x19a8, soml_mask, 0xd);
1443 	}
1444 #endif
1445 #if (RTL8195B_SUPPORT == 1)
1446 	if (!*dm->mp_mode) {
1447 		if (dm->support_ic_type & ODM_RTL8195B)
1448 			odm_set_bb_reg(dm, R_0x19a8, soml_mask, 0xd);
1449 	}
1450 #endif
1451 }
1452