Path: blob/master/ALFA-W1F1/RTL8814AU/hal/phydm/halrf/halphyrf_win.c
1308 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*****************************************************************************/1415#include "mp_precomp.h"16#include "phydm_precomp.h"1718#define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _delta_thermal) \19do {\20for (_offset = 0; _offset < _size; _offset++) { \21\22if (_delta_thermal < thermal_threshold[_direction][_offset]) { \23\24if (_offset != 0)\25_offset--;\26break;\27} \28} \29if (_offset >= _size)\30_offset = _size-1;\31} while (0)3233void configure_txpower_track(34struct dm_struct *dm,35struct txpwrtrack_cfg *config36)37{38#if RTL8192E_SUPPORT39if (dm->support_ic_type == ODM_RTL8192E)40configure_txpower_track_8192e(config);41#endif42#if RTL8821A_SUPPORT43if (dm->support_ic_type == ODM_RTL8821)44configure_txpower_track_8821a(config);45#endif46#if RTL8812A_SUPPORT47if (dm->support_ic_type == ODM_RTL8812)48configure_txpower_track_8812a(config);49#endif50#if RTL8188E_SUPPORT51if (dm->support_ic_type == ODM_RTL8188E)52configure_txpower_track_8188e(config);53#endif5455#if RTL8188F_SUPPORT56if (dm->support_ic_type == ODM_RTL8188F)57configure_txpower_track_8188f(config);58#endif5960#if RTL8723B_SUPPORT61if (dm->support_ic_type == ODM_RTL8723B)62configure_txpower_track_8723b(config);63#endif6465#if RTL8814A_SUPPORT66if (dm->support_ic_type == ODM_RTL8814A)67configure_txpower_track_8814a(config);68#endif6970#if RTL8703B_SUPPORT71if (dm->support_ic_type == ODM_RTL8703B)72configure_txpower_track_8703b(config);73#endif7475#if RTL8822B_SUPPORT76if (dm->support_ic_type == ODM_RTL8822B)77configure_txpower_track_8822b(config);78#endif7980#if RTL8723D_SUPPORT81if (dm->support_ic_type == ODM_RTL8723D)82configure_txpower_track_8723d(config);83#endif8485/* JJ ADD 20161014 */86#if RTL8710B_SUPPORT87if (dm->support_ic_type == ODM_RTL8710B)88configure_txpower_track_8710b(config);89#endif9091#if RTL8821C_SUPPORT92if (dm->support_ic_type == ODM_RTL8821C)93configure_txpower_track_8821c(config);94#endif9596#if RTL8192F_SUPPORT97if (dm->support_ic_type == ODM_RTL8192F)98configure_txpower_track_8192f(config);99#endif100101#if RTL8822C_SUPPORT102if (dm->support_ic_type == ODM_RTL8822C)103configure_txpower_track_8822c(config);104#endif105106#if RTL8814B_SUPPORT107if (dm->support_ic_type == ODM_RTL8814B)108configure_txpower_track_8814b(config);109#endif110111112}113114/* **********************************************************************115* <20121113, Kordan> This function should be called when tx_agc changed.116* Otherwise the previous compensation is gone, because we record the117* delta of temperature between two TxPowerTracking watch dogs.118*119* NOTE: If Tx BB swing or Tx scaling is varified during run-time, still120* need to call this function.121* ********************************************************************** */122void123odm_clear_txpowertracking_state(124struct dm_struct *dm125)126{127PHAL_DATA_TYPE hal_data = GET_HAL_DATA((PADAPTER)(dm->adapter));128u8 p = 0;129struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);130131cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;132cali_info->bb_swing_idx_cck = cali_info->default_cck_index;133cali_info->CCK_index = 0;134135for (p = RF_PATH_A; p < MAX_RF_PATH; ++p) {136cali_info->bb_swing_idx_ofdm_base[p] = cali_info->default_ofdm_index;137cali_info->bb_swing_idx_ofdm[p] = cali_info->default_ofdm_index;138cali_info->OFDM_index[p] = cali_info->default_ofdm_index;139140cali_info->power_index_offset[p] = 0;141cali_info->delta_power_index[p] = 0;142cali_info->delta_power_index_last[p] = 0;143144cali_info->absolute_ofdm_swing_idx[p] = 0; /* Initial Mix mode power tracking*/145cali_info->remnant_ofdm_swing_idx[p] = 0;146cali_info->kfree_offset[p] = 0;147}148149cali_info->modify_tx_agc_flag_path_a = false; /*Initial at Modify Tx Scaling mode*/150cali_info->modify_tx_agc_flag_path_b = false; /*Initial at Modify Tx Scaling mode*/151cali_info->modify_tx_agc_flag_path_c = false; /*Initial at Modify Tx Scaling mode*/152cali_info->modify_tx_agc_flag_path_d = false; /*Initial at Modify Tx Scaling mode*/153cali_info->remnant_cck_swing_idx = 0;154cali_info->thermal_value = hal_data->eeprom_thermal_meter;155156cali_info->modify_tx_agc_value_cck = 0; /* modify by Mingzhi.Guo */157cali_info->modify_tx_agc_value_ofdm = 0; /* modify by Mingzhi.Guo */158159}160161void162odm_txpowertracking_callback_thermal_meter(163#if (DM_ODM_SUPPORT_TYPE & ODM_AP)164struct dm_struct *dm165#else166void *adapter167#endif168)169{170#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)171HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));172#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)173struct dm_struct *dm = &hal_data->DM_OutSrc;174#elif (DM_ODM_SUPPORT_TYPE == ODM_CE)175struct dm_struct *dm = &hal_data->odmpriv;176#endif177#endif178179struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);180struct dm_iqk_info *iqk_info = &dm->IQK_info;181struct _hal_rf_ *rf = &(dm->rf_table);182u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;183s8 diff_DPK[4] = {0};184u8 thermal_value_avg_count = 0;185u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4, regc88, rege14, reg848,reg838, reg86c;186187u8 OFDM_min_index = 0; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */188u8 indexforchannel = 0; /* get_right_chnl_place_for_iqk(hal_data->current_channel) */189u8 power_tracking_type = hal_data->RfPowerTrackingType;190u8 xtal_offset_eanble = 0;191s8 thermal_value_temp = 0;192193struct txpwrtrack_cfg c;194195/* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */196u8 *delta_swing_table_idx_tup_a = NULL;197u8 *delta_swing_table_idx_tdown_a = NULL;198u8 *delta_swing_table_idx_tup_b = NULL;199u8 *delta_swing_table_idx_tdown_b = NULL;200/*for 8814 add by Yu Chen*/201u8 *delta_swing_table_idx_tup_c = NULL;202u8 *delta_swing_table_idx_tdown_c = NULL;203u8 *delta_swing_table_idx_tup_d = NULL;204u8 *delta_swing_table_idx_tdown_d = NULL;205/*for Xtal Offset by James.Tung*/206s8 *delta_swing_table_xtal_up = NULL;207s8 *delta_swing_table_xtal_down = NULL;208209/* 4 2. Initilization ( 7 steps in total ) */210211configure_txpower_track(dm, &c);212213(*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,214(u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);215216if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8814B)) /*for 8814 path C & D*/217(*c.get_delta_swing_table8814only)(dm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,218(u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);219/* JJ ADD 20161014 */220if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B | ODM_RTL8192F)) /*for Xtal Offset*/221(*c.get_delta_swing_xtal_table)(dm, (s8 **)&delta_swing_table_xtal_up, (s8 **)&delta_swing_table_xtal_down);222223224cali_info->txpowertracking_callback_cnt++; /*cosa add for debug*/225cali_info->is_txpowertracking_init = true;226227/*cali_info->txpowertrack_control = hal_data->txpowertrack_control;228<Kordan> We should keep updating the control variable according to HalData.229<Kordan> rf_calibrate_info.rega24 will be initialized when ODM HW configuring, but MP configures with para files. */230#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)231#if (MP_DRIVER == 1)232cali_info->rega24 = 0x090e1317;233#endif234#elif (DM_ODM_SUPPORT_TYPE & ODM_CE)235if (*(dm->mp_mode) == true)236cali_info->rega24 = 0x090e1317;237#endif238239RF_DBG(dm, DBG_RF_TX_PWR_TRACK,240"===>odm_txpowertracking_callback_thermal_meter\n cali_info->bb_swing_idx_cck_base: %d, cali_info->bb_swing_idx_ofdm_base[A]: %d, cali_info->default_ofdm_index: %d\n",241cali_info->bb_swing_idx_cck_base, cali_info->bb_swing_idx_ofdm_base[RF_PATH_A], cali_info->default_ofdm_index);242243RF_DBG(dm, DBG_RF_TX_PWR_TRACK,244"cali_info->txpowertrack_control=%d, hal_data->eeprom_thermal_meter %d\n", cali_info->txpowertrack_control, hal_data->eeprom_thermal_meter);245thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */246247thermal_value_temp = thermal_value + phydm_get_thermal_offset(dm);248249RF_DBG(dm, DBG_RF_TX_PWR_TRACK,250"thermal_value_temp(%d) = thermal_value(%d) + power_time_thermal(%d)\n", thermal_value_temp, thermal_value, phydm_get_thermal_offset(dm));251252if (thermal_value_temp > 63)253thermal_value = 63;254else if (thermal_value_temp < 0)255thermal_value = 0;256else257thermal_value = thermal_value_temp;258259/*add log by zhao he, check c80/c94/c14/ca0 value*/260if (dm->support_ic_type == ODM_RTL8723D) {261regc80 = odm_get_bb_reg(dm, R_0xc80, MASKDWORD);262regcd0 = odm_get_bb_reg(dm, R_0xcd0, MASKDWORD);263regcd4 = odm_get_bb_reg(dm, R_0xcd4, MASKDWORD);264regab4 = odm_get_bb_reg(dm, R_0xab4, 0x000007FF);265RF_DBG(dm, DBG_RF_IQK, "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4);266}267268/* JJ ADD 20161014 */269if (dm->support_ic_type == ODM_RTL8710B) {270regc80 = odm_get_bb_reg(dm, R_0xc80, MASKDWORD);271regcd0 = odm_get_bb_reg(dm, R_0xcd0, MASKDWORD);272regcd4 = odm_get_bb_reg(dm, R_0xcd4, MASKDWORD);273regab4 = odm_get_bb_reg(dm, R_0xab4, 0x000007FF);274RF_DBG(dm, DBG_RF_IQK, "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4);275}276/* Winnita add 20171205 */277if (dm->support_ic_type == ODM_RTL8192F) {278regc80 = odm_get_bb_reg(dm, R_0xc80, MASKDWORD);279regc88 = odm_get_bb_reg(dm, R_0xc88, MASKDWORD);280regab4 = odm_get_bb_reg(dm, R_0xab4, MASKDWORD);281rege14 = odm_get_bb_reg(dm, R_0xe14, MASKDWORD);282reg848 = odm_get_bb_reg(dm, R_0x848, MASKDWORD);283reg838 = odm_get_bb_reg(dm, R_0x838, MASKDWORD);284reg86c = odm_get_bb_reg(dm, R_0x86c, MASKDWORD);285RF_DBG(dm, DBG_RF_IQK, "0xc80 = 0x%x 0xc88 = 0x%x 0xab4 = 0x%x 0xe14 = 0x%x\n", regc80, regc88, regab4, rege14);286RF_DBG(dm, DBG_RF_IQK, "0x848 = 0x%x 0x838 = 0x%x 0x86c = 0x%x\n", reg848, reg838, reg86c);287}288289if (!cali_info->txpowertrack_control)290return;291292if (hal_data->eeprom_thermal_meter == 0xff) {293RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "no pg, hal_data->eeprom_thermal_meter = 0x%x\n", hal_data->eeprom_thermal_meter);294return;295}296297/*4 3. Initialize ThermalValues of rf_calibrate_info*/298299if (cali_info->is_reloadtxpowerindex)300RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "reload ofdm index for band switch\n");301302/*4 4. Calculate average thermal meter*/303304cali_info->thermal_value_avg[cali_info->thermal_value_avg_index] = thermal_value;305cali_info->thermal_value_avg_index++;306if (cali_info->thermal_value_avg_index == c.average_thermal_num) /*Average times = c.average_thermal_num*/307cali_info->thermal_value_avg_index = 0;308309for (i = 0; i < c.average_thermal_num; i++) {310if (cali_info->thermal_value_avg[i]) {311thermal_value_avg += cali_info->thermal_value_avg[i];312thermal_value_avg_count++;313}314}315316if (thermal_value_avg_count) { /* Calculate Average thermal_value after average enough times */317thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);318cali_info->thermal_value_delta = thermal_value - hal_data->eeprom_thermal_meter;319RF_DBG(dm, DBG_RF_TX_PWR_TRACK,320"AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n", thermal_value, hal_data->eeprom_thermal_meter);321}322323/* 4 5. Calculate delta, delta_LCK, delta_IQK. */324325/* "delta" here is used to determine whether thermal value changes or not. */326delta = (thermal_value > cali_info->thermal_value) ? (thermal_value - cali_info->thermal_value) : (cali_info->thermal_value - thermal_value);327delta_LCK = (thermal_value > cali_info->thermal_value_lck) ? (thermal_value - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value);328delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ? (thermal_value - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value);329330if (cali_info->thermal_value_iqk == 0xff) { /*no PG, use thermal value for IQK*/331cali_info->thermal_value_iqk = thermal_value;332delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ? (thermal_value - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value);333RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "no PG, use thermal_value for IQK\n");334}335336for (p = RF_PATH_A; p < c.rf_path_count; p++)337diff_DPK[p] = (s8)thermal_value - (s8)cali_info->dpk_thermal[p];338339/*4 6. If necessary, do LCK.*/340341if (!(dm->support_ic_type & ODM_RTL8821)) { /*no PG, do LCK at initial status*/342if (cali_info->thermal_value_lck == 0xff) {343RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "no PG, do LCK\n");344cali_info->thermal_value_lck = thermal_value;345346/*Use RTLCK, so close power tracking driver LCK*/347if ((!(dm->support_ic_type & ODM_RTL8814A)) && (!(dm->support_ic_type & ODM_RTL8822B))) {348if (c.phy_lc_calibrate)349(*c.phy_lc_calibrate)(dm);350}351352delta_LCK = (thermal_value > cali_info->thermal_value_lck) ? (thermal_value - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value);353}354355RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK);356357/* Wait sacn to do LCK by RF Jenyu*/358if( (*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {359/* Delta temperature is equal to or larger than 20 centigrade.*/360if (delta_LCK >= c.threshold_iqk) {361RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);362cali_info->thermal_value_lck = thermal_value;363364/*Use RTLCK, so close power tracking driver LCK*/365if ((!(dm->support_ic_type & ODM_RTL8814A)) && (!(dm->support_ic_type & ODM_RTL8822B))) {366if (c.phy_lc_calibrate)367(*c.phy_lc_calibrate)(dm);368}369}370}371}372373/*3 7. If necessary, move the index of swing table to adjust Tx power.*/374375if (delta > 0 && cali_info->txpowertrack_control) {376/* "delta" here is used to record the absolute value of differrence. */377#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))378delta = thermal_value > hal_data->eeprom_thermal_meter ? (thermal_value - hal_data->eeprom_thermal_meter) : (hal_data->eeprom_thermal_meter - thermal_value);379#else380delta = (thermal_value > dm->priv->pmib->dot11RFEntry.ther) ? (thermal_value - dm->priv->pmib->dot11RFEntry.ther) : (dm->priv->pmib->dot11RFEntry.ther - thermal_value);381#endif382if (delta >= TXPWR_TRACK_TABLE_SIZE)383delta = TXPWR_TRACK_TABLE_SIZE - 1;384385/*4 7.1 The Final Power index = BaseIndex + power_index_offset*/386387#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))388if (thermal_value > hal_data->eeprom_thermal_meter) {389#else390if (thermal_value > dm->priv->pmib->dot11RFEntry.ther) {391#endif392393for (p = RF_PATH_A; p < c.rf_path_count; p++) {394cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/395switch (p) {396case RF_PATH_B:397RF_DBG(dm, DBG_RF_TX_PWR_TRACK,398"delta_swing_table_idx_tup_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta]);399400cali_info->delta_power_index[p] = delta_swing_table_idx_tup_b[delta];401cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_b[delta]; /*Record delta swing for mix mode power tracking*/402RF_DBG(dm, DBG_RF_TX_PWR_TRACK,403"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);404break;405406case RF_PATH_C:407RF_DBG(dm, DBG_RF_TX_PWR_TRACK,408"delta_swing_table_idx_tup_c[%d] = %d\n", delta, delta_swing_table_idx_tup_c[delta]);409410cali_info->delta_power_index[p] = delta_swing_table_idx_tup_c[delta];411cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_c[delta]; /*Record delta swing for mix mode power tracking*/412RF_DBG(dm, DBG_RF_TX_PWR_TRACK,413"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);414break;415416case RF_PATH_D:417RF_DBG(dm, DBG_RF_TX_PWR_TRACK,418"delta_swing_table_idx_tup_d[%d] = %d\n", delta, delta_swing_table_idx_tup_d[delta]);419420cali_info->delta_power_index[p] = delta_swing_table_idx_tup_d[delta];421cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_d[delta]; /*Record delta swing for mix mode power tracking*/422RF_DBG(dm, DBG_RF_TX_PWR_TRACK,423"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);424break;425426default:427RF_DBG(dm, DBG_RF_TX_PWR_TRACK,428"delta_swing_table_idx_tup_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta]);429430cali_info->delta_power_index[p] = delta_swing_table_idx_tup_a[delta];431cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_a[delta]; /*Record delta swing for mix mode power tracking*/432RF_DBG(dm, DBG_RF_TX_PWR_TRACK,433"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);434break;435}436}437/* JJ ADD 20161014 */438if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B | ODM_RTL8192F)) {439/*Save xtal_offset from Xtal table*/440cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/441RF_DBG(dm, DBG_RF_TX_PWR_TRACK,442"[Xtal] delta_swing_table_xtal_up[%d] = %d\n", delta, delta_swing_table_xtal_up[delta]);443cali_info->xtal_offset = delta_swing_table_xtal_up[delta];444445if (cali_info->xtal_offset_last == cali_info->xtal_offset)446xtal_offset_eanble = 0;447else448xtal_offset_eanble = 1;449}450451} else {452for (p = RF_PATH_A; p < c.rf_path_count; p++) {453cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/454455switch (p) {456case RF_PATH_B:457RF_DBG(dm, DBG_RF_TX_PWR_TRACK,458"delta_swing_table_idx_tdown_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta]);459cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_b[delta];460cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b[delta]; /*Record delta swing for mix mode power tracking*/461RF_DBG(dm, DBG_RF_TX_PWR_TRACK,462"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);463break;464465case RF_PATH_C:466RF_DBG(dm, DBG_RF_TX_PWR_TRACK,467"delta_swing_table_idx_tdown_c[%d] = %d\n", delta, delta_swing_table_idx_tdown_c[delta]);468cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_c[delta];469cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_c[delta]; /*Record delta swing for mix mode power tracking*/470RF_DBG(dm, DBG_RF_TX_PWR_TRACK,471"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);472break;473474case RF_PATH_D:475RF_DBG(dm, DBG_RF_TX_PWR_TRACK,476"delta_swing_table_idx_tdown_d[%d] = %d\n", delta, delta_swing_table_idx_tdown_d[delta]);477cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_d[delta];478cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_d[delta]; /*Record delta swing for mix mode power tracking*/479RF_DBG(dm, DBG_RF_TX_PWR_TRACK,480"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);481break;482483default:484RF_DBG(dm, DBG_RF_TX_PWR_TRACK,485"delta_swing_table_idx_tdown_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta]);486cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_a[delta];487cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a[delta]; /*Record delta swing for mix mode power tracking*/488RF_DBG(dm, DBG_RF_TX_PWR_TRACK,489"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);490break;491}492}493/* JJ ADD 20161014 */494if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B | ODM_RTL8192F)) {495/*Save xtal_offset from Xtal table*/496cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/497RF_DBG(dm, DBG_RF_TX_PWR_TRACK,498"[Xtal] delta_swing_table_xtal_down[%d] = %d\n", delta, delta_swing_table_xtal_down[delta]);499cali_info->xtal_offset = delta_swing_table_xtal_down[delta];500501if (cali_info->xtal_offset_last == cali_info->xtal_offset)502xtal_offset_eanble = 0;503else504xtal_offset_eanble = 1;505}506507}508509for (p = RF_PATH_A; p < c.rf_path_count; p++) {510RF_DBG(dm, DBG_RF_TX_PWR_TRACK,511"\n\n=========================== [path-%d] Calculating power_index_offset===========================\n", p);512513if (cali_info->delta_power_index[p] == cali_info->delta_power_index_last[p]) /*If Thermal value changes but lookup table value still the same*/514cali_info->power_index_offset[p] = 0;515else516cali_info->power_index_offset[p] = cali_info->delta_power_index[p] - cali_info->delta_power_index_last[p]; /*Power index diff between 2 times Power Tracking*/517518RF_DBG(dm, DBG_RF_TX_PWR_TRACK,519"[path-%d] power_index_offset(%d) = delta_power_index(%d) - delta_power_index_last(%d)\n", p, cali_info->power_index_offset[p], cali_info->delta_power_index[p], cali_info->delta_power_index_last[p]);520521cali_info->OFDM_index[p] = cali_info->bb_swing_idx_ofdm_base[p] + cali_info->power_index_offset[p];522cali_info->CCK_index = cali_info->bb_swing_idx_cck_base + cali_info->power_index_offset[p];523524cali_info->bb_swing_idx_cck = cali_info->CCK_index;525cali_info->bb_swing_idx_ofdm[p] = cali_info->OFDM_index[p];526527/*************Print BB Swing base and index Offset*************/528529RF_DBG(dm, DBG_RF_TX_PWR_TRACK,530"The 'CCK' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n", cali_info->bb_swing_idx_cck, cali_info->bb_swing_idx_cck_base, cali_info->power_index_offset[p]);531RF_DBG(dm, DBG_RF_TX_PWR_TRACK,532"The 'OFDM' final index(%d) = BaseIndex[%d](%d) + power_index_offset(%d)\n", cali_info->bb_swing_idx_ofdm[p], p, cali_info->bb_swing_idx_ofdm_base[p], cali_info->power_index_offset[p]);533534/*4 7.1 Handle boundary conditions of index.*/535536if (cali_info->OFDM_index[p] > c.swing_table_size_ofdm - 1)537cali_info->OFDM_index[p] = c.swing_table_size_ofdm - 1;538else if (cali_info->OFDM_index[p] <= OFDM_min_index)539cali_info->OFDM_index[p] = OFDM_min_index;540}541542RF_DBG(dm, DBG_RF_TX_PWR_TRACK,543"\n\n========================================================================================================\n");544545if (cali_info->CCK_index > c.swing_table_size_cck - 1)546cali_info->CCK_index = c.swing_table_size_cck - 1;547else if (cali_info->CCK_index <= 0)548cali_info->CCK_index = 0;549} else {550RF_DBG(dm, DBG_RF_TX_PWR_TRACK,551"The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, cali_info->thermal_value: %d\n",552cali_info->txpowertrack_control, thermal_value, cali_info->thermal_value);553554for (p = RF_PATH_A; p < c.rf_path_count; p++)555cali_info->power_index_offset[p] = 0;556}557558RF_DBG(dm, DBG_RF_TX_PWR_TRACK,559"TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",560cali_info->CCK_index, cali_info->bb_swing_idx_cck_base); /*Print Swing base & current*/561562for (p = RF_PATH_A; p < c.rf_path_count; p++) {563RF_DBG(dm, DBG_RF_TX_PWR_TRACK,564"TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",565cali_info->OFDM_index[p], p, cali_info->bb_swing_idx_ofdm_base[p]);566}567568if (dm->support_ic_type & ODM_RTL8814B)569power_tracking_type = TSSI_MODE;570571if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8814B)) {572RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "power_tracking_type=%d\n", power_tracking_type);573574if (power_tracking_type == 0) {575RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");576for (p = RF_PATH_A; p < c.rf_path_count; p++)577(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);578} else if (power_tracking_type == 1) {579RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX(2G) TSSI(5G) MODE**********\n");580for (p = RF_PATH_A; p < c.rf_path_count; p++)581(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_2G_TSSI_5G_MODE, p, 0);582} else if (power_tracking_type == 2) {583RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX(5G) TSSI(2G)MODE**********\n");584for (p = RF_PATH_A; p < c.rf_path_count; p++)585(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_5G_TSSI_2G_MODE, p, 0);586} else if (power_tracking_type == 3) {587RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI MODE**********\n");588for (p = RF_PATH_A; p < c.rf_path_count; p++)589(*c.odm_tx_pwr_track_set_pwr)(dm, TSSI_MODE, p, 0);590}591cali_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/592593} else if ((cali_info->power_index_offset[RF_PATH_A] != 0 ||594cali_info->power_index_offset[RF_PATH_B] != 0 ||595cali_info->power_index_offset[RF_PATH_C] != 0 ||596cali_info->power_index_offset[RF_PATH_D] != 0) &&597cali_info->txpowertrack_control && (hal_data->eeprom_thermal_meter != 0xff)) {598/* 4 7.2 Configure the Swing Table to adjust Tx Power. */599600cali_info->is_tx_power_changed = true; /*Always true after Tx Power is adjusted by power tracking.*/601/* */602/* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */603/* to increase TX power. Otherwise, EVM will be bad. */604/* */605/* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */606if (thermal_value > cali_info->thermal_value) {607for (p = RF_PATH_A; p < c.rf_path_count; p++) {608RF_DBG(dm, DBG_RF_TX_PWR_TRACK,609"Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",610p, cali_info->power_index_offset[p], delta, thermal_value, hal_data->eeprom_thermal_meter, cali_info->thermal_value);611}612} else if (thermal_value < cali_info->thermal_value) { /*Low temperature*/613for (p = RF_PATH_A; p < c.rf_path_count; p++) {614RF_DBG(dm, DBG_RF_TX_PWR_TRACK,615"Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",616p, cali_info->power_index_offset[p], delta, thermal_value, hal_data->eeprom_thermal_meter, cali_info->thermal_value);617}618}619620#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)621if (thermal_value > hal_data->eeprom_thermal_meter)622#else623if (thermal_value > dm->priv->pmib->dot11RFEntry.ther)624#endif625{626RF_DBG(dm, DBG_RF_TX_PWR_TRACK,627"Temperature(%d) higher than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);628629if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8821 ||630dm->support_ic_type == ODM_RTL8812 || dm->support_ic_type == ODM_RTL8723B || dm->support_ic_type == ODM_RTL8814A ||631dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8822B ||632dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8821C || dm->support_ic_type == ODM_RTL8710B ||633dm->support_ic_type == ODM_RTL8192F) {634635RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");636for (p = RF_PATH_A; p < c.rf_path_count; p++)637(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);638} else {639RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");640for (p = RF_PATH_A; p < c.rf_path_count; p++)641(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);642}643} else {644RF_DBG(dm, DBG_RF_TX_PWR_TRACK,645"Temperature(%d) lower than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);646647if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8821 ||648dm->support_ic_type == ODM_RTL8812 || dm->support_ic_type == ODM_RTL8723B || dm->support_ic_type == ODM_RTL8814A ||649dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8822B ||650dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8821C || dm->support_ic_type == ODM_RTL8710B ||651dm->support_ic_type == ODM_RTL8192F) {652RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");653for (p = RF_PATH_A; p < c.rf_path_count; p++)654(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, indexforchannel);655} else {656RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");657for (p = RF_PATH_A; p < c.rf_path_count; p++)658(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);659}660661}662663cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck; /*Record last time Power Tracking result as base.*/664for (p = RF_PATH_A; p < c.rf_path_count; p++)665cali_info->bb_swing_idx_ofdm_base[p] = cali_info->bb_swing_idx_ofdm[p];666667RF_DBG(dm, DBG_RF_TX_PWR_TRACK,668"cali_info->thermal_value = %d thermal_value= %d\n", cali_info->thermal_value, thermal_value);669670cali_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/671672}673674675if (dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8723D ||676dm->support_ic_type == ODM_RTL8192F || dm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */677678if (xtal_offset_eanble != 0 && cali_info->txpowertrack_control && (hal_data->eeprom_thermal_meter != 0xff)) {679680RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter Xtal Tracking**********\n");681682#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)683if (thermal_value > hal_data->eeprom_thermal_meter) {684#else685if (thermal_value > dm->priv->pmib->dot11RFEntry.ther) {686#endif687RF_DBG(dm, DBG_RF_TX_PWR_TRACK,688"Temperature(%d) higher than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);689(*c.odm_txxtaltrack_set_xtal)(dm);690} else {691RF_DBG(dm, DBG_RF_TX_PWR_TRACK,692"Temperature(%d) lower than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);693(*c.odm_txxtaltrack_set_xtal)(dm);694}695}696RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********End Xtal Tracking**********\n");697}698699#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)700701/* Wait sacn to do IQK by RF Jenyu*/702if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {703if (!IS_HARDWARE_TYPE_8723B(adapter)) {704/*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/705if (delta_IQK >= c.threshold_iqk) {706cali_info->thermal_value_iqk = thermal_value;707RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);708if (!cali_info->is_iqk_in_progress)709(*c.do_iqk)(dm, delta_IQK, thermal_value, 8);710}711}712}713if (cali_info->dpk_thermal[RF_PATH_A] != 0) {714if (diff_DPK[RF_PATH_A] >= c.threshold_dpk) {715odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);716odm_set_bb_reg(dm, R_0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[RF_PATH_A] / c.threshold_dpk));717odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);718} else if ((diff_DPK[RF_PATH_A] <= -1 * c.threshold_dpk)) {719s32 value = 0x20 + (diff_DPK[RF_PATH_A] / c.threshold_dpk);720721odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);722odm_set_bb_reg(dm, R_0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);723odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);724} else {725odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);726odm_set_bb_reg(dm, R_0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);727odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);728}729}730if (cali_info->dpk_thermal[RF_PATH_B] != 0) {731if (diff_DPK[RF_PATH_B] >= c.threshold_dpk) {732odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);733odm_set_bb_reg(dm, R_0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[RF_PATH_B] / c.threshold_dpk));734odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);735} else if ((diff_DPK[RF_PATH_B] <= -1 * c.threshold_dpk)) {736s32 value = 0x20 + (diff_DPK[RF_PATH_B] / c.threshold_dpk);737738odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);739odm_set_bb_reg(dm, R_0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);740odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);741} else {742odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);743odm_set_bb_reg(dm, R_0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);744odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);745}746}747748#endif749750RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "<===odm_txpowertracking_callback_thermal_meter\n");751752cali_info->tx_powercount = 0;753}754755#if (RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1)756void757odm_txpowertracking_new_callback_thermal_meter(void *dm_void)758{759struct dm_struct *dm = (struct dm_struct *)dm_void;760struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);761struct dm_iqk_info *iqk_info = &dm->IQK_info;762struct _hal_rf_ *rf = &dm->rf_table;763struct _halrf_tssi_data *tssi = &rf->halrf_tssi_data;764u8 thermal_value[MAX_RF_PATH] = {0}, delta[MAX_RF_PATH] = {0};765u8 delta_swing_table_idx_tup[DELTA_SWINGIDX_SIZE] = {0};766u8 delta_swing_table_idx_tdown[DELTA_SWINGIDX_SIZE] = {0};767u8 delta_LCK = 0, delta_IQK = 0, i = 0, j = 0, p;768u8 thermal_value_avg_count[MAX_RF_PATH] = {0};769u32 thermal_value_avg[MAX_RF_PATH] = {0};770s8 thermal_value_temp[MAX_RF_PATH] = {0};771u8 tracking_method = MIX_MODE;772773struct txpwrtrack_cfg c;774775u8 *delta_swing_table_idx_tup_a = NULL;776u8 *delta_swing_table_idx_tdown_a = NULL;777u8 *delta_swing_table_idx_tup_b = NULL;778u8 *delta_swing_table_idx_tdown_b = NULL;779u8 *delta_swing_table_idx_tup_c = NULL;780u8 *delta_swing_table_idx_tdown_c = NULL;781u8 *delta_swing_table_idx_tup_d = NULL;782u8 *delta_swing_table_idx_tdown_d = NULL;783784configure_txpower_track(dm, &c);785786(*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,787(u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);788789if (dm->support_ic_type == ODM_RTL8814B) {790(*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,791(u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);792}793794cali_info->txpowertracking_callback_cnt++;795cali_info->is_txpowertracking_init = true;796797RF_DBG(dm, DBG_RF_TX_PWR_TRACK,798"===>odm_txpowertracking_callback_thermal_meter\n cali_info->bb_swing_idx_cck_base: %d, cali_info->bb_swing_idx_ofdm_base[A]: %d, cali_info->default_ofdm_index: %d\n",799cali_info->bb_swing_idx_cck_base, cali_info->bb_swing_idx_ofdm_base[RF_PATH_A], cali_info->default_ofdm_index);800801RF_DBG(dm, DBG_RF_TX_PWR_TRACK,802"cali_info->txpowertrack_control=%d, tssi->thermal[RF_PATH_A]=%d tssi->thermal[RF_PATH_B]=%d\n",803cali_info->txpowertrack_control, tssi->thermal[RF_PATH_A], tssi->thermal[RF_PATH_B]);804805if (dm->support_ic_type == ODM_RTL8822C) {806for (i = 0; i < c.rf_path_count; i++)807thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0x7e); /* 0x42: RF Reg[6:1] Thermal Trim*/808} else {809for (i = 0; i < c.rf_path_count; i++) {810thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10]*/811thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_thermal_offset(dm);812813RF_DBG(dm, DBG_RF_TX_PWR_TRACK,814"thermal_value_temp[%d](%d) = thermal_value[%d](%d) + power_time_thermal(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_thermal_offset(dm));815816if (thermal_value_temp[i] > 63)817thermal_value[i] = 63;818else if (thermal_value_temp[i] < 0)819thermal_value[i] = 0;820else821thermal_value[i] = thermal_value_temp[i];822}823}824825if ((tssi->thermal[RF_PATH_A] == 0xff || tssi->thermal[RF_PATH_B] == 0xff)) {826for (i = 0; i < c.rf_path_count; i++)827RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "no pg, tssi->thermal[%d] = 0x%x\n",828i, tssi->thermal[i]);829return;830}831832for (j = 0; j < c.rf_path_count; j++) {833cali_info->thermal_value_avg_path[j][cali_info->thermal_value_avg_index_path[j]] = thermal_value[j];834cali_info->thermal_value_avg_index_path[j]++;835if (cali_info->thermal_value_avg_index_path[j] == c.average_thermal_num) /*Average times = c.average_thermal_num*/836cali_info->thermal_value_avg_index_path[j] = 0;837838839for (i = 0; i < c.average_thermal_num; i++) {840if (cali_info->thermal_value_avg_path[j][i]) {841thermal_value_avg[j] += cali_info->thermal_value_avg_path[j][i];842thermal_value_avg_count[j]++;843}844}845846if (thermal_value_avg_count[j]) { /* Calculate Average thermal_value after average enough times */847thermal_value[j] = (u8)(thermal_value_avg[j] / thermal_value_avg_count[j]);848RF_DBG(dm, DBG_RF_TX_PWR_TRACK,849"AVG Thermal Meter = 0x%X, tssi->thermal[%d] = 0x%x\n",850thermal_value[j], j, tssi->thermal[j]);851}852/* 4 5. Calculate delta, delta_LCK, delta_IQK. */853854/* "delta" here is used to determine whether thermal value changes or not. */855delta[j] = (thermal_value[j] > cali_info->thermal_value_path[j]) ? (thermal_value[j] - cali_info->thermal_value_path[j]) : (cali_info->thermal_value_path[j] - thermal_value[j]);856delta_LCK = (thermal_value[0] > cali_info->thermal_value_lck) ? (thermal_value[0] - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value[0]);857delta_IQK = (thermal_value[0] > cali_info->thermal_value_iqk) ? (thermal_value[0] - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value[0]);858}859860/*4 6. If necessary, do LCK.*/861862for (i = 0; i < c.rf_path_count; i++)863RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "(delta[%d], delta_LCK, delta_IQK) = (%d, %d, %d)\n", i, delta[i], delta_LCK, delta_IQK);864865/* Wait sacn to do LCK by RF Jenyu*/866if( (*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {867/* Delta temperature is equal to or larger than 20 centigrade.*/868if (delta_LCK >= c.threshold_iqk) {869RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);870cali_info->thermal_value_lck = thermal_value[RF_PATH_A];871872/*Use RTLCK, so close power tracking driver LCK*/873if ((!(dm->support_ic_type & ODM_RTL8814A)) && (!(dm->support_ic_type & ODM_RTL8822B))) {874if (c.phy_lc_calibrate)875(*c.phy_lc_calibrate)(dm);876} else877RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do not do LCK\n");878}879}880881/*3 7. If necessary, move the index of swing table to adjust Tx power.*/882for (i = 0; i < c.rf_path_count; i++) {883if (i == RF_PATH_B) {884odm_move_memory(dm, delta_swing_table_idx_tup, delta_swing_table_idx_tup_b, DELTA_SWINGIDX_SIZE);885odm_move_memory(dm, delta_swing_table_idx_tdown, delta_swing_table_idx_tdown_b, DELTA_SWINGIDX_SIZE);886} else if (i == RF_PATH_C) {887odm_move_memory(dm, delta_swing_table_idx_tup, delta_swing_table_idx_tup_c, DELTA_SWINGIDX_SIZE);888odm_move_memory(dm, delta_swing_table_idx_tdown, delta_swing_table_idx_tdown_c, DELTA_SWINGIDX_SIZE);889} else if (i == RF_PATH_D) {890odm_move_memory(dm, delta_swing_table_idx_tup, delta_swing_table_idx_tup_d, DELTA_SWINGIDX_SIZE);891odm_move_memory(dm, delta_swing_table_idx_tdown, delta_swing_table_idx_tdown_d, DELTA_SWINGIDX_SIZE);892} else {893odm_move_memory(dm, delta_swing_table_idx_tup, delta_swing_table_idx_tup_a, DELTA_SWINGIDX_SIZE);894odm_move_memory(dm, delta_swing_table_idx_tdown, delta_swing_table_idx_tdown_a, DELTA_SWINGIDX_SIZE);895}896897cali_info->delta_power_index_last[i] = cali_info->delta_power_index[i]; /*recording poer index offset*/898delta[i] = thermal_value[i] > tssi->thermal[i] ? (thermal_value[i] - tssi->thermal[i]) : (tssi->thermal[i] - thermal_value[i]);899900if (delta[i] >= TXPWR_TRACK_TABLE_SIZE)901delta[i] = TXPWR_TRACK_TABLE_SIZE - 1;902903if (thermal_value[i] > tssi->thermal[i]) {904RF_DBG(dm, DBG_RF_TX_PWR_TRACK,905"delta_swing_table_idx_tup[%d]=%d Path=%d\n", delta[i], delta_swing_table_idx_tup[delta[i]], i);906907cali_info->delta_power_index[i] = delta_swing_table_idx_tup[delta[i]];908cali_info->absolute_ofdm_swing_idx[i] = delta_swing_table_idx_tup[delta[i]]; /*Record delta swing for mix mode power tracking*/909RF_DBG(dm, DBG_RF_TX_PWR_TRACK,910"******Temp is higher and cali_info->absolute_ofdm_swing_idx[%d]=%d Path=%d\n", delta[i], cali_info->absolute_ofdm_swing_idx[i], i);911} else {912RF_DBG(dm, DBG_RF_TX_PWR_TRACK,913"delta_swing_table_idx_tdown[%d]=%d Path=%d\n", delta[i], delta_swing_table_idx_tdown[delta[i]], i);914cali_info->delta_power_index[i] = -1 * delta_swing_table_idx_tdown[delta[i]];915cali_info->absolute_ofdm_swing_idx[i] = -1 * delta_swing_table_idx_tdown[delta[i]]; /*Record delta swing for mix mode power tracking*/916RF_DBG(dm, DBG_RF_TX_PWR_TRACK,917"******Temp is lower and cali_info->absolute_ofdm_swing_idx[%d]=%d Path=%d\n", delta[i], cali_info->absolute_ofdm_swing_idx[i], i);918}919}920921for (p = RF_PATH_A; p < c.rf_path_count; p++) {922if (cali_info->delta_power_index[p] == cali_info->delta_power_index_last[p]) /*If Thermal value changes but lookup table value still the same*/923cali_info->power_index_offset[p] = 0;924else925cali_info->power_index_offset[p] = cali_info->delta_power_index[p] - cali_info->delta_power_index_last[p]; /*Power index diff between 2 times Power Tracking*/926}927928#if 0929if (dm->support_ic_type == ODM_RTL8822C) {930RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");931for (p = RF_PATH_A; p < c.rf_path_count; p++)932(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);933} else {934RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");935for (p = RF_PATH_A; p < c.rf_path_count; p++)936(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, 0);937}938#endif939if (*dm->mp_mode == 1) {940if (cali_info->txpowertrack_control == 1) {941RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");942tracking_method = MIX_MODE;943} else if (cali_info->txpowertrack_control == 3) {944RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI_MODE**********\n");945tracking_method = TSSI_MODE;946}947} else {948if (rf->power_track_type >= 0 && rf->power_track_type <= 3) {949RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");950tracking_method = MIX_MODE;951} else if (rf->power_track_type >= 4 && rf->power_track_type <= 7) {952RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI_MODE**********\n");953tracking_method = TSSI_MODE;954}955}956957if (dm->support_ic_type == ODM_RTL8822C || dm->support_ic_type == ODM_RTL8814B)958for (p = RF_PATH_A; p < c.rf_path_count; p++)959(*c.odm_tx_pwr_track_set_pwr)(dm, tracking_method, p, 0);960961/* Wait sacn to do IQK by RF Jenyu*/962if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {963/*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/964if (delta_IQK >= c.threshold_iqk) {965cali_info->thermal_value_iqk = thermal_value[RF_PATH_A];966RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);967/*if (!cali_info->is_iqk_in_progress)*/968/* (*c.do_iqk)(dm, delta_IQK, thermal_value[RF_PATH_A], 8);*/969RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do IQK\n");970971/*if (!cali_info->is_iqk_in_progress)*/972/* (*c.do_tssi_dck)(dm, true);*/973RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do TSSI DCK\n");974}975}976977RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "<===%s\n", __func__);978979cali_info->tx_powercount = 0;980}981#endif982983/* 3============================================================984* 3 IQ Calibration985* 3============================================================ */986987void988odm_reset_iqk_result(989struct dm_struct *dm990)991{992return;993}994#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)995u8 odm_get_right_chnl_place_for_iqk(u8 chnl)996{997u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {9981, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159, 161, 163, 165999};1000u8 place = chnl;100110021003if (chnl > 14) {1004for (place = 14; place < sizeof(channel_all); place++) {1005if (channel_all[place] == chnl)1006return place - 13;1007}1008}1009return 0;10101011}1012#endif10131014void1015odm_iq_calibrate(1016struct dm_struct *dm1017)1018{1019void *adapter = dm->adapter;1020struct dm_iqk_info *iqk_info = &dm->IQK_info;10211022RF_DBG(dm, DBG_RF_IQK, "=>%s\n",__FUNCTION__);10231024#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)1025if (*dm->is_fcs_mode_enable)1026return;1027#endif10281029if ((dm->is_linked) && (!iqk_info->rfk_forbidden)) {1030RF_DBG(dm, DBG_RF_IQK, "interval=%d ch=%d prech=%d scan=%s\n", dm->linked_interval,1031*dm->channel, dm->pre_channel, *dm->is_scan_in_process == TRUE ? "TRUE":"FALSE");10321033if (*dm->channel != dm->pre_channel) {1034dm->pre_channel = *dm->channel;1035dm->linked_interval = 0;1036}10371038if ((dm->linked_interval < 3) && (!*dm->is_scan_in_process))1039dm->linked_interval++;10401041if (dm->linked_interval == 2)1042PHY_IQCalibrate(adapter, false);1043} else1044dm->linked_interval = 0;10451046RF_DBG(dm, DBG_RF_IQK, "<=%s interval=%d ch=%d prech=%d scan=%s\n", __FUNCTION__, dm->linked_interval,1047*dm->channel, dm->pre_channel, *dm->is_scan_in_process == TRUE?"TRUE":"FALSE");1048}10491050void phydm_rf_init(struct dm_struct *dm)1051{10521053odm_txpowertracking_init(dm);10541055#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))1056odm_clear_txpowertracking_state(dm);1057#endif10581059#if (DM_ODM_SUPPORT_TYPE & (ODM_AP))1060#if (RTL8814A_SUPPORT == 1)1061if (dm->support_ic_type & ODM_RTL8814A)1062phy_iq_calibrate_8814a_init(dm);1063#endif1064#endif10651066}10671068void phydm_rf_watchdog(struct dm_struct *dm)1069{1070#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)1071FunctionIn(COMP_MLME);10721073if (*dm->mp_mode == 1) {1074#if (MP_DRIVER == 1)1075odm_txpowertracking_check(dm);1076#endif1077} else {1078odm_txpowertracking_check(dm);10791080if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES))1081odm_iq_calibrate(dm);1082}1083#endif1084}108510861087