xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8723ds/hal/phydm/phydm_cfotracking.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 #include "mp_precomp.h"
26*4882a593Smuzhiyun #include "phydm_precomp.h"
27*4882a593Smuzhiyun 
phydm_get_cfo_hz(void * dm_void,u32 val,u8 bit_num,u8 frac_num)28*4882a593Smuzhiyun s32 phydm_get_cfo_hz(void *dm_void, u32 val, u8 bit_num, u8 frac_num)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun 	s32 val_s = 0;
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	val_s = phydm_cnvrt_2_sign(val, bit_num);
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	if (frac_num == 10) /*@ (X*312500)/1024 ~= X*305*/
35*4882a593Smuzhiyun 		val_s *= 305;
36*4882a593Smuzhiyun 	else if (frac_num == 11) /*@ (X*312500)/2048 ~= X*152*/
37*4882a593Smuzhiyun 		val_s *= 152;
38*4882a593Smuzhiyun 	else if (frac_num == 12) /*@ (X*312500)/4096 ~= X*76*/
39*4882a593Smuzhiyun 		val_s *= 76;
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	return val_s;
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #if (ODM_IC_11AC_SERIES_SUPPORT)
phydm_get_cfo_info_ac(void * dm_void,struct phydm_cfo_rpt * cfo)45*4882a593Smuzhiyun void phydm_get_cfo_info_ac(void *dm_void, struct phydm_cfo_rpt *cfo)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
48*4882a593Smuzhiyun 	u8 i = 0;
49*4882a593Smuzhiyun 	u32 val[4] = {0};
50*4882a593Smuzhiyun 	u32 val_1[4] = {0};
51*4882a593Smuzhiyun 	u32 val_2[4] = {0};
52*4882a593Smuzhiyun 	u32 val_tmp = 0;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	val[0] = odm_read_4byte(dm, R_0xd0c);
55*4882a593Smuzhiyun 	val_1[0] = odm_read_4byte(dm, R_0xd10);
56*4882a593Smuzhiyun 	val_2[0] = odm_get_bb_reg(dm, R_0xd14, 0x1fff0000);
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	#if (defined(PHYDM_COMPILE_ABOVE_2SS))
59*4882a593Smuzhiyun 	val[1] = odm_read_4byte(dm, R_0xd4c);
60*4882a593Smuzhiyun 	val_1[1] = odm_read_4byte(dm, R_0xd50);
61*4882a593Smuzhiyun 	val_2[1] = odm_get_bb_reg(dm, R_0xd54, 0x1fff0000);
62*4882a593Smuzhiyun 	#endif
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	#if (defined(PHYDM_COMPILE_ABOVE_3SS))
65*4882a593Smuzhiyun 	val[2] = odm_read_4byte(dm, R_0xd8c);
66*4882a593Smuzhiyun 	val_1[2] = odm_read_4byte(dm, R_0xd90);
67*4882a593Smuzhiyun 	val_2[2] = odm_get_bb_reg(dm, R_0xd94, 0x1fff0000);
68*4882a593Smuzhiyun 	#endif
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 	#if (defined(PHYDM_COMPILE_ABOVE_4SS))
71*4882a593Smuzhiyun 	val[3] = odm_read_4byte(dm, R_0xdcc);
72*4882a593Smuzhiyun 	val_1[3] = odm_read_4byte(dm, R_0xdd0);
73*4882a593Smuzhiyun 	val_2[3] = odm_get_bb_reg(dm, R_0xdd4, 0x1fff0000);
74*4882a593Smuzhiyun 	#endif
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	for (i = 0; i < dm->num_rf_path; i++) {
77*4882a593Smuzhiyun 		val_tmp = val[i] & 0xfff;	/*@ Short CFO, S(12,11)*/
78*4882a593Smuzhiyun 		cfo->cfo_rpt_s[i] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 		val_tmp = val[i] >> 16;		/*@ Long CFO, S(13,12)*/
81*4882a593Smuzhiyun 		cfo->cfo_rpt_l[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 		val_tmp = val_1[i] & 0x7ff;	/*@ SCFO, S(11,10)*/
84*4882a593Smuzhiyun 		cfo->cfo_rpt_sec[i] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 		val_tmp = val_1[i] >> 16;	/*@ Acq CFO, S(13,12)*/
87*4882a593Smuzhiyun 		cfo->cfo_rpt_acq[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 		val_tmp = val_2[i];		/*@ End CFO, S(13,12)*/
90*4882a593Smuzhiyun 		cfo->cfo_rpt_end[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
91*4882a593Smuzhiyun 	}
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun #endif
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun #if (ODM_IC_11N_SERIES_SUPPORT)
phydm_get_cfo_info_n(void * dm_void,struct phydm_cfo_rpt * cfo)96*4882a593Smuzhiyun void phydm_get_cfo_info_n(void *dm_void, struct phydm_cfo_rpt *cfo)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
99*4882a593Smuzhiyun 	u32 val[5] = {0};
100*4882a593Smuzhiyun 	u32 val_tmp = 0;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0xd00, BIT(26), 1);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	val[0] = odm_read_4byte(dm, R_0xdac); /*@ Short CFO*/
105*4882a593Smuzhiyun 	val[1] = odm_read_4byte(dm, R_0xdb0); /*@ Long CFO*/
106*4882a593Smuzhiyun 	val[2] = odm_read_4byte(dm, R_0xdb8); /*@ Sec CFO*/
107*4882a593Smuzhiyun 	val[3] = odm_read_4byte(dm, R_0xde0); /*@ Acq CFO*/
108*4882a593Smuzhiyun 	val[4] = odm_read_4byte(dm, R_0xdbc); /*@ End CFO*/
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	/*@[path-A]*/
111*4882a593Smuzhiyun 	if (dm->support_ic_type & (ODM_RTL8721D | ODM_RTL8710C)) {
112*4882a593Smuzhiyun 		val_tmp = (val[0] & 0x0fff0000) >> 16; /*@ Short CFO, S(12,11)*/
113*4882a593Smuzhiyun 		cfo->cfo_rpt_s[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
114*4882a593Smuzhiyun 		val_tmp = (val[1] & 0x0fff0000) >> 16;	/*@ Long CFO, S(12,11)*/
115*4882a593Smuzhiyun 		cfo->cfo_rpt_l[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
116*4882a593Smuzhiyun 		val_tmp = (val[2] & 0x0fff0000) >> 16;	/*@ Sec CFO, S(12,11)*/
117*4882a593Smuzhiyun 		cfo->cfo_rpt_sec[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
118*4882a593Smuzhiyun 		val_tmp = (val[3] & 0x0fff0000) >> 16;	/*@ Acq CFO, S(12,11)*/
119*4882a593Smuzhiyun 		cfo->cfo_rpt_acq[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
120*4882a593Smuzhiyun 		val_tmp = (val[4] & 0x0fff0000) >> 16;	/*@ Acq CFO, S(12,11)*/
121*4882a593Smuzhiyun 		cfo->cfo_rpt_end[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
122*4882a593Smuzhiyun 	} else {
123*4882a593Smuzhiyun 		val_tmp = (val[0] & 0x0fff0000) >> 16; /*@ Short CFO, S(12,11)*/
124*4882a593Smuzhiyun 		cfo->cfo_rpt_s[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
125*4882a593Smuzhiyun 		val_tmp = (val[1] & 0x1fff0000) >> 16;	/*@ Long CFO, S(13,12)*/
126*4882a593Smuzhiyun 		cfo->cfo_rpt_l[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
127*4882a593Smuzhiyun 		val_tmp = (val[2] & 0x7ff0000) >> 16;	/*@ Sec CFO, S(11,10)*/
128*4882a593Smuzhiyun 		cfo->cfo_rpt_sec[0] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);
129*4882a593Smuzhiyun 		val_tmp = (val[3] & 0x1fff0000) >> 16;	/*@ Acq CFO, S(13,12)*/
130*4882a593Smuzhiyun 		cfo->cfo_rpt_acq[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
131*4882a593Smuzhiyun 		val_tmp = (val[4] & 0x1fff0000) >> 16;	/*@ Acq CFO, S(13,12)*/
132*4882a593Smuzhiyun 		cfo->cfo_rpt_end[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
133*4882a593Smuzhiyun 	}
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	#if (defined(PHYDM_COMPILE_ABOVE_2SS))
136*4882a593Smuzhiyun 	/*@[path-B]*/
137*4882a593Smuzhiyun 	val_tmp = val[0] & 0xfff;		/*@ Short CFO, S(12,11)*/
138*4882a593Smuzhiyun 	cfo->cfo_rpt_s[1] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
139*4882a593Smuzhiyun 	val_tmp = val[1] & 0x1fff;		/*@ Long CFO, S(13,12)*/
140*4882a593Smuzhiyun 	cfo->cfo_rpt_l[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
141*4882a593Smuzhiyun 	val_tmp = val[2] & 0x7ff;		/*@ Sec CFO, S(11,10)*/
142*4882a593Smuzhiyun 	cfo->cfo_rpt_sec[1] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);
143*4882a593Smuzhiyun 	val_tmp = val[3] & 0x1fff;		/*@ Acq CFO, S(13,12)*/
144*4882a593Smuzhiyun 	cfo->cfo_rpt_acq[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
145*4882a593Smuzhiyun 	val_tmp = val[4] & 0x1fff;		/*@ Acq CFO, S(13,12)*/
146*4882a593Smuzhiyun 	cfo->cfo_rpt_end[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
147*4882a593Smuzhiyun 	#endif
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun 
phydm_set_atc_status(void * dm_void,boolean atc_status)150*4882a593Smuzhiyun void phydm_set_atc_status(void *dm_void, boolean atc_status)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
153*4882a593Smuzhiyun 	struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
154*4882a593Smuzhiyun 	u32 reg_tmp = 0;
155*4882a593Smuzhiyun 	u32 mask_tmp = 0;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]ATC_en=%d\n", __func__, atc_status);
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	if (cfo_track->is_atc_status == atc_status)
160*4882a593Smuzhiyun 		return;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	reg_tmp = ODM_REG(BB_ATC, dm);
163*4882a593Smuzhiyun 	mask_tmp = ODM_BIT(BB_ATC, dm);
164*4882a593Smuzhiyun 	odm_set_bb_reg(dm, reg_tmp, mask_tmp, atc_status);
165*4882a593Smuzhiyun 	cfo_track->is_atc_status = atc_status;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun boolean
phydm_get_atc_status(void * dm_void)169*4882a593Smuzhiyun phydm_get_atc_status(void *dm_void)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun 	boolean atc_status = false;
172*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
173*4882a593Smuzhiyun 	u32 reg_tmp = 0;
174*4882a593Smuzhiyun 	u32 mask_tmp = 0;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	reg_tmp = ODM_REG(BB_ATC, dm);
177*4882a593Smuzhiyun 	mask_tmp = ODM_BIT(BB_ATC, dm);
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	atc_status = (boolean)odm_get_bb_reg(dm, reg_tmp, mask_tmp);
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]atc_status=%d\n", __func__, atc_status);
182*4882a593Smuzhiyun 	return atc_status;
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun #endif
185*4882a593Smuzhiyun 
phydm_get_cfo_info(void * dm_void,struct phydm_cfo_rpt * cfo)186*4882a593Smuzhiyun void phydm_get_cfo_info(void *dm_void, struct phydm_cfo_rpt *cfo)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	switch (dm->ic_ip_series) {
191*4882a593Smuzhiyun 	#if (ODM_IC_11N_SERIES_SUPPORT)
192*4882a593Smuzhiyun 	case PHYDM_IC_N:
193*4882a593Smuzhiyun 		phydm_get_cfo_info_n(dm, cfo);
194*4882a593Smuzhiyun 		break;
195*4882a593Smuzhiyun 	#endif
196*4882a593Smuzhiyun 	#if (ODM_IC_11AC_SERIES_SUPPORT)
197*4882a593Smuzhiyun 	case PHYDM_IC_AC:
198*4882a593Smuzhiyun 		phydm_get_cfo_info_ac(dm, cfo);
199*4882a593Smuzhiyun 		break;
200*4882a593Smuzhiyun 	#endif
201*4882a593Smuzhiyun 	default:
202*4882a593Smuzhiyun 		break;
203*4882a593Smuzhiyun 	}
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun boolean
phydm_set_crystal_cap_reg(void * dm_void,u8 crystal_cap)207*4882a593Smuzhiyun phydm_set_crystal_cap_reg(void *dm_void, u8 crystal_cap)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
210*4882a593Smuzhiyun 	struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
211*4882a593Smuzhiyun 	u32 reg_val = 0;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B |
214*4882a593Smuzhiyun 	    ODM_RTL8195B | ODM_RTL8812F | ODM_RTL8721D | ODM_RTL8710C|ODM_RTL8723F)) {
215*4882a593Smuzhiyun 		crystal_cap &= 0x7F;
216*4882a593Smuzhiyun 		reg_val = crystal_cap | (crystal_cap << 7);
217*4882a593Smuzhiyun 	} else {
218*4882a593Smuzhiyun 		crystal_cap &= 0x3F;
219*4882a593Smuzhiyun 		reg_val = crystal_cap | (crystal_cap << 6);
220*4882a593Smuzhiyun 	}
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	cfo_track->crystal_cap = crystal_cap;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8188F)) {
225*4882a593Smuzhiyun 		#if (RTL8188E_SUPPORT || RTL8188F_SUPPORT)
226*4882a593Smuzhiyun 		/* write 0x24[22:17] = 0x24[16:11] = crystal_cap */
227*4882a593Smuzhiyun 		odm_set_mac_reg(dm, R_0x24, 0x7ff800, reg_val);
228*4882a593Smuzhiyun 		#endif
229*4882a593Smuzhiyun 	}
230*4882a593Smuzhiyun 	#if (RTL8812A_SUPPORT)
231*4882a593Smuzhiyun 	else if (dm->support_ic_type & ODM_RTL8812) {
232*4882a593Smuzhiyun 		/* write 0x2C[30:25] = 0x2C[24:19] = crystal_cap */
233*4882a593Smuzhiyun 		odm_set_mac_reg(dm, R_0x2c, 0x7FF80000, reg_val);
234*4882a593Smuzhiyun 	}
235*4882a593Smuzhiyun 	#endif
236*4882a593Smuzhiyun 	#if (RTL8703B_SUPPORT || RTL8723B_SUPPORT || RTL8192E_SUPPORT ||\
237*4882a593Smuzhiyun 	     RTL8821A_SUPPORT || RTL8723D_SUPPORT)
238*4882a593Smuzhiyun 	else if ((dm->support_ic_type &
239*4882a593Smuzhiyun 		 (ODM_RTL8703B | ODM_RTL8723B | ODM_RTL8192E | ODM_RTL8821 |
240*4882a593Smuzhiyun 		 ODM_RTL8723D))) {
241*4882a593Smuzhiyun 		/* @0x2C[23:18] = 0x2C[17:12] = crystal_cap */
242*4882a593Smuzhiyun 		odm_set_mac_reg(dm, R_0x2c, 0x00FFF000, reg_val);
243*4882a593Smuzhiyun 	}
244*4882a593Smuzhiyun 	#endif
245*4882a593Smuzhiyun 	#if (RTL8814A_SUPPORT)
246*4882a593Smuzhiyun 	else if (dm->support_ic_type & ODM_RTL8814A) {
247*4882a593Smuzhiyun 		/* write 0x2C[26:21] = 0x2C[20:15] = crystal_cap */
248*4882a593Smuzhiyun 		odm_set_mac_reg(dm, R_0x2c, 0x07FF8000, reg_val);
249*4882a593Smuzhiyun 	}
250*4882a593Smuzhiyun 	#endif
251*4882a593Smuzhiyun 	#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8197F_SUPPORT ||\
252*4882a593Smuzhiyun 	     RTL8192F_SUPPORT || RTL8197G_SUPPORT || RTL8198F_SUPPORT)
253*4882a593Smuzhiyun 	else if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C |
254*4882a593Smuzhiyun 		 ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8197G | ODM_RTL8198F)) {
255*4882a593Smuzhiyun 		/* write 0x24[30:25] = 0x28[6:1] = crystal_cap */
256*4882a593Smuzhiyun 		odm_set_mac_reg(dm, R_0x24, 0x7e000000, crystal_cap);
257*4882a593Smuzhiyun 		odm_set_mac_reg(dm, R_0x28, 0x7e, crystal_cap);
258*4882a593Smuzhiyun 	}
259*4882a593Smuzhiyun 	#endif
260*4882a593Smuzhiyun 	#if (RTL8710B_SUPPORT)
261*4882a593Smuzhiyun 	else if (dm->support_ic_type & (ODM_RTL8710B)) {
262*4882a593Smuzhiyun 		#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
263*4882a593Smuzhiyun 		/* write 0x60[29:24] = 0x60[23:18] = crystal_cap */
264*4882a593Smuzhiyun 		HAL_SetSYSOnReg(dm->adapter, R_0x60, 0x3FFC0000, reg_val);
265*4882a593Smuzhiyun 		#endif
266*4882a593Smuzhiyun 	}
267*4882a593Smuzhiyun 	#endif
268*4882a593Smuzhiyun 	#if (RTL8195B_SUPPORT)
269*4882a593Smuzhiyun 	else if (dm->support_ic_type & ODM_RTL8195B) {
270*4882a593Smuzhiyun 		phydm_set_crystalcap(dm, (u8)(reg_val & 0x7f));
271*4882a593Smuzhiyun 	}
272*4882a593Smuzhiyun 	#endif
273*4882a593Smuzhiyun 	#if (RTL8721D_SUPPORT)
274*4882a593Smuzhiyun 	else if (dm->support_ic_type & (ODM_RTL8721D)) {
275*4882a593Smuzhiyun 		/* write 0x4800_0228[30:24] crystal_cap */
276*4882a593Smuzhiyun 		/*HAL_SetSYSOnReg(dm->adapter, */
277*4882a593Smuzhiyun 		/*REG_SYS_XTAL_8721d, 0x7F000000, crystal_cap);*/
278*4882a593Smuzhiyun 		u32 temp_val = HAL_READ32(SYSTEM_CTRL_BASE_LP,
279*4882a593Smuzhiyun 					   REG_SYS_EFUSE_SYSCFG2);
280*4882a593Smuzhiyun 		temp_val = ((crystal_cap << 24) & 0x7F000000)
281*4882a593Smuzhiyun 						| (temp_val & (~0x7F000000));
282*4882a593Smuzhiyun 		HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_SYS_EFUSE_SYSCFG2,
283*4882a593Smuzhiyun 			    temp_val);
284*4882a593Smuzhiyun 	}
285*4882a593Smuzhiyun 	#endif
286*4882a593Smuzhiyun 	#if (RTL8710C_SUPPORT)
287*4882a593Smuzhiyun 	else if (dm->support_ic_type & (ODM_RTL8710C)) {
288*4882a593Smuzhiyun 		/* write MAC reg 0x28[13:7][6:0] crystal_cap */
289*4882a593Smuzhiyun 		phydm_set_crystalcap(dm, (u8)(reg_val & 0x7f));
290*4882a593Smuzhiyun 	}
291*4882a593Smuzhiyun 	#endif
292*4882a593Smuzhiyun 	#if (RTL8723F_SUPPORT)
293*4882a593Smuzhiyun 	else if (dm->support_ic_type & ODM_RTL8723F) {
294*4882a593Smuzhiyun 		/* write 0x103c[23:17] = 0x103c[16:10] = crystal_cap */
295*4882a593Smuzhiyun 		odm_set_mac_reg(dm, R_0x103c, 0x00FFFC00, reg_val);
296*4882a593Smuzhiyun 	}
297*4882a593Smuzhiyun 	#endif
298*4882a593Smuzhiyun #if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8812F_SUPPORT)
299*4882a593Smuzhiyun 	else if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B |
300*4882a593Smuzhiyun 		 ODM_RTL8812F)) {
301*4882a593Smuzhiyun 		/* write 0x1040[23:17] = 0x1040[16:10] = crystal_cap */
302*4882a593Smuzhiyun 		odm_set_mac_reg(dm, R_0x1040, 0x00FFFC00, reg_val);
303*4882a593Smuzhiyun 	} else {
304*4882a593Smuzhiyun 		return false;
305*4882a593Smuzhiyun 	}
306*4882a593Smuzhiyun #endif
307*4882a593Smuzhiyun 	return true;
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun 
phydm_set_crystal_cap(void * dm_void,u8 crystal_cap)310*4882a593Smuzhiyun void phydm_set_crystal_cap(void *dm_void, u8 crystal_cap)
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
313*4882a593Smuzhiyun 	struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	if (cfo_track->crystal_cap == crystal_cap)
316*4882a593Smuzhiyun 		return;
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	if (phydm_set_crystal_cap_reg(dm, crystal_cap))
319*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_CFO_TRK, "Set crystal_cap = 0x%x\n",
320*4882a593Smuzhiyun 			  cfo_track->crystal_cap);
321*4882a593Smuzhiyun 	else
322*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_CFO_TRK, "Set fail\n");
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun 
phydm_cfo_tracking_reset(void * dm_void)325*4882a593Smuzhiyun void phydm_cfo_tracking_reset(void *dm_void)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
328*4882a593Smuzhiyun 	struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_CFO_TRK, "%s ======>\n", __func__);
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8195B |
333*4882a593Smuzhiyun 	    ODM_RTL8812F | ODM_RTL8710C | ODM_RTL8721D | ODM_RTL8723F))
334*4882a593Smuzhiyun 		cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x7f;
335*4882a593Smuzhiyun 	else
336*4882a593Smuzhiyun 		cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x3f;
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	cfo_track->is_adjust = true;
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	if (cfo_track->crystal_cap > cfo_track->def_x_cap) {
341*4882a593Smuzhiyun 		phydm_set_crystal_cap(dm, cfo_track->crystal_cap - 1);
342*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_CFO_TRK, "approch to Init-val (0x%x)\n",
343*4882a593Smuzhiyun 			  cfo_track->crystal_cap);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	} else if (cfo_track->crystal_cap < cfo_track->def_x_cap) {
346*4882a593Smuzhiyun 		phydm_set_crystal_cap(dm, cfo_track->crystal_cap + 1);
347*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_CFO_TRK, "approch to init-val 0x%x\n",
348*4882a593Smuzhiyun 			  cfo_track->crystal_cap);
349*4882a593Smuzhiyun 	}
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun #if ODM_IC_11N_SERIES_SUPPORT
352*4882a593Smuzhiyun #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
353*4882a593Smuzhiyun 	if (dm->support_ic_type & ODM_IC_11N_SERIES)
354*4882a593Smuzhiyun 		phydm_set_atc_status(dm, true);
355*4882a593Smuzhiyun #endif
356*4882a593Smuzhiyun #endif
357*4882a593Smuzhiyun #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
358*4882a593Smuzhiyun #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE | ODM_AP))
359*4882a593Smuzhiyun 	if (dm->support_ic_type & ODM_RTL8814B) {
360*4882a593Smuzhiyun 		/*Disable advance time for CFO residual*/
361*4882a593Smuzhiyun 		odm_set_bb_reg(dm, R_0xc2c, BIT29, 0x0);
362*4882a593Smuzhiyun 	}
363*4882a593Smuzhiyun #endif
364*4882a593Smuzhiyun #endif
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun 
phydm_cfo_tracking_init(void * dm_void)367*4882a593Smuzhiyun void phydm_cfo_tracking_init(void *dm_void)
368*4882a593Smuzhiyun {
369*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
370*4882a593Smuzhiyun 	struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]=========>\n", __func__);
373*4882a593Smuzhiyun 	if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8195B |
374*4882a593Smuzhiyun 	    ODM_RTL8812F | ODM_RTL8710C | ODM_RTL8721D | ODM_RTL8723F))
375*4882a593Smuzhiyun 		cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x7f;
376*4882a593Smuzhiyun 	else
377*4882a593Smuzhiyun 		cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x3f;
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	cfo_track->def_x_cap = cfo_track->crystal_cap;
380*4882a593Smuzhiyun 	cfo_track->is_adjust = true;
381*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_CFO_TRK, "crystal_cap=0x%x\n", cfo_track->def_x_cap);
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun #if (RTL8822B_SUPPORT || RTL8821C_SUPPORT)
384*4882a593Smuzhiyun 	/* @Crystal cap. control by WiFi */
385*4882a593Smuzhiyun 	if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C))
386*4882a593Smuzhiyun 		odm_set_mac_reg(dm, R_0x10, 0x40, 0x1);
387*4882a593Smuzhiyun #endif
388*4882a593Smuzhiyun }
389*4882a593Smuzhiyun 
phydm_cfo_tracking(void * dm_void)390*4882a593Smuzhiyun void phydm_cfo_tracking(void *dm_void)
391*4882a593Smuzhiyun {
392*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
393*4882a593Smuzhiyun 	struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
394*4882a593Smuzhiyun 	s32 cfo_avg = 0, cfo_path_sum = 0, cfo_abs = 0;
395*4882a593Smuzhiyun 	u32 cfo_rpt_sum = 0, cfo_khz_avg[4] = {0};
396*4882a593Smuzhiyun 	s8 crystal_cap = cfo_track->crystal_cap;
397*4882a593Smuzhiyun 	u8 i = 0, valid_path_cnt = 0;
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 	if (!(dm->support_ability & ODM_BB_CFO_TRACKING))
400*4882a593Smuzhiyun 		return;
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_CFO_TRK, "%s ======>\n", __func__);
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	if (!dm->is_linked || !dm->is_one_entry_only) {
405*4882a593Smuzhiyun 		phydm_cfo_tracking_reset(dm);
406*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_CFO_TRK, "is_linked=%d, one_entry_only=%d\n",
407*4882a593Smuzhiyun 			  dm->is_linked, dm->is_one_entry_only);
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	} else {
410*4882a593Smuzhiyun 		/* No new packet */
411*4882a593Smuzhiyun 		if (cfo_track->packet_count == cfo_track->packet_count_pre) {
412*4882a593Smuzhiyun 			PHYDM_DBG(dm, DBG_CFO_TRK, "Pkt cnt doesn't change\n");
413*4882a593Smuzhiyun 			return;
414*4882a593Smuzhiyun 		}
415*4882a593Smuzhiyun 		cfo_track->packet_count_pre = cfo_track->packet_count;
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 		/*@Calculate CFO */
418*4882a593Smuzhiyun 		for (i = 0; i < dm->num_rf_path; i++) {
419*4882a593Smuzhiyun 			if (!(dm->rx_ant_status & BIT(i)))
420*4882a593Smuzhiyun 				continue;
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 			valid_path_cnt++;
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 			if (cfo_track->CFO_tail[i] < 0)
425*4882a593Smuzhiyun 				cfo_abs = 0 - cfo_track->CFO_tail[i];
426*4882a593Smuzhiyun 			else
427*4882a593Smuzhiyun 				cfo_abs = cfo_track->CFO_tail[i];
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 			cfo_rpt_sum = (u32)CFO_HW_RPT_2_KHZ(cfo_abs);
430*4882a593Smuzhiyun 			cfo_khz_avg[i] = PHYDM_DIV(cfo_rpt_sum,
431*4882a593Smuzhiyun 						   cfo_track->CFO_cnt[i]);
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 			PHYDM_DBG(dm, DBG_CFO_TRK,
434*4882a593Smuzhiyun 				  "[Path-%d] CFO_sum=((%d)), cnt=((%d)), CFO_avg=((%s%d))kHz\n",
435*4882a593Smuzhiyun 				  i, cfo_rpt_sum, cfo_track->CFO_cnt[i],
436*4882a593Smuzhiyun 				  ((cfo_track->CFO_tail[i] < 0) ? "-" : " "),
437*4882a593Smuzhiyun 				  cfo_khz_avg[i]);
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 			if (cfo_track->CFO_tail[i] < 0)
440*4882a593Smuzhiyun 				cfo_path_sum += (0 - (s32)cfo_khz_avg[i]);
441*4882a593Smuzhiyun 			else
442*4882a593Smuzhiyun 				cfo_path_sum += (s32)cfo_khz_avg[i];
443*4882a593Smuzhiyun 		}
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 		if (valid_path_cnt >= 2)
446*4882a593Smuzhiyun 			cfo_avg = cfo_path_sum / valid_path_cnt;
447*4882a593Smuzhiyun 		else
448*4882a593Smuzhiyun 			cfo_avg = cfo_path_sum;
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 		cfo_track->CFO_ave_pre = cfo_avg;
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_CFO_TRK, "path_cnt=%d, CFO_avg_path=%d kHz\n",
453*4882a593Smuzhiyun 			  valid_path_cnt, cfo_avg);
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 		/*reset counter*/
456*4882a593Smuzhiyun 		for (i = 0; i < dm->num_rf_path; i++) {
457*4882a593Smuzhiyun 			cfo_track->CFO_tail[i] = 0;
458*4882a593Smuzhiyun 			cfo_track->CFO_cnt[i] = 0;
459*4882a593Smuzhiyun 		}
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 		/* To adjust crystal cap or not */
462*4882a593Smuzhiyun 		if (!cfo_track->is_adjust) {
463*4882a593Smuzhiyun 			if (cfo_avg > CFO_TRK_ENABLE_TH ||
464*4882a593Smuzhiyun 			    cfo_avg < (-CFO_TRK_ENABLE_TH))
465*4882a593Smuzhiyun 				cfo_track->is_adjust = true;
466*4882a593Smuzhiyun 		} else {
467*4882a593Smuzhiyun 			if (cfo_avg <= CFO_TRK_STOP_TH &&
468*4882a593Smuzhiyun 			    cfo_avg >= (-CFO_TRK_STOP_TH))
469*4882a593Smuzhiyun 				cfo_track->is_adjust = false;
470*4882a593Smuzhiyun 		}
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 		#ifdef ODM_CONFIG_BT_COEXIST
473*4882a593Smuzhiyun 		/*@BT case: Disable CFO tracking */
474*4882a593Smuzhiyun 		if (dm->bt_info_table.is_bt_enabled) {
475*4882a593Smuzhiyun 			cfo_track->is_adjust = false;
476*4882a593Smuzhiyun 			phydm_set_crystal_cap(dm, cfo_track->def_x_cap);
477*4882a593Smuzhiyun 			PHYDM_DBG(dm, DBG_CFO_TRK, "[BT]Disable CFO_track\n");
478*4882a593Smuzhiyun 		}
479*4882a593Smuzhiyun 		#endif
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 		/*@Adjust Crystal Cap. */
482*4882a593Smuzhiyun 		if (cfo_track->is_adjust) {
483*4882a593Smuzhiyun 			if (cfo_avg > CFO_TRK_STOP_TH)
484*4882a593Smuzhiyun 				crystal_cap += 1;
485*4882a593Smuzhiyun 			else if (cfo_avg < (-CFO_TRK_STOP_TH))
486*4882a593Smuzhiyun 				crystal_cap -= 1;
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 			if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B |
489*4882a593Smuzhiyun 			    ODM_RTL8195B | ODM_RTL8812F | ODM_RTL8710C | ODM_RTL8721D | ODM_RTL8723F)) {
490*4882a593Smuzhiyun 				if (crystal_cap > 0x7F)
491*4882a593Smuzhiyun 					crystal_cap = 0x7F;
492*4882a593Smuzhiyun 			} else {
493*4882a593Smuzhiyun 				if (crystal_cap > 0x3F)
494*4882a593Smuzhiyun 					crystal_cap = 0x3F;
495*4882a593Smuzhiyun 			}
496*4882a593Smuzhiyun 			if (crystal_cap < 0)
497*4882a593Smuzhiyun 				crystal_cap = 0;
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 			phydm_set_crystal_cap(dm, (u8)crystal_cap);
500*4882a593Smuzhiyun 		}
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_CFO_TRK, "X_cap{Curr,Default}={0x%x,0x%x}\n",
503*4882a593Smuzhiyun 			  cfo_track->crystal_cap, cfo_track->def_x_cap);
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 		/* @Dynamic ATC switch */
506*4882a593Smuzhiyun 		#if ODM_IC_11N_SERIES_SUPPORT
507*4882a593Smuzhiyun 		#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
508*4882a593Smuzhiyun 		if (dm->support_ic_type & ODM_IC_11N_SERIES) {
509*4882a593Smuzhiyun 			if (cfo_avg < CFO_TH_ATC && cfo_avg > -CFO_TH_ATC)
510*4882a593Smuzhiyun 				phydm_set_atc_status(dm, false);
511*4882a593Smuzhiyun 			else
512*4882a593Smuzhiyun 				phydm_set_atc_status(dm, true);
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 		}
515*4882a593Smuzhiyun 		#endif
516*4882a593Smuzhiyun 		#endif
517*4882a593Smuzhiyun 		#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
518*4882a593Smuzhiyun 		#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE | ODM_AP))
519*4882a593Smuzhiyun 		if (dm->support_ic_type & ODM_RTL8814B) {
520*4882a593Smuzhiyun 			//Disable advance time for CFO residual
521*4882a593Smuzhiyun 			odm_set_bb_reg(dm, R_0xc2c, BIT29, 0x0);
522*4882a593Smuzhiyun 		}
523*4882a593Smuzhiyun 		#endif
524*4882a593Smuzhiyun 		#endif
525*4882a593Smuzhiyun 	}
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun 
phydm_parsing_cfo(void * dm_void,void * pktinfo_void,s8 * pcfotail,u8 num_ss)528*4882a593Smuzhiyun void phydm_parsing_cfo(void *dm_void, void *pktinfo_void, s8 *pcfotail,
529*4882a593Smuzhiyun 		       u8 num_ss)
530*4882a593Smuzhiyun {
531*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
532*4882a593Smuzhiyun 	struct phydm_perpkt_info_struct *pktinfo = NULL;
533*4882a593Smuzhiyun 	struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
534*4882a593Smuzhiyun 	boolean valid_info = false;
535*4882a593Smuzhiyun 	u8 i = 0;
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	if (!(dm->support_ability & ODM_BB_CFO_TRACKING))
538*4882a593Smuzhiyun 		return;
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	pktinfo = (struct phydm_perpkt_info_struct *)pktinfo_void;
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE | ODM_IOT))
543*4882a593Smuzhiyun 	if (pktinfo->is_packet_match_bssid)
544*4882a593Smuzhiyun 		valid_info = true;
545*4882a593Smuzhiyun #else
546*4882a593Smuzhiyun 	if (dm->number_active_client == 1)
547*4882a593Smuzhiyun 		valid_info = true;
548*4882a593Smuzhiyun #endif
549*4882a593Smuzhiyun 	if (valid_info) {
550*4882a593Smuzhiyun 		if (num_ss > dm->num_rf_path) /*@For fool proof*/
551*4882a593Smuzhiyun 			num_ss = dm->num_rf_path;
552*4882a593Smuzhiyun 		#if 0
553*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_CFO_TRK, "num_ss=%d, num_rf_path=%d\n",
554*4882a593Smuzhiyun 			  num_ss, dm->num_rf_path);
555*4882a593Smuzhiyun 		#endif
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun 		/* @ Update CFO report for path-A & path-B */
558*4882a593Smuzhiyun 		/* Only paht-A and path-B have CFO tail and short CFO */
559*4882a593Smuzhiyun 		for (i = 0; i < dm->num_rf_path; i++) {
560*4882a593Smuzhiyun 			if (!(dm->rx_ant_status & BIT(i)))
561*4882a593Smuzhiyun 				continue;
562*4882a593Smuzhiyun 			cfo_track->CFO_tail[i] += pcfotail[i];
563*4882a593Smuzhiyun 			cfo_track->CFO_cnt[i]++;
564*4882a593Smuzhiyun 			#if 0
565*4882a593Smuzhiyun 			PHYDM_DBG(dm, DBG_CFO_TRK,
566*4882a593Smuzhiyun 				  "[ID %d][path %d][rate 0x%x] CFO_tail = ((%d)), CFO_tail_sum = ((%d)), CFO_cnt = ((%d))\n",
567*4882a593Smuzhiyun 				  pktinfo->station_id, i, pktinfo->data_rate,
568*4882a593Smuzhiyun 				  pcfotail[i], cfo_track->CFO_tail[i],
569*4882a593Smuzhiyun 				  cfo_track->CFO_cnt[i]);
570*4882a593Smuzhiyun 			#endif
571*4882a593Smuzhiyun 		}
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 		/* @ Update packet counter */
574*4882a593Smuzhiyun 		if (cfo_track->packet_count == 0xffffffff)
575*4882a593Smuzhiyun 			cfo_track->packet_count = 0;
576*4882a593Smuzhiyun 		else
577*4882a593Smuzhiyun 			cfo_track->packet_count++;
578*4882a593Smuzhiyun 	}
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
phy_Init_crystal_capacity(void * dm_void,u8 crystal_cap)582*4882a593Smuzhiyun void phy_Init_crystal_capacity(void *dm_void, u8 crystal_cap)
583*4882a593Smuzhiyun {
584*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	if (!phydm_set_crystal_cap_reg(dm, crystal_cap))
587*4882a593Smuzhiyun 		RT_TRACE_F(COMP_INIT, DBG_SERIOUS,
588*4882a593Smuzhiyun 			   ("Crystal is not initialized!\n"));
589*4882a593Smuzhiyun }
590*4882a593Smuzhiyun #endif
591*4882a593Smuzhiyun 
phydm_cfo_tracking_debug(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)592*4882a593Smuzhiyun void phydm_cfo_tracking_debug(void *dm_void, char input[][16], u32 *_used,
593*4882a593Smuzhiyun 			      char *output, u32 *_out_len)
594*4882a593Smuzhiyun {
595*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
596*4882a593Smuzhiyun 	struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
597*4882a593Smuzhiyun 	char help[] = "-h";
598*4882a593Smuzhiyun 	u32 var1[10] = {0};
599*4882a593Smuzhiyun 	u32 used = *_used;
600*4882a593Smuzhiyun 	u32 out_len = *_out_len;
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 	if ((strcmp(input[1], help) == 0)) {
603*4882a593Smuzhiyun 		PDM_SNPF(out_len, used, output + used, out_len - used,
604*4882a593Smuzhiyun 			 "set Xcap: {1}\n");
605*4882a593Smuzhiyun 		PDM_SNPF(out_len, used, output + used, out_len - used,
606*4882a593Smuzhiyun 			 "show Xcap: {100}\n");
607*4882a593Smuzhiyun 	} else {
608*4882a593Smuzhiyun 		PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 		if (var1[0] == 1) {
611*4882a593Smuzhiyun 			PHYDM_SSCANF(input[2], DCMD_HEX, &var1[1]);
612*4882a593Smuzhiyun 			phydm_set_crystal_cap(dm, (u8)var1[1]);
613*4882a593Smuzhiyun 			PDM_SNPF(out_len, used, output + used, out_len - used,
614*4882a593Smuzhiyun 				 "Set X_cap=0x%x\n", cfo_track->crystal_cap);
615*4882a593Smuzhiyun 		} else if (var1[0] == 100) {
616*4882a593Smuzhiyun 			PDM_SNPF(out_len, used, output + used, out_len - used,
617*4882a593Smuzhiyun 				 "X_cap=0x%x\n", cfo_track->crystal_cap);
618*4882a593Smuzhiyun 		}
619*4882a593Smuzhiyun 	}
620*4882a593Smuzhiyun 	*_used = used;
621*4882a593Smuzhiyun 	*_out_len = out_len;
622*4882a593Smuzhiyun }
623*4882a593Smuzhiyun 
624