Path: blob/master/ALFA-W1F1/RTL8814AU/hal/phydm/halrf/rtl8814a/halrf_8814a_ap.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#if !defined(__ECOS) && !defined(CONFIG_COMPAT_WIRELESS)16#include "mp_precomp.h"17#else18#include "../mp_precomp.h"19#endif20#include "../../phydm_precomp.h"21222324/*---------------------------Define Local Constant---------------------------*/25/* 2010/04/25 MH Define the max tx power tracking tx agc power. */26#define ODM_TXPWRTRACK_MAX_IDX8814A 62728/*---------------------------Define Local Constant---------------------------*/293031/* 3============================================================32* 3 Tx Power Tracking33* 3============================================================ */3435u836check_rf_gain_offset(37struct dm_struct *dm,38enum pwrtrack_method method,39u8 rf_path40)41{42s8 upper_bound = 10, lower_bound = -5; /* 4'b1010 = 10 */43s8 final_rf_index = 0;44boolean is_positive = false;45u32 bit_mask = 0;46u8 final_ofdm_swing_index = 0, tx_scaling_upper_bound = 28, tx_scaling_lower_bound = 4;/* upper bound +2dB, lower bound -9dB */47struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);4849if (method == MIX_MODE) { /* normal Tx power tracking */50RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "is 8814 MP chip\n");51bit_mask = BIT(19);52cali_info->absolute_ofdm_swing_idx[rf_path] = cali_info->absolute_ofdm_swing_idx[rf_path] + cali_info->kfree_offset[rf_path];5354if (cali_info->absolute_ofdm_swing_idx[rf_path] >= 0) /* check if RF_Index is positive or not */55is_positive = true;56else57is_positive = false;5859odm_set_rf_reg(dm, rf_path, REG_RF_TX_GAIN_OFFSET, bit_mask, is_positive);6061bit_mask = BIT(18) | BIT(17) | BIT(16) | BIT(15);62final_rf_index = cali_info->absolute_ofdm_swing_idx[rf_path] / 2; /*TxBB 1 step equal 1dB, BB swing 1step equal 0.5dB*/6364}6566if (final_rf_index > upper_bound) { /* Upper bound = 10dB, if more htan upper bound, then move to bb swing max = +2dB */67odm_set_rf_reg(dm, rf_path, REG_RF_TX_GAIN_OFFSET, bit_mask, upper_bound); /* set RF Reg0x55 per path */6869final_ofdm_swing_index = cali_info->default_ofdm_index + (cali_info->absolute_ofdm_swing_idx[rf_path] - (upper_bound << 1));7071if (final_ofdm_swing_index > tx_scaling_upper_bound) /* bb swing upper bound = +2dB */72final_ofdm_swing_index = tx_scaling_upper_bound;7374return final_ofdm_swing_index;75} else if (final_rf_index < lower_bound) { /* lower bound = -5dB */76odm_set_rf_reg(dm, rf_path, REG_RF_TX_GAIN_OFFSET, bit_mask, (-1) * (lower_bound)); /* set RF Reg0x55 per path */7778final_ofdm_swing_index = cali_info->default_ofdm_index - ((lower_bound << 1) - cali_info->absolute_ofdm_swing_idx[rf_path]);7980if (final_ofdm_swing_index < tx_scaling_lower_bound) /* bb swing lower bound = -10dB */81final_ofdm_swing_index = tx_scaling_lower_bound;82return final_ofdm_swing_index;83} else { /* normal case */8485if (is_positive == true)86odm_set_rf_reg(dm, rf_path, REG_RF_TX_GAIN_OFFSET, bit_mask, final_rf_index); /* set RF Reg0x55 per path */87else88odm_set_rf_reg(dm, rf_path, REG_RF_TX_GAIN_OFFSET, bit_mask, (-1) * final_rf_index); /* set RF Reg0x55 per path */8990final_ofdm_swing_index = cali_info->default_ofdm_index + (cali_info->absolute_ofdm_swing_idx[rf_path]) % 2;91return final_ofdm_swing_index;92}9394return false;95}969798void99odm_tx_pwr_track_set_pwr8814a(100struct dm_struct *dm,101enum pwrtrack_method method,102u8 rf_path,103u8 channel_mapped_index104)105{106u8 final_ofdm_swing_index = 0;107struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);108109if (method == MIX_MODE) {110RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "dm->default_ofdm_index=%d, dm->absolute_ofdm_swing_idx[rf_path]=%d, rf_path = %d\n",111cali_info->default_ofdm_index, cali_info->absolute_ofdm_swing_idx[rf_path], rf_path);112113final_ofdm_swing_index = check_rf_gain_offset(dm, MIX_MODE, rf_path);114} else if (method == TSSI_MODE)115odm_set_rf_reg(dm, rf_path, REG_RF_TX_GAIN_OFFSET, BIT(18) | BIT(17) | BIT(16) | BIT(15), 0);116else if (method == BBSWING) { /* use for mp driver clean power tracking status */117cali_info->absolute_ofdm_swing_idx[rf_path] = cali_info->absolute_ofdm_swing_idx[rf_path] + cali_info->kfree_offset[rf_path];118119final_ofdm_swing_index = cali_info->default_ofdm_index + (cali_info->absolute_ofdm_swing_idx[rf_path]);120121odm_set_rf_reg(dm, rf_path, REG_RF_TX_GAIN_OFFSET, BIT(18) | BIT(17) | BIT(16) | BIT(15), 0);122}123124if ((method == MIX_MODE) || (method == BBSWING)) {125switch (rf_path) {126case RF_PATH_A:127128odm_set_bb_reg(dm, REG_A_TX_SCALE_JAGUAR, 0xFFE00000, tx_scaling_table_jaguar[final_ofdm_swing_index]); /* set BBswing */129130RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Path_A Compensate with BBSwing, final_ofdm_swing_index = %d\n", final_ofdm_swing_index);131break;132133case RF_PATH_B:134135odm_set_bb_reg(dm, REG_B_TX_SCALE_JAGUAR, 0xFFE00000, tx_scaling_table_jaguar[final_ofdm_swing_index]); /* set BBswing */136137RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Path_B Compensate with BBSwing, final_ofdm_swing_index = %d\n", final_ofdm_swing_index);138break;139140case RF_PATH_C:141142odm_set_bb_reg(dm, REG_C_TX_SCALE_JAGUAR2, 0xFFE00000, tx_scaling_table_jaguar[final_ofdm_swing_index]); /* set BBswing */143144RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Path_C Compensate with BBSwing, final_ofdm_swing_index = %d\n", final_ofdm_swing_index);145break;146147case RF_PATH_D:148149odm_set_bb_reg(dm, REG_D_TX_SCALE_JAGUAR2, 0xFFE00000, tx_scaling_table_jaguar[final_ofdm_swing_index]); /* set BBswing */150151RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Path_D Compensate with BBSwing, final_ofdm_swing_index = %d\n", final_ofdm_swing_index);152break;153154default:155RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"Wrong path name!!!!\n");156157break;158}159}160return;161} /* odm_tx_pwr_track_set_pwr8814a */162163void164get_delta_swing_table_8814a(165struct dm_struct *dm,166u8 **temperature_up_a,167u8 **temperature_down_a,168u8 **temperature_up_b,169u8 **temperature_down_b170)171{172struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);173u16 rate = *(dm->forced_data_rate);174u8 channel = *(dm->channel);175176if (1 <= channel && channel <= 14) {177if (IS_CCK_RATE(rate)) {178*temperature_up_a = cali_info->delta_swing_table_idx_2g_cck_a_p;179*temperature_down_a = cali_info->delta_swing_table_idx_2g_cck_a_n;180*temperature_up_b = cali_info->delta_swing_table_idx_2g_cck_b_p;181*temperature_down_b = cali_info->delta_swing_table_idx_2g_cck_b_n;182} else {183*temperature_up_a = cali_info->delta_swing_table_idx_2ga_p;184*temperature_down_a = cali_info->delta_swing_table_idx_2ga_n;185*temperature_up_b = cali_info->delta_swing_table_idx_2gb_p;186*temperature_down_b = cali_info->delta_swing_table_idx_2gb_n;187}188} else if (36 <= channel && channel <= 64) {189*temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[0];190*temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[0];191*temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[0];192*temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[0];193} else if (100 <= channel && channel <= 144) {194*temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[1];195*temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[1];196*temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[1];197*temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[1];198} else if (149 <= channel && channel <= 177) {199*temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[2];200*temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[2];201*temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[2];202*temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[2];203} else {204*temperature_up_a = (u8 *)delta_swing_table_idx_2ga_p_default;205*temperature_down_a = (u8 *)delta_swing_table_idx_2ga_n_default;206*temperature_up_b = (u8 *)delta_swing_table_idx_2ga_p_default;207*temperature_down_b = (u8 *)delta_swing_table_idx_2ga_n_default;208}209210return;211}212213214void215get_delta_swing_table_8814a_path_cd(216struct dm_struct *dm,217u8 **temperature_up_c,218u8 **temperature_down_c,219u8 **temperature_up_d,220u8 **temperature_down_d221)222{223struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);224u16 rate = *(dm->forced_data_rate);225u8 channel = *(dm->channel);226227if (1 <= channel && channel <= 14) {228if (IS_CCK_RATE(rate)) {229*temperature_up_c = cali_info->delta_swing_table_idx_2g_cck_c_p;230*temperature_down_c = cali_info->delta_swing_table_idx_2g_cck_c_n;231*temperature_up_d = cali_info->delta_swing_table_idx_2g_cck_d_p;232*temperature_down_d = cali_info->delta_swing_table_idx_2g_cck_d_n;233} else {234*temperature_up_c = cali_info->delta_swing_table_idx_2gc_p;235*temperature_down_c = cali_info->delta_swing_table_idx_2gc_n;236*temperature_up_d = cali_info->delta_swing_table_idx_2gd_p;237*temperature_down_d = cali_info->delta_swing_table_idx_2gd_n;238}239} else if (36 <= channel && channel <= 64) {240*temperature_up_c = cali_info->delta_swing_table_idx_5gc_p[0];241*temperature_down_c = cali_info->delta_swing_table_idx_5gc_n[0];242*temperature_up_d = cali_info->delta_swing_table_idx_5gd_p[0];243*temperature_down_d = cali_info->delta_swing_table_idx_5gd_n[0];244} else if (100 <= channel && channel <= 144) {245*temperature_up_c = cali_info->delta_swing_table_idx_5gc_p[1];246*temperature_down_c = cali_info->delta_swing_table_idx_5gc_n[1];247*temperature_up_d = cali_info->delta_swing_table_idx_5gd_p[1];248*temperature_down_d = cali_info->delta_swing_table_idx_5gd_n[1];249} else if (149 <= channel && channel <= 177) {250*temperature_up_c = cali_info->delta_swing_table_idx_5gc_p[2];251*temperature_down_c = cali_info->delta_swing_table_idx_5gc_n[2];252*temperature_up_d = cali_info->delta_swing_table_idx_5gd_p[2];253*temperature_down_d = cali_info->delta_swing_table_idx_5gd_n[2];254} else {255*temperature_up_c = (u8 *)delta_swing_table_idx_2ga_p_default;256*temperature_down_c = (u8 *)delta_swing_table_idx_2ga_n_default;257*temperature_up_d = (u8 *)delta_swing_table_idx_2ga_p_default;258*temperature_down_d = (u8 *)delta_swing_table_idx_2ga_n_default;259}260261return;262}263264265void configure_txpower_track_8814a(266struct txpwrtrack_cfg *config267)268{269config->swing_table_size_cck = ODM_CCK_TABLE_SIZE;270config->swing_table_size_ofdm = ODM_OFDM_TABLE_SIZE;271config->threshold_iqk = 8;272config->average_thermal_num = AVG_THERMAL_NUM_8814A;273config->rf_path_count = MAX_PATH_NUM_8814A;274config->thermal_reg_addr = RF_T_METER_8814A;275276config->odm_tx_pwr_track_set_pwr = odm_tx_pwr_track_set_pwr8814a;277config->phy_lc_calibrate = halrf_lck_trigger;278config->do_iqk = do_iqk_8814a;279config->get_delta_swing_table = get_delta_swing_table_8814a;280config->get_delta_swing_table8814only = get_delta_swing_table_8814a_path_cd;281}282283284285/* 1 7. IQK */286void287_phy_save_adda_registers_8814a(288struct dm_struct *dm,289u32 *adda_reg,290u32 *adda_backup,291u32 register_num292)293{294u32 i;295RF_DBG(dm, DBG_RF_IQK, "Save ADDA parameters.\n");296for (i = 0 ; i < register_num ; i++)297adda_backup[i] = odm_get_bb_reg(dm, adda_reg[i], MASKDWORD);298}299300301void302_phy_save_mac_registers_8814a(303struct dm_struct *dm,304u32 *mac_reg,305u32 *mac_backup306)307{308u32 i;309RF_DBG(dm, DBG_RF_IQK, "Save MAC parameters.\n");310for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++)311mac_backup[i] = odm_read_1byte(dm, mac_reg[i]);312mac_backup[i] = odm_read_4byte(dm, mac_reg[i]);313314}315316317void318_phy_reload_adda_registers_8814a(319struct dm_struct *dm,320u32 *adda_reg,321u32 *adda_backup,322u32 regiester_num323)324{325u32 i;326RF_DBG(dm, DBG_RF_IQK, "Reload ADDA power saving parameters !\n");327for (i = 0 ; i < regiester_num; i++)328odm_set_bb_reg(dm, adda_reg[i], MASKDWORD, adda_backup[i]);329}330331void332_phy_reload_mac_registers_8814a(333struct dm_struct *dm,334u32 *mac_reg,335u32 *mac_backup336)337{338u32 i;339RF_DBG(dm, DBG_RF_IQK, "Reload MAC parameters !\n");340for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++)341odm_write_1byte(dm, mac_reg[i], (u8)mac_backup[i]);342odm_write_4byte(dm, mac_reg[i], mac_backup[i]);343}344345346347void348_phy_mac_setting_calibration_8814a(349struct dm_struct *dm,350u32 *mac_reg,351u32 *mac_backup352)353{354u32 i = 0;355RF_DBG(dm, DBG_RF_IQK, "MAC settings for Calibration.\n");356357odm_write_1byte(dm, mac_reg[i], 0x3F);358359for (i = 1 ; i < (IQK_MAC_REG_NUM - 1); i++)360odm_write_1byte(dm, mac_reg[i], (u8)(mac_backup[i] & (~BIT(3))));361odm_write_1byte(dm, mac_reg[i], (u8)(mac_backup[i] & (~BIT(5))));362363}364365366void367_phy_lc_calibrate_8814a(368struct dm_struct *dm,369boolean is2T370)371{372u32 /*rf_amode=0, rf_bmode=0,*/ lc_cal = 0, tmp = 0;373u32 cnt;374375/* Check continuous TX and Packet TX */376u32 reg0x914 = odm_read_4byte(dm, REG_SINGLE_TONE_CONT_TX_JAGUAR);;377378/* Backup RF reg18. */379380if ((reg0x914 & 0x70000) == 0)381odm_write_1byte(dm, REG_TXPAUSE_8812, 0xFF);382383/* 3 3. Read RF reg18 */384lc_cal = odm_get_rf_reg(dm, RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK);385386/* 3 4. Set LC calibration begin bit15 */387odm_set_rf_reg(dm, RF_PATH_A, RF_CHNLBW, 0x8000, 0x1);388389ODM_delay_ms(100);390391for (cnt = 0; cnt < 100; cnt++) {392if (odm_get_rf_reg(dm, RF_PATH_A, RF_CHNLBW, 0x8000) != 0x1)393break;394ODM_delay_ms(10);395}396RF_DBG(dm, DBG_RF_IQK, "retry cnt = %d\n", cnt);397398399/* 3 Restore original situation */400if ((reg0x914 & 70000) == 0)401odm_write_1byte(dm, REG_TXPAUSE_8812, 0x00);402403/* Recover channel number */404odm_set_rf_reg(dm, RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, lc_cal);405}406407408void409phy_lc_calibrate_8814a(410void *dm_void411)412{413struct dm_struct *dm = (struct dm_struct *)dm_void;414415_phy_lc_calibrate_8814a(dm, true);416}417418419void _phy_set_rf_path_switch_8814a(420struct dm_struct *dm,421boolean is_main,422boolean is2T423)424{425if (is2T) { /* 92C */426if (is_main)427odm_set_bb_reg(dm, REG_FPGA0_XB_RF_INTERFACE_OE, BIT(5) | BIT(6), 0x1); /* 92C_Path_A */428else429odm_set_bb_reg(dm, REG_FPGA0_XB_RF_INTERFACE_OE, BIT(5) | BIT(6), 0x2); /* BT */430} else { /* 88C */431432if (is_main)433odm_set_bb_reg(dm, REG_FPGA0_XA_RF_INTERFACE_OE, BIT(8) | BIT(9), 0x2); /* Main */434else435odm_set_bb_reg(dm, REG_FPGA0_XA_RF_INTERFACE_OE, BIT(8) | BIT(9), 0x1); /* Aux */436}437}438void phy_set_rf_path_switch_8814a(439struct dm_struct *dm,440boolean is_main441)442{443/* HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); */444445#ifdef DISABLE_BB_RF446return;447#endif448449{450/* For 88C 1T1R */451_phy_set_rf_path_switch_8814a(dm, is_main, false);452}453}454455456