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