Path: blob/master/ALFA-W1F1/RTL8814AU/hal/phydm/phydm_cfotracking.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13* The full GNU General Public License is included in this distribution in the14* file called LICENSE.15*16* Contact Information:17* wlanfae <[email protected]>18* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,19* Hsinchu 300, Taiwan.20*21* Larry Finger <[email protected]>22*23*****************************************************************************/24#include "mp_precomp.h"25#include "phydm_precomp.h"2627s32 phydm_get_cfo_hz(void *dm_void, u32 val, u8 bit_num, u8 frac_num)28{29s32 val_s = 0;3031val_s = phydm_cnvrt_2_sign(val, bit_num);3233if (frac_num == 10) /*@ (X*312500)/1024 ~= X*305*/34val_s *= 305;35else if (frac_num == 11) /*@ (X*312500)/2048 ~= X*152*/36val_s *= 152;37else if (frac_num == 12) /*@ (X*312500)/4096 ~= X*76*/38val_s *= 76;3940return val_s;41}4243#if (ODM_IC_11AC_SERIES_SUPPORT)44void phydm_get_cfo_info_ac(void *dm_void, struct phydm_cfo_rpt *cfo)45{46struct dm_struct *dm = (struct dm_struct *)dm_void;47u8 i = 0;48u32 val[4] = {0};49u32 val_1[4] = {0};50u32 val_2[4] = {0};51u32 val_tmp = 0;5253val[0] = odm_read_4byte(dm, R_0xd0c);54val_1[0] = odm_read_4byte(dm, R_0xd10);55val_2[0] = odm_get_bb_reg(dm, R_0xd14, 0x1fff0000);5657#if (defined(PHYDM_COMPILE_ABOVE_2SS))58val[1] = odm_read_4byte(dm, R_0xd4c);59val_1[1] = odm_read_4byte(dm, R_0xd50);60val_2[1] = odm_get_bb_reg(dm, R_0xd54, 0x1fff0000);61#endif6263#if (defined(PHYDM_COMPILE_ABOVE_3SS))64val[2] = odm_read_4byte(dm, R_0xd8c);65val_1[2] = odm_read_4byte(dm, R_0xd90);66val_2[2] = odm_get_bb_reg(dm, R_0xd94, 0x1fff0000);67#endif6869#if (defined(PHYDM_COMPILE_ABOVE_4SS))70val[3] = odm_read_4byte(dm, R_0xdcc);71val_1[3] = odm_read_4byte(dm, R_0xdd0);72val_2[3] = odm_get_bb_reg(dm, R_0xdd4, 0x1fff0000);73#endif7475for (i = 0; i < dm->num_rf_path; i++) {76val_tmp = val[i] & 0xfff; /*@ Short CFO, S(12,11)*/77cfo->cfo_rpt_s[i] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);7879val_tmp = val[i] >> 16; /*@ Long CFO, S(13,12)*/80cfo->cfo_rpt_l[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);8182val_tmp = val_1[i] & 0x7ff; /*@ SCFO, S(11,10)*/83cfo->cfo_rpt_sec[i] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);8485val_tmp = val_1[i] >> 16; /*@ Acq CFO, S(13,12)*/86cfo->cfo_rpt_acq[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);8788val_tmp = val_2[i]; /*@ End CFO, S(13,12)*/89cfo->cfo_rpt_end[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);90}91}92#endif9394#if (ODM_IC_11N_SERIES_SUPPORT)95void phydm_get_cfo_info_n(void *dm_void, struct phydm_cfo_rpt *cfo)96{97struct dm_struct *dm = (struct dm_struct *)dm_void;98u32 val[5] = {0};99u32 val_tmp = 0;100101odm_set_bb_reg(dm, R_0xd00, BIT(26), 1);102103val[0] = odm_read_4byte(dm, R_0xdac); /*@ Short CFO*/104val[1] = odm_read_4byte(dm, R_0xdb0); /*@ Long CFO*/105val[2] = odm_read_4byte(dm, R_0xdb8); /*@ Sec CFO*/106val[3] = odm_read_4byte(dm, R_0xde0); /*@ Acq CFO*/107val[4] = odm_read_4byte(dm, R_0xdbc); /*@ End CFO*/108109/*@[path-A]*/110if (dm->support_ic_type & (ODM_RTL8721D | ODM_RTL8710C)) {111val_tmp = (val[0] & 0x0fff0000) >> 16; /*@ Short CFO, S(12,11)*/112cfo->cfo_rpt_s[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);113val_tmp = (val[1] & 0x0fff0000) >> 16; /*@ Long CFO, S(12,11)*/114cfo->cfo_rpt_l[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);115val_tmp = (val[2] & 0x0fff0000) >> 16; /*@ Sec CFO, S(12,11)*/116cfo->cfo_rpt_sec[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);117val_tmp = (val[3] & 0x0fff0000) >> 16; /*@ Acq CFO, S(12,11)*/118cfo->cfo_rpt_acq[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);119val_tmp = (val[4] & 0x0fff0000) >> 16; /*@ Acq CFO, S(12,11)*/120cfo->cfo_rpt_end[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);121} else {122val_tmp = (val[0] & 0x0fff0000) >> 16; /*@ Short CFO, S(12,11)*/123cfo->cfo_rpt_s[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);124val_tmp = (val[1] & 0x1fff0000) >> 16; /*@ Long CFO, S(13,12)*/125cfo->cfo_rpt_l[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);126val_tmp = (val[2] & 0x7ff0000) >> 16; /*@ Sec CFO, S(11,10)*/127cfo->cfo_rpt_sec[0] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);128val_tmp = (val[3] & 0x1fff0000) >> 16; /*@ Acq CFO, S(13,12)*/129cfo->cfo_rpt_acq[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);130val_tmp = (val[4] & 0x1fff0000) >> 16; /*@ Acq CFO, S(13,12)*/131cfo->cfo_rpt_end[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);132}133134#if (defined(PHYDM_COMPILE_ABOVE_2SS))135/*@[path-B]*/136val_tmp = val[0] & 0xfff; /*@ Short CFO, S(12,11)*/137cfo->cfo_rpt_s[1] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);138val_tmp = val[1] & 0x1fff; /*@ Long CFO, S(13,12)*/139cfo->cfo_rpt_l[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);140val_tmp = val[2] & 0x7ff; /*@ Sec CFO, S(11,10)*/141cfo->cfo_rpt_sec[1] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);142val_tmp = val[3] & 0x1fff; /*@ Acq CFO, S(13,12)*/143cfo->cfo_rpt_acq[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);144val_tmp = val[4] & 0x1fff; /*@ Acq CFO, S(13,12)*/145cfo->cfo_rpt_end[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);146#endif147}148149void phydm_set_atc_status(void *dm_void, boolean atc_status)150{151struct dm_struct *dm = (struct dm_struct *)dm_void;152struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;153u32 reg_tmp = 0;154u32 mask_tmp = 0;155156PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]ATC_en=%d\n", __func__, atc_status);157158if (cfo_track->is_atc_status == atc_status)159return;160161reg_tmp = ODM_REG(BB_ATC, dm);162mask_tmp = ODM_BIT(BB_ATC, dm);163odm_set_bb_reg(dm, reg_tmp, mask_tmp, atc_status);164cfo_track->is_atc_status = atc_status;165}166167boolean168phydm_get_atc_status(void *dm_void)169{170boolean atc_status = false;171struct dm_struct *dm = (struct dm_struct *)dm_void;172u32 reg_tmp = 0;173u32 mask_tmp = 0;174175reg_tmp = ODM_REG(BB_ATC, dm);176mask_tmp = ODM_BIT(BB_ATC, dm);177178atc_status = (boolean)odm_get_bb_reg(dm, reg_tmp, mask_tmp);179180PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]atc_status=%d\n", __func__, atc_status);181return atc_status;182}183#endif184185void phydm_get_cfo_info(void *dm_void, struct phydm_cfo_rpt *cfo)186{187struct dm_struct *dm = (struct dm_struct *)dm_void;188189switch (dm->ic_ip_series) {190#if (ODM_IC_11N_SERIES_SUPPORT)191case PHYDM_IC_N:192phydm_get_cfo_info_n(dm, cfo);193break;194#endif195#if (ODM_IC_11AC_SERIES_SUPPORT)196case PHYDM_IC_AC:197phydm_get_cfo_info_ac(dm, cfo);198break;199#endif200default:201break;202}203}204205boolean206phydm_set_crystal_cap_reg(void *dm_void, u8 crystal_cap)207{208struct dm_struct *dm = (struct dm_struct *)dm_void;209struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;210u32 reg_val = 0;211212if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B |213ODM_RTL8195B | ODM_RTL8812F | ODM_RTL8721D | ODM_RTL8710C)) {214crystal_cap &= 0x7F;215reg_val = crystal_cap | (crystal_cap << 7);216} else {217crystal_cap &= 0x3F;218reg_val = crystal_cap | (crystal_cap << 6);219}220221cfo_track->crystal_cap = crystal_cap;222223if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8188F)) {224#if (RTL8188E_SUPPORT || RTL8188F_SUPPORT)225/* write 0x24[22:17] = 0x24[16:11] = crystal_cap */226odm_set_mac_reg(dm, R_0x24, 0x7ff800, reg_val);227#endif228}229#if (RTL8812A_SUPPORT)230else if (dm->support_ic_type & ODM_RTL8812) {231/* write 0x2C[30:25] = 0x2C[24:19] = crystal_cap */232odm_set_mac_reg(dm, R_0x2c, 0x7FF80000, reg_val);233}234#endif235#if (RTL8703B_SUPPORT || RTL8723B_SUPPORT || RTL8192E_SUPPORT ||\236RTL8821A_SUPPORT || RTL8723D_SUPPORT)237else if ((dm->support_ic_type &238(ODM_RTL8703B | ODM_RTL8723B | ODM_RTL8192E | ODM_RTL8821 |239ODM_RTL8723D))) {240/* @0x2C[23:18] = 0x2C[17:12] = crystal_cap */241odm_set_mac_reg(dm, R_0x2c, 0x00FFF000, reg_val);242}243#endif244#if (RTL8814A_SUPPORT)245else if (dm->support_ic_type & ODM_RTL8814A) {246/* write 0x2C[26:21] = 0x2C[20:15] = crystal_cap */247odm_set_mac_reg(dm, R_0x2c, 0x07FF8000, reg_val);248}249#endif250#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8197F_SUPPORT ||\251RTL8192F_SUPPORT || RTL8197G_SUPPORT)252else if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C |253ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8197G)) {254/* write 0x24[30:25] = 0x28[6:1] = crystal_cap */255odm_set_mac_reg(dm, R_0x24, 0x7e000000, crystal_cap);256odm_set_mac_reg(dm, R_0x28, 0x7e, crystal_cap);257}258#endif259#if (RTL8710B_SUPPORT)260else if (dm->support_ic_type & (ODM_RTL8710B)) {261#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))262/* write 0x60[29:24] = 0x60[23:18] = crystal_cap */263HAL_SetSYSOnReg(dm->adapter, R_0x60, 0x3FFC0000, reg_val);264#endif265}266#endif267#if (RTL8195B_SUPPORT)268else if (dm->support_ic_type & ODM_RTL8195B) {269phydm_set_crystalcap(dm, (u8)(reg_val & 0x7f));270}271#endif272#if (RTL8721D_SUPPORT)273else if (dm->support_ic_type & (ODM_RTL8721D)) {274/* write 0x4800_0228[30:24] crystal_cap */275/*HAL_SetSYSOnReg(dm->adapter, */276/*REG_SYS_XTAL_8721d, 0x7F000000, crystal_cap);*/277u32 temp_val = HAL_READ32(SYSTEM_CTRL_BASE_LP,278REG_SYS_EFUSE_SYSCFG2);279temp_val = ((crystal_cap << 24) & 0x7F000000)280| (temp_val & (~0x7F000000));281HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_SYS_EFUSE_SYSCFG2,282temp_val);283}284#endif285#if (RTL8710C_SUPPORT)286else if (dm->support_ic_type & (ODM_RTL8710C)) {287/* write MAC reg 0x28[13:7][6:0] crystal_cap */288phydm_set_crystalcap(dm, (u8)(reg_val & 0x7f));289}290#endif291292#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8812F_SUPPORT)293else if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B |294ODM_RTL8812F)) {295/* write 0x1040[23:17] = 0x1040[16:10] = crystal_cap */296odm_set_mac_reg(dm, R_0x1040, 0x00FFFC00, reg_val);297} else {298return false;299}300#endif301return true;302}303304void phydm_set_crystal_cap(void *dm_void, u8 crystal_cap)305{306struct dm_struct *dm = (struct dm_struct *)dm_void;307struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;308309if (cfo_track->crystal_cap == crystal_cap)310return;311312if (phydm_set_crystal_cap_reg(dm, crystal_cap))313PHYDM_DBG(dm, DBG_CFO_TRK, "Set crystal_cap = 0x%x\n",314cfo_track->crystal_cap);315else316PHYDM_DBG(dm, DBG_CFO_TRK, "Set fail\n");317}318319void phydm_cfo_tracking_reset(void *dm_void)320{321struct dm_struct *dm = (struct dm_struct *)dm_void;322struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;323324PHYDM_DBG(dm, DBG_CFO_TRK, "%s ======>\n", __func__);325326if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8195B |327ODM_RTL8812F))328cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x7f;329else330cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x3f;331332cfo_track->is_adjust = true;333334if (cfo_track->crystal_cap > cfo_track->def_x_cap) {335phydm_set_crystal_cap(dm, cfo_track->crystal_cap - 1);336PHYDM_DBG(dm, DBG_CFO_TRK, "approch to Init-val (0x%x)\n",337cfo_track->crystal_cap);338339} else if (cfo_track->crystal_cap < cfo_track->def_x_cap) {340phydm_set_crystal_cap(dm, cfo_track->crystal_cap + 1);341PHYDM_DBG(dm, DBG_CFO_TRK, "approch to init-val 0x%x\n",342cfo_track->crystal_cap);343}344345#if ODM_IC_11N_SERIES_SUPPORT346#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))347if (dm->support_ic_type & ODM_IC_11N_SERIES)348phydm_set_atc_status(dm, true);349#endif350#endif351}352353void phydm_cfo_tracking_init(void *dm_void)354{355struct dm_struct *dm = (struct dm_struct *)dm_void;356struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;357358PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]=========>\n", __func__);359if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8195B |360ODM_RTL8812F))361cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x7f;362else363cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x3f;364365cfo_track->def_x_cap = cfo_track->crystal_cap;366cfo_track->is_adjust = true;367PHYDM_DBG(dm, DBG_CFO_TRK, "crystal_cap=0x%x\n", cfo_track->def_x_cap);368369#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT)370/* @Crystal cap. control by WiFi */371if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C))372odm_set_mac_reg(dm, R_0x10, 0x40, 0x1);373#endif374}375376void phydm_cfo_tracking(void *dm_void)377{378struct dm_struct *dm = (struct dm_struct *)dm_void;379struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;380s32 cfo_avg = 0, cfo_path_sum = 0, cfo_abs = 0;381u32 cfo_rpt_sum = 0, cfo_khz_avg[4] = {0};382s8 crystal_cap = cfo_track->crystal_cap;383u8 i = 0, valid_path_cnt = 0;384385if (!(dm->support_ability & ODM_BB_CFO_TRACKING))386return;387388PHYDM_DBG(dm, DBG_CFO_TRK, "%s ======>\n", __func__);389390if (!dm->is_linked || !dm->is_one_entry_only) {391phydm_cfo_tracking_reset(dm);392PHYDM_DBG(dm, DBG_CFO_TRK, "is_linked=%d, one_entry_only=%d\n",393dm->is_linked, dm->is_one_entry_only);394395} else {396/* No new packet */397if (cfo_track->packet_count == cfo_track->packet_count_pre) {398PHYDM_DBG(dm, DBG_CFO_TRK, "Pkt cnt doesn't change\n");399return;400}401cfo_track->packet_count_pre = cfo_track->packet_count;402403/*@Calculate CFO */404for (i = 0; i < dm->num_rf_path; i++) {405if (!(dm->rx_ant_status & BIT(i)))406continue;407408valid_path_cnt++;409410if (cfo_track->CFO_tail[i] < 0)411cfo_abs = 0 - cfo_track->CFO_tail[i];412else413cfo_abs = cfo_track->CFO_tail[i];414415cfo_rpt_sum = (u32)CFO_HW_RPT_2_KHZ(cfo_abs);416cfo_khz_avg[i] = PHYDM_DIV(cfo_rpt_sum,417cfo_track->CFO_cnt[i]);418419PHYDM_DBG(dm, DBG_CFO_TRK,420"[Path-%d] CFO_sum=((%d)), cnt=((%d)), CFO_avg=((%s%d))kHz\n",421i, cfo_rpt_sum, cfo_track->CFO_cnt[i],422((cfo_track->CFO_tail[i] < 0) ? "-" : " "),423cfo_khz_avg[i]);424425if (cfo_track->CFO_tail[i] < 0)426cfo_path_sum += (0 - (s32)cfo_khz_avg[i]);427else428cfo_path_sum += (s32)cfo_khz_avg[i];429}430431if (valid_path_cnt >= 2)432cfo_avg = cfo_path_sum / valid_path_cnt;433else434cfo_avg = cfo_path_sum;435436cfo_track->CFO_ave_pre = cfo_avg;437438PHYDM_DBG(dm, DBG_CFO_TRK, "path_cnt=%d, CFO_avg_path=%d kHz\n",439valid_path_cnt, cfo_avg);440441/*reset counter*/442for (i = 0; i < dm->num_rf_path; i++) {443cfo_track->CFO_tail[i] = 0;444cfo_track->CFO_cnt[i] = 0;445}446447/* To adjust crystal cap or not */448if (!cfo_track->is_adjust) {449if (cfo_avg > CFO_TRK_ENABLE_TH ||450cfo_avg < (-CFO_TRK_ENABLE_TH))451cfo_track->is_adjust = true;452} else {453if (cfo_avg <= CFO_TRK_STOP_TH &&454cfo_avg >= (-CFO_TRK_STOP_TH))455cfo_track->is_adjust = false;456}457458#ifdef ODM_CONFIG_BT_COEXIST459/*@BT case: Disable CFO tracking */460if (dm->bt_info_table.is_bt_enabled) {461cfo_track->is_adjust = false;462phydm_set_crystal_cap(dm, cfo_track->def_x_cap);463PHYDM_DBG(dm, DBG_CFO_TRK, "[BT]Disable CFO_track\n");464}465#endif466467/*@Adjust Crystal Cap. */468if (cfo_track->is_adjust) {469if (cfo_avg > CFO_TRK_STOP_TH)470crystal_cap += 1;471else if (cfo_avg < (-CFO_TRK_STOP_TH))472crystal_cap -= 1;473474if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B |475ODM_RTL8195B | ODM_RTL8812F)) {476if (crystal_cap > 0x7F)477crystal_cap = 0x7F;478} else {479if (crystal_cap > 0x3F)480crystal_cap = 0x3F;481}482if (crystal_cap < 0)483crystal_cap = 0;484485phydm_set_crystal_cap(dm, (u8)crystal_cap);486}487488PHYDM_DBG(dm, DBG_CFO_TRK, "X_cap{Curr,Default}={0x%x,0x%x}\n",489cfo_track->crystal_cap, cfo_track->def_x_cap);490491/* @Dynamic ATC switch */492#if ODM_IC_11N_SERIES_SUPPORT493#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))494if (dm->support_ic_type & ODM_IC_11N_SERIES) {495if (cfo_avg < CFO_TH_ATC && cfo_avg > -CFO_TH_ATC)496phydm_set_atc_status(dm, false);497else498phydm_set_atc_status(dm, true);499500}501#endif502#endif503}504}505506void phydm_parsing_cfo(void *dm_void, void *pktinfo_void, s8 *pcfotail,507u8 num_ss)508{509struct dm_struct *dm = (struct dm_struct *)dm_void;510struct phydm_perpkt_info_struct *pktinfo = NULL;511struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;512boolean valid_info = false;513u8 i = 0;514515if (!(dm->support_ability & ODM_BB_CFO_TRACKING))516return;517518pktinfo = (struct phydm_perpkt_info_struct *)pktinfo_void;519520#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE | ODM_IOT))521if (pktinfo->is_packet_match_bssid)522valid_info = true;523#else524if (dm->number_active_client == 1)525valid_info = true;526#endif527if (valid_info) {528if (num_ss > dm->num_rf_path) /*@For fool proof*/529num_ss = dm->num_rf_path;530#if 0531PHYDM_DBG(dm, DBG_CFO_TRK, "num_ss=%d, num_rf_path=%d\n",532num_ss, dm->num_rf_path);533#endif534535/* @ Update CFO report for path-A & path-B */536/* Only paht-A and path-B have CFO tail and short CFO */537for (i = 0; i < dm->num_rf_path; i++) {538if (!(dm->rx_ant_status & BIT(i)))539continue;540cfo_track->CFO_tail[i] += pcfotail[i];541cfo_track->CFO_cnt[i]++;542#if 0543PHYDM_DBG(dm, DBG_CFO_TRK,544"[ID %d][path %d][rate 0x%x] CFO_tail = ((%d)), CFO_tail_sum = ((%d)), CFO_cnt = ((%d))\n",545pktinfo->station_id, i, pktinfo->data_rate,546pcfotail[i], cfo_track->CFO_tail[i],547cfo_track->CFO_cnt[i]);548#endif549}550551/* @ Update packet counter */552if (cfo_track->packet_count == 0xffffffff)553cfo_track->packet_count = 0;554else555cfo_track->packet_count++;556}557}558559#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)560void phy_Init_crystal_capacity(void *dm_void, u8 crystal_cap)561{562struct dm_struct *dm = (struct dm_struct *)dm_void;563564if (!phydm_set_crystal_cap_reg(dm, crystal_cap))565RT_TRACE_F(COMP_INIT, DBG_SERIOUS,566("Crystal is not initialized!\n"));567}568#endif569570void phydm_cfo_tracking_debug(void *dm_void, char input[][16], u32 *_used,571char *output, u32 *_out_len)572{573struct dm_struct *dm = (struct dm_struct *)dm_void;574struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;575char help[] = "-h";576u32 var1[10] = {0};577u32 used = *_used;578u32 out_len = *_out_len;579580if ((strcmp(input[1], help) == 0)) {581PDM_SNPF(out_len, used, output + used, out_len - used,582"set Xcap: {1}\n");583PDM_SNPF(out_len, used, output + used, out_len - used,584"show Xcap: {100}\n");585} else {586PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);587588if (var1[0] == 1) {589PHYDM_SSCANF(input[2], DCMD_HEX, &var1[1]);590phydm_set_crystal_cap(dm, (u8)var1[1]);591PDM_SNPF(out_len, used, output + used, out_len - used,592"Set X_cap=0x%x\n", cfo_track->crystal_cap);593} else if (var1[0] == 100) {594PDM_SNPF(out_len, used, output + used, out_len - used,595"X_cap=0x%x\n", cfo_track->crystal_cap);596}597}598*_used = used;599*_out_len = out_len;600}601602603604