summaryrefslogtreecommitdiffstats
path: root/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/Hal8192CDMOutSrc.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/realtek/files/drivers/net/wireless/rtl8192cd/Hal8192CDMOutSrc.c')
-rw-r--r--target/linux/realtek/files/drivers/net/wireless/rtl8192cd/Hal8192CDMOutSrc.c5089
1 files changed, 5000 insertions, 89 deletions
diff --git a/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/Hal8192CDMOutSrc.c b/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/Hal8192CDMOutSrc.c
index 3c0322f8c..9bdbba951 100644
--- a/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/Hal8192CDMOutSrc.c
+++ b/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/Hal8192CDMOutSrc.c
@@ -21,7 +21,11 @@
#include <linux/fs.h>
#include <linux/file.h>
#include <asm/unistd.h>
-#include <linux/synclink.h>
+#elif defined(__ECOS)
+#include <cyg/io/eth/rltk/819x/wrapper/sys_support.h>
+#include <cyg/io/eth/rltk/819x/wrapper/skbuff.h>
+#include <cyg/io/eth/rltk/819x/wrapper/timer.h>
+#include <cyg/io/eth/rltk/819x/wrapper/wrapper.h>
#endif
#include "./8192cd_cfg.h"
@@ -38,12 +42,29 @@
#endif
#endif
+#if defined(CONFIG_RTL_819X) && defined(USE_RLX_BSP)
+#include <bsp/bspchip.h>
+#endif
+
+#ifndef CONFIG_RTL_8198B
+#ifndef BSP_WDTCNR
+ #define BSP_WDTCNR 0xB800311C
+#endif
+#endif
+
+
+//Analog Pre-distortion calibration
+#define APK_BB_REG_NUM 5
+#define APK_AFE_REG_NUM 16
+#define APK_CURVE_REG_NUM 4
+#define PATH_NUM 2
+
//============================================================
// Global var
//============================================================
-static unsigned int OFDMSwingTable[] = {
+unsigned int OFDMSwingTable[] = {
0x7f8001fe, // 0, +6.0dB
0x788001e2, // 1, +5.5dB
0x71c001c7, // 2, +5.0dB
@@ -310,7 +331,7 @@ static unsigned int OFDMSwingTable_92D[] = {
//3 ============================================================
//3 DIG related functions
//3 ============================================================
-
+#if 0
int getIGIFor1RCCA(int value_IGI)
{
#define ONERCCA_LOW_TH 0x30
@@ -453,8 +474,56 @@ void set_DIG_state(struct rtl8192cd_priv *priv, int state)
#endif
}
}
+#endif
+
+void MP_DIG_process(struct rtl8192cd_priv *priv)
+{
+ u1Byte DIG_Upper = 0x40, DIG_Lower = 0x20, C50, C58;
+ u4Byte RXOK_cal, RxPWDBAve;
+ unsigned int FA_cnt_ofdm = priv->pshare->ofdm_FA_cnt1 + priv->pshare->ofdm_FA_cnt2 +
+ priv->pshare->ofdm_FA_cnt3 + priv->pshare->ofdm_FA_cnt4;
+ unsigned int FA_cnt_cck = priv->pshare->cck_FA_cnt;
+
+ if (!(priv->pshare->rf_ft_var.mp_specific && priv->pshare->mp_dig_on))
+ return;
+
+ //printk("===> %s, pBandType = %d\n", __FUNCTION__, priv->pmib->dot11RFEntry.phyBandSelect);
+ if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G) {
+ FA_statistic(priv);
+
+ priv->pshare->LastNumQryPhyStatusAll = priv->pshare->NumQryPhyStatus;
+ priv->pshare->NumQryPhyStatus = priv->pshare->NumQryPhyStatusCCK + priv->pshare->NumQryPhyStatusOFDM;
+ RXOK_cal = priv->pshare->NumQryPhyStatus - priv->pshare->LastNumQryPhyStatusAll;
+
+ if (RXOK_cal == 0)
+ RxPWDBAve = 0;
+ else
+ RxPWDBAve = priv->pshare->RxPWDBAve/RXOK_cal;
+
+ priv->pshare->RxPWDBAve= 0;
+
+ //printk("RX OK = %d\n", RXOK_cal);
+ //printk("RSSI = %d\n", RxPWDBAve);
+ //printk("DIG = (%x, %x), Cnt_all = %d, Cnt_Ofdm_fail = %d, Cnt_Cck_fail = %d\n", RTL_R8(0xc50), RTL_R8(0xc58), priv->pshare->FA_total_cnt, FA_cnt_ofdm, FA_cnt_cck);
+
+ if (RXOK_cal >= 70) {
+ if (RxPWDBAve <= 40) {
+ RTL_W8(0xc50, 0x1C);
+ RTL_W8(0xc58, 0x1C);
+ } else if (RxPWDBAve > 45) {
+ RTL_W8(0xc50, 0x20);
+ RTL_W8(0xc58, 0x20);
+ }
+ }
+ else {
+ RTL_W8(0xc50, 0x20);
+ RTL_W8(0xc58, 0x20);
+ }
+ }
+ mod_timer(&priv->pshare->MP_DIGTimer, jiffies + (700+9)/10);
+}
void DIG_process(struct rtl8192cd_priv *priv)
{
#define DEAD_POINT_TH 10000
@@ -463,9 +532,11 @@ void DIG_process(struct rtl8192cd_priv *priv)
unsigned char value_IGI;
signed char value8;
-
+ unsigned int IGI_target;
#ifdef INTERFERENCE_CONTROL
- unsigned short thd0, thd1, thd2;
+ unsigned short thd0 = priv->pshare->threshold0;
+ unsigned short thd1 = priv->pshare->threshold1;
+ unsigned short thd2 = priv->pshare->threshold2;
#endif
if (priv->pshare->DIG_on == 1)
@@ -502,11 +573,7 @@ void DIG_process(struct rtl8192cd_priv *priv)
// limit upper bound to prevent the minimal signal sta from disconnect
// if ((priv->pshare->rssi_min + 10) < priv->pshare->FA_upper)
// priv->pshare->FA_upper = priv->pshare->rssi_min + 10;
- priv->pshare->FA_upper = MIN_NUM(0x3E, priv->pshare->rssi_min+20);
-
- thd0 = priv->pshare->threshold0;
- thd1 = priv->pshare->threshold1;
- thd2 = priv->pshare->threshold2;
+ priv->pshare->FA_upper = MIN_NUM(0x3E, priv->pshare->rssi_min+20);
}
else // before link
{
@@ -521,10 +588,10 @@ void DIG_process(struct rtl8192cd_priv *priv)
if (priv->pmib->dot11BssType.net_work_type == WIRELESS_11B)
priv->pshare->FA_upper = MIN_NUM(0x2A, priv->pshare->rssi_min+20);
else
- priv->pshare->FA_upper = MIN_NUM(0x32, priv->pshare->rssi_min+20);
+ priv->pshare->FA_upper = MIN_NUM(0x3E, priv->pshare->rssi_min+20);
}
else
- priv->pshare->FA_upper = MIN_NUM(0x32, priv->pshare->rssi_min+20);
+ priv->pshare->FA_upper = MIN_NUM(0x3E, priv->pshare->rssi_min+20);
priv->pshare->FA_lower = 0x20;
if (priv->pshare->rssi_min > 30)
@@ -692,6 +759,12 @@ void DIG_process(struct rtl8192cd_priv *priv)
value_IGI = priv->pshare->FA_upper;
else if (value_IGI < priv->pshare->FA_lower)
value_IGI = priv->pshare->FA_lower;
+ if (priv->pshare->rf_ft_var.dynamic_edcca)
+ {
+ IGI_target = priv->pshare->rf_ft_var.IGI_target;
+ if(value_IGI > (IGI_target + 4))
+ value_IGI = IGI_target + 4;
+ }
#if defined(HW_ANT_SWITCH)
// wirte new initial gain index into regC50/C58
@@ -800,7 +873,7 @@ void DIG_process(struct rtl8192cd_priv *priv)
}
}
-
+#if 0
void check_DIG_by_rssi(struct rtl8192cd_priv *priv, unsigned char rssi_strength)
{
unsigned int dig_on = 0;
@@ -878,6 +951,7 @@ void DIG_for_site_survey(struct rtl8192cd_priv *priv, int do_ss)
}
}
}
+#endif
#ifdef INTERFERENCE_CONTROL
void check_NBI_by_rssi(struct rtl8192cd_priv *priv, unsigned char rssi_strength)
@@ -1034,7 +1108,7 @@ void tx_power_control(struct rtl8192cd_priv *priv)
}
#endif
-
+#if 0
int get_CCK_swing_index(struct rtl8192cd_priv *priv)
{
int TempCCk, index=12, i;
@@ -1067,6 +1141,7 @@ int get_CCK_swing_index(struct rtl8192cd_priv *priv)
return index;
}
+
void set_CCK_swing_index(struct rtl8192cd_priv *priv, short CCK_index)
{
short channel;
@@ -1077,6 +1152,32 @@ void set_CCK_swing_index(struct rtl8192cd_priv *priv, short CCK_index)
#endif
channel = (priv->pmib->dot11RFEntry.dot11channel);
+
+#ifdef CONFIG_RTL_88E_SUPPORT //for 88e tx power tracking
+ if(GET_CHIP_VER(priv) == VERSION_8188E){
+ if(channel !=14) {
+ RTL_W8( 0xa22, 0x1c);
+ RTL_W8( 0xa23, 0x1a);
+ RTL_W8( 0xa24, 0x18);
+ RTL_W8( 0xa25, 0x12);
+ RTL_W8( 0xa26, 0xe);
+ RTL_W8( 0xa27, 0x8);
+ RTL_W8( 0xa28, 0x4);
+ RTL_W8( 0xa29, 0x2);
+ }
+ else{
+ RTL_W8( 0xa22, 0x1c);
+ RTL_W8( 0xa23, 0x1a);
+ RTL_W8( 0xa24, 0x18);
+ RTL_W8( 0xa25, 0x12);
+ RTL_W8( 0xa26, 0x0);
+ RTL_W8( 0xa27, 0x0);
+ RTL_W8( 0xa28, 0x0);
+ RTL_W8( 0xa29, 0x0);
+ }
+ }
+ else
+#endif
if(channel !=14) {
RTL_W8( 0xa22, CCKSwingTable_Ch1_Ch13[CCK_index][0]);
RTL_W8( 0xa23, CCKSwingTable_Ch1_Ch13[CCK_index][1]);
@@ -1098,6 +1199,7 @@ void set_CCK_swing_index(struct rtl8192cd_priv *priv, short CCK_index)
RTL_W8( 0xa29, CCKSwingTable_Ch14[CCK_index][7]);
}
}
+#endif
unsigned char getThermalValue(struct rtl8192cd_priv *priv)
{
@@ -1243,7 +1345,7 @@ void tx_power_tracking(struct rtl8192cd_priv *priv)
ThermalValue = getThermalValue(priv);
rf += is2T;
- if(ThermalValue) {
+ if (ThermalValue) {
if(!priv->pshare->ThermalValue) {
priv->pshare->ThermalValue = priv->pmib->dot11RFEntry.ther;
@@ -1285,7 +1387,6 @@ void tx_power_tracking(struct rtl8192cd_priv *priv)
if(delta_LCK > 1) {
priv->pshare->ThermalValue_LCK = ThermalValue;
-
#ifdef MP_TEST
if(priv->pshare->rf_ft_var.mp_specific)
{
@@ -1297,7 +1398,6 @@ void tx_power_tracking(struct rtl8192cd_priv *priv)
else
#endif
PHY_LCCalibrate(priv);
-
}
if(delta > 0) {
@@ -1513,7 +1613,6 @@ void tx_power_tracking(struct rtl8192cd_priv *priv)
if(delta_IQK > 3) {
priv->pshare->ThermalValue_IQK = ThermalValue;
-
#ifdef MP_TEST
if(priv->pshare->rf_ft_var.mp_specific)
{
@@ -1563,6 +1662,511 @@ static void rx_gain_tracking_92D(struct rtl8192cd_priv *priv)
#endif
+#if 0
+//#ifdef CONFIG_RTL_88E_SUPPORT //for 88e tx power tracking
+
+void ODM_ResetIQKResult(struct rtl8192cd_priv *priv)
+{
+/*
+#if (DM_ODM_SUPPORT_TYPE == ODM_MP || DM_ODM_SUPPORT_TYPE == ODM_CE)
+ PADAPTER Adapter = pDM_Odm->Adapter;
+ u1Byte i;
+
+ if (!IS_HARDWARE_TYPE_8192D(Adapter))
+ return;
+#endif
+*/
+
+ unsigned char i;
+
+ //printk("PHY_ResetIQKResult:: settings regs %d default regs %d\n", sizeof(priv->pshare->IQKMatrixRegSetting)/sizeof(IQK_MATRIX_REGS_SETTING), IQK_Matrix_Settings_NUM);
+ //0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc
+
+ for(i = 0; i < IQK_Matrix_Settings_NUM; i++)
+ {
+ {
+ priv->pshare->IQKMatrixRegSetting[i].Value[0][0] =
+ priv->pshare->IQKMatrixRegSetting[i].Value[0][2] =
+ priv->pshare->IQKMatrixRegSetting[i].Value[0][4] =
+ priv->pshare->IQKMatrixRegSetting[i].Value[0][6] = 0x100;
+
+ priv->pshare->IQKMatrixRegSetting[i].Value[0][1] =
+ priv->pshare->IQKMatrixRegSetting[i].Value[0][3] =
+ priv->pshare->IQKMatrixRegSetting[i].Value[0][5] =
+ priv->pshare->IQKMatrixRegSetting[i].Value[0][7] = 0x0;
+
+ priv->pshare->IQKMatrixRegSetting[i].bIQKDone = FALSE;
+
+ }
+ }
+
+}
+
+#define RF_PATH_A 0 //Radio Path A
+#define OFDM_TABLE_SIZE_92D 43
+
+#define bRFRegOffsetMask 0xfffff
+
+
+//091212 chiyokolin
+void odm_TXPowerTrackingCallback_ThermalMeter_8188E(struct rtl8192cd_priv *priv)
+{
+
+ //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ unsigned char ThermalValue = 0, delta, delta_LCK, delta_IQK, offset;
+ unsigned char ThermalValue_AVG_count = 0;
+ unsigned int ThermalValue_AVG = 0;
+ int ele_A=0, ele_D, TempCCk, X, value32;
+ int Y, ele_C=0;
+ char OFDM_index[2], CCK_index=0, OFDM_index_old[2]={0,0}, CCK_index_old=0, index;
+ unsigned int i = 0, j = 0;
+ char is2T = FALSE;
+ //char bInteralPA = FALSE;
+
+ unsigned char OFDM_min_index = 6, rf; //OFDM BB Swing should be less than +3.0dB, which is required by Arthur
+ unsigned char Indexforchannel = 0/*GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/;
+ char OFDM_index_mapping[2][index_mapping_NUM_88E] = {
+ {0, 0, 2, 3, 4, 4, //2.4G, decrease power
+ 5, 6, 7, 7, 8, 9,
+ 10, 10, 11}, // For lower temperature, 20120220 updated on 20120220.
+ {0, 0, -1, -2, -3, -4, //2.4G, increase power
+ -4, -4, -4, -5, -7, -8,
+ -9, -9, -10},
+ };
+ unsigned char Thermal_mapping[2][index_mapping_NUM_88E] = {
+ {0, 2, 4, 6, 8, 10, //2.4G, decrease power
+ 12, 14, 16, 18, 20, 22,
+ 24, 26, 27},
+ {0, 2, 4, 6, 8, 10, //2.4G,, increase power
+ 12, 14, 16, 18, 20, 22,
+ 25, 25, 25},
+ };
+
+ priv->pshare->TXPowerTrackingCallbackCnt++; //cosa add for debug
+ priv->pshare->bTXPowerTrackingInit = TRUE;
+
+#if (MP_DRIVER == 1)
+ priv->pshare->TxPowerTrackControl = 1; //priv->pshare->TxPowerTrackControl; //_eric_?? // <Kordan> We should keep updating the control variable according to HalData.
+ // <Kordan> pshare->RegA24 will be initialized when ODM HW configuring, but MP configures with para files.
+ priv->pshare->RegA24 = 0x090e1317;
+#endif
+
+
+#ifdef MP_TEST
+ if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) {
+ if(priv->pshare->mp_txpwr_tracking == FALSE)
+ return;
+ }
+#endif
+
+ if(priv->pshare->Power_tracking_on_88E == 0)
+ {
+ priv->pshare->Power_tracking_on_88E = 1;
+ PHY_SetRFReg(priv, RF92CD_PATH_A, 0x42, (BIT(17) | BIT(16)), 0x03);
+ return;
+ }
+ else
+ {
+
+ priv->pshare->Power_tracking_on_88E = 0;
+
+ //printk("===>dm_TXPowerTrackingCallback_ThermalMeter_8188E txpowercontrol %d\n", priv->pshare->TxPowerTrackControl);
+
+ ThermalValue = (unsigned char)PHY_QueryRFReg(priv, RF_PATH_A, RF_T_METER_88E, 0xfc00, 1); //0x42: RF Reg[15:10] 88E
+
+ printk("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", ThermalValue, priv->pshare->ThermalValue, priv->pmib->dot11RFEntry.ther);
+
+ }
+
+ if(is2T)
+ rf = 2;
+ else
+ rf = 1;
+
+ if(ThermalValue)
+ {
+// if(!pHalData->ThermalValue)
+ {
+ //Query OFDM path A default setting
+ ele_D = PHY_QueryBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord)&bMaskOFDM_D;
+
+ for(i=0; i<OFDM_TABLE_SIZE_92D; i++) //find the index
+ {
+ if(ele_D == (OFDMSwingTable[i]&bMaskOFDM_D))
+ {
+ OFDM_index_old[0] = (unsigned char)i;
+ printk("Initial pathA ele_D reg0x%x = 0x%x, OFDM_index=0x%x\n",
+ rOFDM0_XATxIQImbalance, ele_D, OFDM_index_old[0]);
+ break;
+ }
+ }
+
+ //Query OFDM path B default setting
+ if(is2T)
+ {
+ ele_D = PHY_QueryBBReg(priv, rOFDM0_XBTxIQImbalance, bMaskDWord)&bMaskOFDM_D;
+ for(i=0; i<OFDM_TABLE_SIZE_92D; i++) //find the index
+ {
+ if(ele_D == (OFDMSwingTable[i]&bMaskOFDM_D))
+ {
+ OFDM_index_old[1] = (unsigned char)i;
+ printk("Initial pathB ele_D reg0x%x = 0x%x, OFDM_index=0x%x\n",
+ rOFDM0_XBTxIQImbalance, ele_D, OFDM_index_old[1]);
+ break;
+ }
+ }
+ }
+
+ {
+ //Query CCK default setting From 0xa24
+ TempCCk = priv->pshare->RegA24;
+
+ for(i=0 ; i<CCK_TABLE_SIZE ; i++)
+ {
+ if(priv->pshare->bCCKinCH14)
+ {
+ if(memcmp((void*)&TempCCk, (void*)&CCKSwingTable_Ch14[i][2], 4)==0)
+ {
+ CCK_index_old =(unsigned char) i;
+ //printk("Initial reg0x%x = 0x%x, CCK_index=0x%x, ch 14 %d\n",
+ //rCCK0_TxFilter2, TempCCk, CCK_index_old, priv->pshare->bCCKinCH14);
+ break;
+ }
+ }
+ else
+ {
+ //printk("RegA24: 0x%X, CCKSwingTable_Ch1_Ch13[%d][2]: CCKSwingTable_Ch1_Ch13[i][2]: 0x%X\n", TempCCk, i, CCKSwingTable_Ch1_Ch13[i][2]);
+ if(memcmp((void*)&TempCCk, (void*)&CCKSwingTable_Ch1_Ch13[i][2], 4)==0)
+ {
+ CCK_index_old =(unsigned char) i;
+ //printk("Initial reg0x%x = 0x%x, CCK_index=0x%x, ch14 %d\n",
+ //rCCK0_TxFilter2, TempCCk, CCK_index_old, priv->pshare->bCCKinCH14);
+ break;
+ }
+ }
+ }
+ }
+
+ if(!priv->pshare->ThermalValue)
+ {
+ priv->pshare->ThermalValue = priv->pmib->dot11RFEntry.ther;
+ priv->pshare->ThermalValue_LCK = ThermalValue;
+ priv->pshare->ThermalValue_IQK = ThermalValue;
+
+ for(i = 0; i < rf; i++)
+ priv->pshare->OFDM_index[i] = OFDM_index_old[i];
+ priv->pshare->CCK_index = CCK_index_old;
+ }
+
+ if(priv->pshare->bReloadtxpowerindex)
+ {
+ printk("reload ofdm index for band switch\n");
+ }
+
+ //calculate average thermal meter
+ {
+ priv->pshare->ThermalValue_AVG[priv->pshare->ThermalValue_AVG_index] = ThermalValue;
+ priv->pshare->ThermalValue_AVG_index++;
+ if(priv->pshare->ThermalValue_AVG_index == AVG_THERMAL_NUM_88E)
+ priv->pshare->ThermalValue_AVG_index = 0;
+
+ for(i = 0; i < AVG_THERMAL_NUM_88E; i++)
+ {
+ if(priv->pshare->ThermalValue_AVG[i])
+ {
+ ThermalValue_AVG += priv->pshare->ThermalValue_AVG[i];
+ ThermalValue_AVG_count++;
+ }
+ }
+
+ if(ThermalValue_AVG_count)
+ {
+ ThermalValue = (unsigned char)(ThermalValue_AVG / ThermalValue_AVG_count);
+ printk("AVG Thermal Meter = 0x%x \n", ThermalValue);
+ }
+ }
+ }
+
+ if(priv->pshare->bReloadtxpowerindex)
+ {
+ delta = ThermalValue > priv->pmib->dot11RFEntry.ther?(ThermalValue - priv->pmib->dot11RFEntry.ther):(priv->pmib->dot11RFEntry.ther - ThermalValue);
+ priv->pshare->bReloadtxpowerindex = FALSE;
+ priv->pshare->bDoneTxpower = FALSE;
+ }
+ else if(priv->pshare->bDoneTxpower)
+ {
+ delta = (ThermalValue > priv->pshare->ThermalValue)?(ThermalValue - priv->pshare->ThermalValue):(priv->pshare->ThermalValue - ThermalValue);
+ }
+ else
+ {
+ delta = ThermalValue > priv->pmib->dot11RFEntry.ther?(ThermalValue - priv->pmib->dot11RFEntry.ther):(priv->pmib->dot11RFEntry.ther - ThermalValue);
+ }
+ delta_LCK = (ThermalValue > priv->pshare->ThermalValue_LCK)?(ThermalValue - priv->pshare->ThermalValue_LCK):(priv->pshare->ThermalValue_LCK - ThermalValue);
+ delta_IQK = (ThermalValue > priv->pshare->ThermalValue_IQK)?(ThermalValue - priv->pshare->ThermalValue_IQK):(priv->pshare->ThermalValue_IQK - ThermalValue);
+
+ printk("Readback Thermal Meter = 0x%x \npre thermal meter 0x%x EEPROMthermalmeter 0x%x delta 0x%x \ndelta_LCK 0x%x delta_IQK 0x%x \n", ThermalValue, priv->pshare->ThermalValue, priv->pshare->EEPROMThermalMeter, delta, delta_LCK, delta_IQK);
+ printk("pre thermal meter LCK 0x%x \npre thermal meter IQK 0x%x \ndelta_LCK_bound 0x%x delta_IQK_bound 0x%x\n", priv->pshare->ThermalValue_LCK, priv->pshare->ThermalValue_IQK, priv->pshare->Delta_LCK, priv->pshare->Delta_IQK);
+
+
+ //if((delta_LCK > pHalData->Delta_LCK) && (pHalData->Delta_LCK != 0))
+ if (delta_LCK >= 8) // Delta temperature is equal to or larger than 20 centigrade.
+ {
+ priv->pshare->ThermalValue_LCK = ThermalValue;
+ PHY_LCCalibrate(priv);
+ }
+
+
+ if(delta > 0 && priv->pshare->TxPowerTrackControl)
+ {
+ delta = ThermalValue > priv->pmib->dot11RFEntry.ther?(ThermalValue - priv->pmib->dot11RFEntry.ther):(priv->pmib->dot11RFEntry.ther - ThermalValue);
+
+ //calculate new OFDM / CCK offset
+ {
+ {
+ if(ThermalValue > priv->pmib->dot11RFEntry.ther)
+ j = 1;
+ else
+ j = 0;
+
+ for(offset = 0; offset < index_mapping_NUM_88E; offset++)
+ {
+ if(delta < Thermal_mapping[j][offset])
+ {
+ if(offset != 0)
+ offset--;
+ break;
+ }
+ }
+ if(offset >= index_mapping_NUM_88E)
+ offset = index_mapping_NUM_88E-1;
+
+ index = OFDM_index_mapping[j][offset];
+
+ printk("\nj = %d delta = %d, index = %d\n\n", j, delta, index);
+
+ for(i = 0; i < rf; i++)
+ OFDM_index[i] = priv->pshare->OFDM_index[i] + OFDM_index_mapping[j][offset];
+ CCK_index = priv->pshare->CCK_index + OFDM_index_mapping[j][offset];
+ }
+
+ if(is2T)
+ {
+ printk("temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, CCK_index=0x%x\n",
+ priv->pshare->OFDM_index[0], priv->pshare->OFDM_index[1], priv->pshare->CCK_index);
+ }
+ else
+ {
+ printk("temp OFDM_A_index=0x%x, CCK_index=0x%x\n",
+ priv->pshare->OFDM_index[0], priv->pshare->CCK_index);
+ }
+
+ for(i = 0; i < rf; i++)
+ {
+ if(OFDM_index[i] > OFDM_TABLE_SIZE_92D-1)
+ {
+ OFDM_index[i] = OFDM_TABLE_SIZE_92D-1;
+ }
+ else if (OFDM_index[i] < OFDM_min_index)
+ {
+ OFDM_index[i] = OFDM_min_index;
+ }
+ }
+
+ {
+ if(CCK_index > CCK_TABLE_SIZE-1)
+ CCK_index = CCK_TABLE_SIZE-1;
+ else if (CCK_index < 0)
+ CCK_index = 0;
+ }
+
+ if(is2T)
+ {
+ printk("new OFDM_A_index=0x%x, OFDM_B_index=0x%x, CCK_index=0x%x\n",
+ OFDM_index[0], OFDM_index[1], CCK_index);
+ }
+ else
+ {
+ printk("new OFDM_A_index=0x%x, CCK_index=0x%x\n",
+ OFDM_index[0], CCK_index);
+ }
+ }
+
+ //2 temporarily remove bNOPG
+ //Config by SwingTable
+ if(priv->pshare->TxPowerTrackControl /*&& !pHalData->bNOPG*/)
+ {
+ priv->pshare->bDoneTxpower = TRUE;
+
+ //Adujst OFDM Ant_A according to IQK result
+ ele_D = (OFDMSwingTable[(unsigned char)OFDM_index[0]] & 0xFFC00000)>>22;
+ X = priv->pshare->IQKMatrixRegSetting[Indexforchannel].Value[0][0];
+ Y = priv->pshare->IQKMatrixRegSetting[Indexforchannel].Value[0][1];
+
+ if(X != 0)
+ {
+ if ((X & 0x00000200) != 0)
+ X = X | 0xFFFFFC00;
+ ele_A = ((X * ele_D)>>8)&0x000003FF;
+
+ //new element C = element D x Y
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+ ele_C = ((Y * ele_D)>>8)&0x000003FF;
+
+ //wirte new elements A, C, D to regC80 and regC94, element B is always 0
+ value32 = (ele_D<<22)|((ele_C&0x3F)<<16)|ele_A;
+ PHY_SetBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, value32);
+
+ value32 = (ele_C&0x000003C0)>>6;
+ PHY_SetBBReg(priv, rOFDM0_XCTxAFE, bMaskH4Bits, value32);
+
+ value32 = ((X * ele_D)>>7)&0x01;
+ PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(24), value32);
+
+ }
+ else
+ {
+ PHY_SetBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[(unsigned char)OFDM_index[0]]);
+ PHY_SetBBReg(priv, rOFDM0_XCTxAFE, bMaskH4Bits, 0x00);
+ PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(24), 0x00);
+ }
+
+ //printk("TxPwrTracking for path A: X = 0x%x, Y = 0x%x ele_A = 0x%x ele_C = 0x%x ele_D = 0x%x 0xe94 = 0x%x 0xe9c = 0x%x\n",
+ //(unsigned int)X, (unsigned int)Y, (unsigned int)ele_A, (unsigned int)ele_C, (unsigned int)ele_D, (unsigned int)X, (unsigned int)Y);
+
+ {
+ //Adjust CCK according to IQK result
+ if(!priv->pshare->bCCKinCH14){
+ RTL_W8(0xa22, CCKSwingTable_Ch1_Ch13[(unsigned char)CCK_index][0]);
+ RTL_W8(0xa23, CCKSwingTable_Ch1_Ch13[(unsigned char)CCK_index][1]);
+ RTL_W8(0xa24, CCKSwingTable_Ch1_Ch13[(unsigned char)CCK_index][2]);
+ RTL_W8(0xa25, CCKSwingTable_Ch1_Ch13[(unsigned char)CCK_index][3]);
+ RTL_W8(0xa26, CCKSwingTable_Ch1_Ch13[(unsigned char)CCK_index][4]);
+ RTL_W8(0xa27, CCKSwingTable_Ch1_Ch13[(unsigned char)CCK_index][5]);
+ RTL_W8(0xa28, CCKSwingTable_Ch1_Ch13[(unsigned char)CCK_index][6]);
+ RTL_W8(0xa29, CCKSwingTable_Ch1_Ch13[(unsigned char)CCK_index][7]);
+ }
+ else{
+ RTL_W8(0xa22, CCKSwingTable_Ch14[(unsigned char)CCK_index][0]);
+ RTL_W8(0xa23, CCKSwingTable_Ch14[(unsigned char)CCK_index][1]);
+ RTL_W8(0xa24, CCKSwingTable_Ch14[(unsigned char)CCK_index][2]);
+ RTL_W8(0xa25, CCKSwingTable_Ch14[(unsigned char)CCK_index][3]);
+ RTL_W8(0xa26, CCKSwingTable_Ch14[(unsigned char)CCK_index][4]);
+ RTL_W8(0xa27, CCKSwingTable_Ch14[(unsigned char)CCK_index][5]);
+ RTL_W8(0xa28, CCKSwingTable_Ch14[(unsigned char)CCK_index][6]);
+ RTL_W8(0xa29, CCKSwingTable_Ch14[(unsigned char)CCK_index][7]);
+ }
+ }
+
+ if(is2T)
+ {
+ ele_D = (OFDMSwingTable[(unsigned char)OFDM_index[1]] & 0xFFC00000)>>22;
+
+ //new element A = element D x X
+ X = priv->pshare->IQKMatrixRegSetting[Indexforchannel].Value[0][4];
+ Y = priv->pshare->IQKMatrixRegSetting[Indexforchannel].Value[0][5];
+
+ //if(X != 0 && pHalData->CurrentBandType92D == ODM_BAND_ON_2_4G)
+ if((X != 0) && (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G))
+
+ {
+ if ((X & 0x00000200) != 0) //consider minus
+ X = X | 0xFFFFFC00;
+ ele_A = ((X * ele_D)>>8)&0x000003FF;
+
+ //new element C = element D x Y
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+ ele_C = ((Y * ele_D)>>8)&0x00003FF;
+
+ //wirte new elements A, C, D to regC88 and regC9C, element B is always 0
+ value32=(ele_D<<22)|((ele_C&0x3F)<<16) |ele_A;
+ PHY_SetBBReg(priv, rOFDM0_XBTxIQImbalance, bMaskDWord, value32);
+
+ value32 = (ele_C&0x000003C0)>>6;
+ PHY_SetBBReg(priv, rOFDM0_XDTxAFE, bMaskH4Bits, value32);
+
+ value32 = ((X * ele_D)>>7)&0x01;
+ PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(28), value32);
+
+ }
+ else
+ {
+ PHY_SetBBReg(priv, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable[(unsigned char)OFDM_index[1]]);
+ PHY_SetBBReg(priv, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00);
+ PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(28), 0x00);
+ }
+
+ //printk("TxPwrTracking path B: X = 0x%x, Y = 0x%x ele_A = 0x%x ele_C = 0x%x ele_D = 0x%x 0xeb4 = 0x%x 0xebc = 0x%x\n",
+ //(unsigned int)X, (unsigned int)Y, (unsigned int)ele_A, (unsigned int)ele_C, (unsigned int)ele_D, (unsigned int)X, (unsigned int)Y);
+ }
+
+ printk("TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n\n", PHY_QueryBBReg(priv, 0xc80, bMaskDWord), PHY_QueryBBReg(priv, 0xc94, bMaskDWord), PHY_QueryRFReg(priv, RF_PATH_A, 0x24, bRFRegOffsetMask, 1));
+ }
+ }
+
+
+#if 0 //DO NOT do IQK during 88E power tracking
+ // if((delta_IQK > pHalData->Delta_IQK) && (pHalData->Delta_IQK != 0))
+ if (delta_IQK >= 8) // Delta temperature is equal to or larger than 20 centigrade.
+ {
+ ODM_ResetIQKResult(priv);
+
+/*
+#if(DM_ODM_SUPPORT_TYPE & ODM_MP)
+#if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
+#if USE_WORKITEM
+ PlatformAcquireMutex(&pHalData->mxChnlBwControl);
+#else
+ PlatformAcquireSpinLock(Adapter, RT_CHANNEL_AND_BANDWIDTH_SPINLOCK);
+#endif
+#elif((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE))
+ PlatformAcquireMutex(&pHalData->mxChnlBwControl);
+#endif
+#endif
+*/
+ priv->pshare->ThermalValue_IQK= ThermalValue;
+ PHY_IQCalibrate_8188E(priv, FALSE);
+
+/*
+#if(DM_ODM_SUPPORT_TYPE & ODM_MP)
+#if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
+#if USE_WORKITEM
+ PlatformReleaseMutex(&pHalData->mxChnlBwControl);
+#else
+ PlatformReleaseSpinLock(Adapter, RT_CHANNEL_AND_BANDWIDTH_SPINLOCK);
+#endif
+#elif((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE))
+ PlatformReleaseMutex(&pHalData->mxChnlBwControl);
+#endif
+#endif
+*/
+ }
+#endif
+
+ //update thermal meter value
+ if(priv->pshare->TxPowerTrackControl)
+ {
+ //Adapter->HalFunc.SetHalDefVarHandler(Adapter, HAL_DEF_THERMAL_VALUE, &ThermalValue);
+ priv->pshare->ThermalValue = ThermalValue;
+ }
+
+ }
+
+ //printk("<===dm_TXPowerTrackingCallback_ThermalMeter_8188E\n");
+
+ priv->pshare->TXPowercount = 0;
+
+}
+
+
+
+
+#endif
+
+
+
#ifdef CONFIG_RTL_92D_SUPPORT
void getDeltaValue(struct rtl8192cd_priv *priv)
@@ -2081,7 +2685,7 @@ u8 index_mapping_HighPower_PA[12][index_mapping_NUM] = {
//Config by SwingTable
{
//Adujst OFDM Ant_A according to IQK result
- ele_D = (OFDMSwingTable_92D[OFDM_index[0]] & 0xFFC00000)>>22;
+ ele_D = (OFDMSwingTable_92D[(unsigned int)OFDM_index[0]] & 0xFFC00000)>>22;
X = priv->pshare->RegE94;
Y = priv->pshare->RegE9C;
@@ -2108,7 +2712,7 @@ u8 index_mapping_HighPower_PA[12][index_mapping_NUM] = {
}
else
{
- PHY_SetBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable_92D[OFDM_index[0]]);
+ PHY_SetBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable_92D[(unsigned int)OFDM_index[0]]);
PHY_SetBBReg(priv, rOFDM0_XCTxAFE, bMaskH4Bits, 0x00);
PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(24), 0x00);
#ifdef MP_TEST
@@ -2131,7 +2735,7 @@ u8 index_mapping_HighPower_PA[12][index_mapping_NUM] = {
if(is2T)
{
- ele_D = (OFDMSwingTable_92D[OFDM_index[1]] & 0xFFC00000)>>22;
+ ele_D = (OFDMSwingTable_92D[(unsigned int)OFDM_index[1]] & 0xFFC00000)>>22;
//new element A = element D x X
X = priv->pshare->RegEB4;
@@ -2159,7 +2763,7 @@ u8 index_mapping_HighPower_PA[12][index_mapping_NUM] = {
}
else{
- PHY_SetBBReg(priv, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable_92D[OFDM_index[1]]);
+ PHY_SetBBReg(priv, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable_92D[(unsigned int)OFDM_index[1]]);
PHY_SetBBReg(priv, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00);
PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(28), 0x00);
#ifdef MP_TEST
@@ -2332,6 +2936,9 @@ void init_EDCA_para(struct rtl8192cd_priv *priv, int mode)
#ifdef WMM_VIBE_PRI
priv->pshare->iot_mode_BE_exist = 0;
#endif
+#ifdef WMM_BEBK_PRI
+ priv->pshare->iot_mode_BK_exist = 0;
+#endif
#ifdef LOW_TP_TXOP
priv->pshare->BE_cwmax_enhance = 0;
#endif
@@ -2339,6 +2946,14 @@ void init_EDCA_para(struct rtl8192cd_priv *priv, int mode)
void choose_IOT_main_sta(struct rtl8192cd_priv *priv, struct stat_info *pstat)
{
+ if (priv->pshare->rf_ft_var.low_tp_no_aggr) {
+ unsigned long sta_tp = (pstat->current_tx_bytes + pstat->current_rx_bytes) >> 17;
+ if (!pstat->low_tp_disable_ampdu && sta_tp <= 2)
+ pstat->low_tp_disable_ampdu = 1;
+ else if (pstat->low_tp_disable_ampdu && sta_tp >= 5)
+ pstat->low_tp_disable_ampdu = 0;
+ }
+
if ((GET_ROOT(priv)->up_time % 2) == 0) {
unsigned int tx_2s_avg = 0;
unsigned int rx_2s_avg = 0;
@@ -2360,9 +2975,12 @@ void choose_IOT_main_sta(struct rtl8192cd_priv *priv, struct stat_info *pstat)
for(i=0; i<8; i++)
aggReady += (pstat->ADDBA_ready[i]);
- if (pstat->ht_cap_len && aggReady) {
+ if ((pstat->ht_cap_len && aggReady) || (pstat->is_intel_sta)) {
if ((tx_2s_avg + rx_2s_avg >= 50)) {
priv->pshare->highTP_found_pstat = pstat;
+ } /*this STA's TXRX packet very close AP's total TXRX packet then let it as highTP_found_pstat*/
+ else if(RTL_ABS((pstat->current_tx_bytes + pstat->current_rx_bytes) , total_sum)<50){
+ priv->pshare->highTP_found_pstat = pstat;
}
#ifdef CLIENT_MODE
if (OPMODE & WIFI_STATION_STATE) {
@@ -2394,8 +3012,11 @@ void rxBB_dm(struct rtl8192cd_priv *priv)
#endif
}
- check_EDCCA(priv, priv->pshare->rssi_min);
-
+ if (priv->pshare->rf_ft_var.dynamic_edcca){
+ unsigned char IGI;
+ IGI = RTL_R8(0xc50);
+ Dynamic_EDCCA(priv,IGI);
+ }
#ifdef MP_TEST
if (!((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific))
#endif
@@ -2424,7 +3045,7 @@ void IOT_engine(struct rtl8192cd_priv *priv)
#ifdef WIFI_WMM
if (QOS_ENABLE) {
if (!priv->pmib->dot11OperationEntry.wifi_specific ||
- ((OPMODE & WIFI_AP_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific == 2))) {
+ ((OPMODE & WIFI_AP_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific))) {
if (priv->pshare->iot_mode_enable &&
((priv->pshare->phw->VO_pkt_count > 50) ||
(priv->pshare->phw->VI_pkt_count > 50) ||
@@ -2462,6 +3083,19 @@ void IOT_engine(struct rtl8192cd_priv *priv)
}
#endif
+#ifdef WMM_BEBK_PRI
+ if (priv->pshare->phw->BE_pkt_count) {
+ //printk("[%s %d] BK_pkt_count=%d\n", __FUNCTION__, __LINE__, priv->pshare->phw->BK_pkt_count);
+ if (!priv->pshare->iot_mode_BK_exist && (priv->pshare->phw->BK_pkt_count > 250)) {
+ priv->pshare->iot_mode_BK_exist++;
+ switch_turbo++;
+ } else if (priv->pshare->iot_mode_BE_exist && (priv->pshare->phw->BK_pkt_count < 250)) {
+ priv->pshare->iot_mode_BK_exist = 0;
+ switch_turbo++;
+ }
+ }
+#endif
+
if (priv->pshare->rf_ft_var.wifi_beq_iot) {
if (!priv->pshare->iot_mode_VI_exist && (priv->pshare->phw->VI_rx_pkt_count > 50)) {
priv->pshare->iot_mode_VI_exist++;
@@ -2471,10 +3105,25 @@ void IOT_engine(struct rtl8192cd_priv *priv)
switch_turbo++;
}
}
+
+#ifdef CONFIG_RTL_92D_DMDP
+ if ((GET_CHIP_VER(priv) == VERSION_8192D) && (priv->pmib->dot11RFEntry.macPhyMode == DUALMAC_DUALPHY)) {
+ unsigned int tp = (unsigned int)(priv->ext_stats.tx_avarage>>17) + (unsigned int)(priv->ext_stats.rx_avarage>>17);
+ if (priv->pshare->rf_ft_var.wifi_beq_iot) {
+ if (priv->pshare->wifi_beq_lower && priv->pshare->iot_mode_VI_exist && tp <= 20) {
+ priv->pshare->wifi_beq_lower= 0;
+ switch_turbo++;
+ } else if (!priv->pshare->wifi_beq_lower&& (!priv->pshare->iot_mode_VI_exist || tp > 20)) {
+ priv->pshare->wifi_beq_lower= 1;
+ switch_turbo++;
+ }
+ }
+ }
+#endif
}
#ifdef CLIENT_MODE
- if ((OPMODE & WIFI_STATION_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific == 2))
+ if ((OPMODE & WIFI_STATION_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific))
{
if (priv->pshare->iot_mode_enable &&
(((priv->pshare->phw->VO_pkt_count > 50) ||
@@ -2576,50 +3225,70 @@ void IOT_engine(struct rtl8192cd_priv *priv)
#ifdef SW_TX_QUEUE
if ((priv->assoc_num > 1) && (AMPDU_ENABLE))
- {
- if (priv->swq_txmac_chg >= priv->pshare->rf_ft_var.swq_en_highthd)
- {
- if ((priv->swq_en == 0))
- {
- switch_turbo++;
- if (priv->pshare->txop_enlarge == 0)
- priv->pshare->txop_enlarge = 2;
- priv->swq_en = 1;
- }
- else
- {
- if ((switch_turbo > 0) && (priv->pshare->txop_enlarge == 0) && (priv->pshare->iot_mode_enable != 0))
- {
+ {
+ unsigned int total_tp = (unsigned int)(priv->ext_stats.tx_avarage>>17)+(unsigned int)(priv->ext_stats.rx_avarage>>17);
+ if(total_tp > 0) {
+ if (((unsigned int)(priv->ext_stats.tx_avarage>>17) * 100/total_tp) > 30)
+ {
+ if (priv->swq_txmac_chg >= priv->pshare->rf_ft_var.swq_en_highthd)
+ {
+ if ((priv->swq_en == 0))
+ {
+ switch_turbo++;
+ if (priv->pshare->txop_enlarge == 0)
+ priv->pshare->txop_enlarge = 2;
+ priv->swq_en = 1;
+ priv->swqen_keeptime = priv->up_time;
+ }
+ else
+ {
+ if ((switch_turbo > 0) && (priv->pshare->txop_enlarge == 0) && (priv->pshare->iot_mode_enable != 0))
+ {
+ priv->pshare->txop_enlarge = 2;
+ switch_turbo--;
+ }
+ }
+ }
+ else if(priv->swq_txmac_chg <= priv->pshare->rf_ft_var.swq_dis_lowthd)
+ {
+ priv->swq_en = 0;
+ priv->swqen_keeptime = 0;
+ }
+ else if ((priv->swq_en == 1) && (switch_turbo > 0) && (priv->pshare->txop_enlarge == 0) && (priv->pshare->iot_mode_enable != 0))
+ {
priv->pshare->txop_enlarge = 2;
- switch_turbo--;
- }
+ switch_turbo--;
+ }
}
- }
- else if(priv->swq_txmac_chg <= priv->pshare->rf_ft_var.swq_dis_lowthd)
- {
- priv->swq_en = 0;
- }
- else if ((priv->swq_en == 1) && (switch_turbo > 0) && (priv->pshare->txop_enlarge == 0) && (priv->pshare->iot_mode_enable != 0))
- {
- priv->pshare->txop_enlarge = 2;
- switch_turbo--;
- }
-
+ else if (((unsigned int)(priv->ext_stats.tx_avarage>>17) * 100/total_tp) < 20)
+ {
+ priv->swq_en = 0;
+ priv->swqen_keeptime = 0;
+ }
+ }
//debug msg
//printk("swq=%d,sw=%d,en=%d,mode=%d\n", priv->swq_en, switch_turbo, priv->pshare->txop_enlarge, priv->pshare->iot_mode_enable);
}
-#if defined(CONFIG_RTL_819XD)
- else if((priv->assoc_num == 1) && (AMPDU_ENABLE)) {
- if (pstat) {
- if ((pstat->current_tx_bytes > 14417920) && (pstat->current_rx_bytes > 14417920) && (priv->swq_en == 0)) { //55Mbps
- priv->swq_en = 1;
- }
- else if (((pstat->tx_avarage < 4587520) || (pstat->rx_avarage < 4587520)) && (priv->swq_en == 1)) { //35Mbps
- priv->swq_en = 0;
- }
+#if 1//defined(CONFIG_RTL_819XD)
+ else if( (priv->assoc_num == 1) && (AMPDU_ENABLE)) {
+ //if (pstat) {
+ if ((pstat) && pstat->is_intel_sta) {
+ //int en_thd = 14417920>>(priv->up_time % 2);
+ //if ((priv->swq_en == 0) && (pstat->current_tx_bytes > en_thd) && (pstat->current_rx_bytes > en_thd) ) { //50Mbps
+ if ((pstat->current_tx_bytes > 14417920) && (priv->swq_en == 0)) { // && (pstat->current_rx_bytes > 14417920) && (priv->swq_en == 0)) { //55Mbps
+ priv->swq_en = 1;
+ priv->swqen_keeptime = priv->up_time;
+ }
+ //else if ((priv->swq_en == 1) && ((pstat->tx_avarage < 4587520) || (pstat->rx_avarage < 4587520))) { //35Mbps
+ else if ((pstat->tx_avarage < 9175040) && (priv->swq_en == 1)) { //35Mbps
+ priv->swq_en = 0;
+ priv->swqen_keeptime = 0;
+ }
}
- else
+ else {
priv->swq_en = 0;
+ priv->swqen_keeptime = 0;
+ }
}
#endif
#endif
@@ -2691,9 +3360,9 @@ void IOT_EDCA_switch(struct rtl8192cd_priv *priv, int mode, char enable)
unsigned int vi_cw_max = 4, vi_cw_min = 3, vi_aifs;
if (!(!priv->pmib->dot11OperationEntry.wifi_specific ||
- ((OPMODE & WIFI_AP_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific == 2))
+ ((OPMODE & WIFI_AP_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific))
#ifdef CLIENT_MODE
- || ((OPMODE & WIFI_STATION_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific == 2))
+ || ((OPMODE & WIFI_STATION_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific))
#endif
))
return;
@@ -2712,7 +3381,7 @@ void IOT_EDCA_switch(struct rtl8192cd_priv *priv, int mode, char enable)
VI_TXOP = 188;
}
-#if 0 //defined(CONFIG_RTL_8196D) || defined(CONFIG_RTL_8196E) || (defined(CONFIG_RTL_8197D) && !defined(CONFIG_PORT0_EXT_GIGA))
+#if 0 //defined(CONFIG_RTL_8196D) || defined(CONFIG_RTL_8197DL) || defined(CONFIG_RTL_8196E) || (defined(CONFIG_RTL_8197D) && !defined(CONFIG_PORT0_EXT_GIGA))
if (priv->pshare->is_40m_bw)
{
BE_TXOP = 23;
@@ -2739,15 +3408,32 @@ void IOT_EDCA_switch(struct rtl8192cd_priv *priv, int mode, char enable)
RTL_W32(EDCA_VI_PARA, ((VI_TXOP*(1-priv->pshare->iot_mode_VO_exist)) << 16)
| (vi_cw_max << 12) | (vi_cw_min << 8) | vi_aifs);
+
+#ifdef WMM_BEBK_PRI
+#ifdef CONFIG_RTL_88E_SUPPORT
+ if ((GET_CHIP_VER(priv) == VERSION_8188E ) && priv->pshare->iot_mode_BK_exist) {
+ RTL_W32(EDCA_BK_PARA, (10 << 12) | (6 << 8) | 0x4f);
+ }
+#endif
+#endif
}
if (!enable || (priv->pshare->rf_ft_var.wifi_beq_iot && priv->pshare->iot_mode_VI_exist)) {
if (priv->pshare->rf_ft_var.wifi_beq_iot && priv->pshare->iot_mode_VI_exist) {
+#ifdef CONFIG_RTL_92D_DMDP
+ if ((GET_CHIP_VER(priv) == VERSION_8192D) && (priv->pmib->dot11RFEntry.macPhyMode == DUALMAC_DUALPHY)) {
+ if (priv->pshare->wifi_beq_lower)
+ RTL_W32(EDCA_BE_PARA, (10 << 12) | (4 << 8) | (sifs_time + 10 * slot_time));
+ else
+ RTL_W32(EDCA_BE_PARA, (6 << 12) | (4 << 8) | (sifs_time + 3 * slot_time));
+ } else
+#endif
RTL_W32(EDCA_BE_PARA, (10 << 12) | (4 << 8) | 0x4f);
} else {
RTL_W32(EDCA_BE_PARA, (((OPMODE & WIFI_AP_STATE)?6:10) << 12) | (4 << 8)
| (sifs_time + 3 * slot_time));
}
+ RTL_W16(RD_CTRL, RTL_R16(RD_CTRL) | DIS_TXOP_CFE);
} else {
#ifdef LOW_TP_TXOP
int txop;
@@ -2776,10 +3462,17 @@ void IOT_EDCA_switch(struct rtl8192cd_priv *priv, int mode, char enable)
if (priv->pshare->txop_enlarge == 0xe) {
#ifndef LOW_TP_TXOP
// is intel client, use a different edca value
-#if 0 //defined(CONFIG_RTL_8196D) || defined(CONFIG_RTL_8196E) || (defined(CONFIG_RTL_8197D) && !defined(CONFIG_PORT0_EXT_GIGA))
+#if 0 //defined(CONFIG_RTL_8196D) || defined(CONFIG_RTL_8197DL) || defined(CONFIG_RTL_8196E) || (defined(CONFIG_RTL_8197D) && !defined(CONFIG_PORT0_EXT_GIGA))
RTL_W32(EDCA_BE_PARA, (BE_TXOP*2 << 16) | (6 << 12) | (5 << 8) | 0x1f);
#else
- RTL_W32(EDCA_BE_PARA, (BE_TXOP*2 << 16) | (6 << 12) | (4 << 8) | 0x1f);
+ //RTL_W32(EDCA_BE_PARA, (BE_TXOP*2 << 16) | (6 << 12) | (4 << 8) | 0x1f);
+ if (get_rf_mimo_mode(priv) == MIMO_1T1R)
+ //RTL_W32(EDCA_BE_PARA, (BE_TXOP*2 << 16) | (5 << 12) | (3 << 8) | 0x1f);
+ RTL_W32(EDCA_BE_PARA, (BE_TXOP*2 << 16) | (6 << 12) | (5 << 8) | 0x1f);
+ else
+ RTL_W32(EDCA_BE_PARA, (BE_TXOP*2 << 16) | (8 << 12) | (5 << 8) | 0x1f);
+
+ RTL_W16(RD_CTRL, RTL_R16(RD_CTRL) & ~(DIS_TXOP_CFE));
#endif
priv->pshare->txop_enlarge = 2;
} else if (priv->pshare->txop_enlarge == 0xd) {
@@ -2787,8 +3480,11 @@ void IOT_EDCA_switch(struct rtl8192cd_priv *priv, int mode, char enable)
RTL_W32(EDCA_BE_PARA, (BE_TXOP*2 << 16) | (4 << 12) | (3 << 8) | 0x19);
priv->pshare->txop_enlarge = 2;
} else {
+ if (priv->pshare->txop_enlarge == 0)
+ RTL_W16(RD_CTRL, RTL_R16(RD_CTRL) | DIS_TXOP_CFE);
+
if (get_rf_mimo_mode(priv) == MIMO_2T2R)
-#if 0 //defined(CONFIG_RTL_8196D) || defined(CONFIG_RTL_8196E) || (defined(CONFIG_RTL_8197D) && !defined(CONFIG_PORT0_EXT_GIGA))
+#if 0 //defined(CONFIG_RTL_8196D) || defined(CONFIG_RTL_8197DL) || defined(CONFIG_RTL_8196E) || (defined(CONFIG_RTL_8197D) && !defined(CONFIG_PORT0_EXT_GIGA))
RTL_W32(EDCA_BE_PARA, ((BE_TXOP*priv->pshare->txop_enlarge) << 16) |
(6 << 12) | (5 << 8) | (sifs_time + 3 * slot_time));
#else
@@ -2796,7 +3492,7 @@ void IOT_EDCA_switch(struct rtl8192cd_priv *priv, int mode, char enable)
(6 << 12) | (4 << 8) | (sifs_time + 3 * slot_time));
#endif
else
-#if 0 //defined(CONFIG_RTL_8196D) || defined(CONFIG_RTL_8196E) || (defined(CONFIG_RTL_8197D) && !defined(CONFIG_PORT0_EXT_GIGA))
+#if 0 //defined(CONFIG_RTL_8196D) || defined(CONFIG_RTL_8197DL) || defined(CONFIG_RTL_8196E) || (defined(CONFIG_RTL_8197D) && !defined(CONFIG_PORT0_EXT_GIGA))
RTL_W32(EDCA_BE_PARA, ((BE_TXOP*priv->pshare->txop_enlarge) << 16) |
(5 << 12) | (4 << 8) | (sifs_time + 2 * slot_time));
#else
@@ -2806,7 +3502,10 @@ void IOT_EDCA_switch(struct rtl8192cd_priv *priv, int mode, char enable)
#else
// is intel client, use a different edca value
- RTL_W32(EDCA_BE_PARA, (txop << 16) | (cw_max << 12) | (4 << 8) | 0x1f);
+ if (get_rf_mimo_mode(priv) == MIMO_1T1R)
+ RTL_W32(EDCA_BE_PARA, (BE_TXOP*2 << 16) | (6 << 12) | (5 << 8) | 0x1f);
+ else
+ RTL_W32(EDCA_BE_PARA, (txop << 16) | (cw_max << 12) | (4 << 8) | 0x1f);
} else {
txop = (txop_close ? 0: (BE_TXOP*priv->pshare->txop_enlarge));
@@ -2821,11 +3520,15 @@ void IOT_EDCA_switch(struct rtl8192cd_priv *priv, int mode, char enable)
#ifdef LOW_TP_TXOP
RTL_W32(EDCA_BE_PARA, (txop << 16) | (cw_max << 12) | (4 << 8) | (sifs_time + 3 * slot_time));
#else
-#if defined(CONFIG_RTL_8196D) || defined(CONFIG_RTL_8196E) || (defined(CONFIG_RTL_8197D) && !defined(CONFIG_PORT0_EXT_GIGA))
+#if defined(CONFIG_RTL_8196D) || defined(CONFIG_RTL_8197DL) || defined(CONFIG_RTL_8196E) || (defined(CONFIG_RTL_8197D) && !defined(CONFIG_PORT0_EXT_GIGA))
RTL_W32(EDCA_BE_PARA, (BE_TXOP*2 << 16) | (6 << 12) | (5 << 8) | (sifs_time + 3 * slot_time));
#else
RTL_W32(EDCA_BE_PARA, (BE_TXOP*2 << 16) | (6 << 12) | (4 << 8) | (sifs_time + 3 * slot_time));
#endif
+ if (priv->pshare->txop_enlarge == 0xe)
+ RTL_W16(RD_CTRL, RTL_R16(RD_CTRL) & ~(DIS_TXOP_CFE));
+ else
+ RTL_W16(RD_CTRL, RTL_R16(RD_CTRL) | DIS_TXOP_CFE);
#endif
}
/*
@@ -2838,6 +3541,8 @@ void IOT_EDCA_switch(struct rtl8192cd_priv *priv, int mode, char enable)
}
}
+
+#if 0
void check_NAV_prot_len(struct rtl8192cd_priv *priv, struct stat_info *pstat, unsigned int disassoc)
{
if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat
@@ -2899,11 +3604,13 @@ void check_NAV_prot_len(struct rtl8192cd_priv *priv, struct stat_info *pstat, un
}
}
#endif
+#endif
//3 ============================================================
//3 FA statistic functions
//3 ============================================================
+#if 0
#if !defined(CONFIG_RTL_NEW_AUTOCH)
static
@@ -2931,7 +3638,9 @@ void reset_FA_reg(struct rtl8192cd_priv *priv)
RTL_W8(TXPAUSE, 0x00);
#endif
#else
+#ifdef INTERFERENCE_CONTROL
unsigned char value8;
+#endif
/* cck CCA */
PHY_SetBBReg(priv, 0xa2c, BIT(13) | BIT(12), 0);
@@ -3055,11 +3764,18 @@ void FA_statistic(struct rtl8192cd_priv *priv)
priv->pshare->cck_FA_cnt = RTL_R8(0xa5b);
priv->pshare->cck_FA_cnt = priv->pshare->cck_FA_cnt << 8;
priv->pshare->cck_FA_cnt += RTL_R8(0xa5c);
+#ifdef INTERFERENCE_CONTROL
+ priv->pshare->ofdm_FA_total_cnt = (unsigned int) priv->pshare->ofdm_FA_cnt1 +
+ priv->pshare->ofdm_FA_cnt2 + priv->pshare->ofdm_FA_cnt3 +
+ priv->pshare->ofdm_FA_cnt4 + RTL_R16(0xcf0) + RTL_R16(0xcf2);
+
+ priv->pshare->FA_total_cnt = priv->pshare->ofdm_FA_total_cnt + priv->pshare->cck_FA_cnt;
+#else
priv->pshare->FA_total_cnt = priv->pshare->ofdm_FA_cnt1 + priv->pshare->ofdm_FA_cnt2 +
priv->pshare->ofdm_FA_cnt3 + priv->pshare->ofdm_FA_cnt4 +
priv->pshare->cck_FA_cnt + RTL_R16(0xcf0) + RTL_R16(0xcf2);
-
+#endif
if (priv->pshare->rf_ft_var.rssi_dump)
priv->pshare->CCA_total_cnt = ((RTL_R8(0xa60)<<8)|RTL_R8(0xa61)) + RTL_R16(0xda0);
#else
@@ -3116,7 +3832,7 @@ void FA_statistic(struct rtl8192cd_priv *priv)
PHY_SetBBReg(priv, 0x870, bMaskDWord, 0x07000700);
if (!timer_pending(&priv->dnc_timer)) {
//printk("... Start Check Noise ...\n");
- mod_timer(&priv->dnc_timer, jiffies + 10); // 100 ms
+ mod_timer(&priv->dnc_timer, jiffies + RTL_MILISECONDS_TO_JIFFIES(100)); // 100 ms
}
}
}
@@ -3199,11 +3915,15 @@ void check_RA_by_rssi(struct rtl8192cd_priv *priv, struct stat_info *pstat)
} else
#endif
{
+#if defined(CONFIG_RTL_92D_SUPPORT) || defined(CONFIG_RTL_92C_SUPPORT)
add_update_RATid(priv, pstat);
+#endif
}
}
}
+#endif
+#if defined(CONFIG_RTL_92C_SUPPORT) || defined(CONFIG_RTL_92D_SUPPORT)
void check_txrate_by_reg(struct rtl8192cd_priv *priv, struct stat_info *pstat)
{
@@ -3251,8 +3971,7 @@ void check_txrate_by_reg(struct rtl8192cd_priv *priv, struct stat_info *pstat)
&& !((OPMODE & WIFI_AP_STATE) && priv->pmib->dot11nConfigEntry.dot11nCoexist &&
(priv->bg_ap_timeout || priv->force_20_sta || priv->switch_20_sta
#ifdef CONFIG_RTL_88E_SUPPORT
- || (GET_CHIP_VER(priv) == VERSION_8188E)?(priv->force_20_sta_88e_hw_ext
- || priv->switch_20_sta_88e_hw_ext):(0)
+ || ((GET_CHIP_VER(priv) == VERSION_8188E)?(priv->force_20_sta_88e_hw_ext || priv->switch_20_sta_88e_hw_ext):0)
#endif
#ifdef STA_EXT
|| priv->force_20_sta_ext || priv->switch_20_sta_ext
@@ -3286,7 +4005,8 @@ void check_txrate_by_reg(struct rtl8192cd_priv *priv, struct stat_info *pstat)
DEBUG_INFO("sta has no aid found to check current tx rate\n");
}
}
-
+#endif
+#if 0
void add_RATid(struct rtl8192cd_priv *priv, struct stat_info *pstat)
{
unsigned char limit=16;
@@ -3322,8 +4042,7 @@ void add_RATid(struct rtl8192cd_priv *priv, struct stat_info *pstat)
&& !((OPMODE & WIFI_AP_STATE) && priv->pmib->dot11nConfigEntry.dot11nCoexist &&
(priv->bg_ap_timeout || priv->force_20_sta || priv->switch_20_sta
#ifdef CONFIG_RTL_88E_SUPPORT
- || (GET_CHIP_VER(priv) == VERSION_8188E)?(priv->force_20_sta_88e_hw_ext
- || priv->switch_20_sta_88e_hw_ext):(0)
+ || ((GET_CHIP_VER(priv) == VERSION_8188E)?(priv->force_20_sta_88e_hw_ext || priv->switch_20_sta_88e_hw_ext):0)
#endif
#ifdef STA_EXT
|| priv->force_20_sta_ext || priv->switch_20_sta_ext
@@ -3486,6 +4205,7 @@ void add_RATid(struct rtl8192cd_priv *priv, struct stat_info *pstat)
#if defined(CONFIG_RTL_88E_SUPPORT) && defined(TXREPORT)
if (GET_CHIP_VER(priv)==VERSION_8188E) {
+#ifndef RATEADAPTIVE_BY_ODM
if (pstat->tx_ra_bitmap & 0xff000) {
if (priv->pshare->is_40m_bw)
priv->pshare->RaInfo[pstat->aid].RateID = ARFR_1T_40M;
@@ -3499,8 +4219,23 @@ void add_RATid(struct rtl8192cd_priv *priv, struct stat_info *pstat)
priv->pshare->RaInfo[pstat->aid].RateMask = pstat->tx_ra_bitmap;
ARFBRefresh(priv, &priv->pshare->RaInfo[pstat->aid]);
+#else
+ PODM_RA_INFO_T pRAInfo = &(ODMPTR->RAInfo[pstat->aid]);
+ if (pstat->tx_ra_bitmap & 0xff000) {
+ if (priv->pshare->is_40m_bw)
+ pRAInfo->RateID = ARFR_1T_40M;
+ else
+ pRAInfo->RateID = ARFR_1T_20M;
+ } else if (pstat->tx_ra_bitmap & 0xff0) {
+ pRAInfo->RateID = ARFR_BG_MIX;
+ } else {
+ pRAInfo->RateID = ARFR_B_ONLY;
+ }
+ ODM_RA_UpdateRateInfo_8188E(ODMPTR, pstat->aid, pRAInfo->RateID, pstat->tx_ra_bitmap, pRAInfo->RateSGI);
+#endif
} else
#endif
+#if defined(CONFIG_RTL_92C_SUPPORT) || defined(CONFIG_RTL_92D_SUPPORT)
{
#ifdef STA_EXT
if (REMAP_AID(pstat) < FW_NUM_STAT-1)
@@ -3581,9 +4316,11 @@ void add_RATid(struct rtl8192cd_priv *priv, struct stat_info *pstat)
#endif
}
}
+#endif
RESTORE_INT(flags);
}
+#endif
void set_rssi_cmd(struct rtl8192cd_priv *priv, struct stat_info *pstat)
{
@@ -3619,7 +4356,7 @@ void set_rssi_cmd(struct rtl8192cd_priv *priv, struct stat_info *pstat)
/*
* set macid
*/
- content |= pstat->aid << 8;
+ content |= REMAP_AID(pstat) << 8;
/*
* set cmd id
@@ -3631,8 +4368,13 @@ void set_rssi_cmd(struct rtl8192cd_priv *priv, struct stat_info *pstat)
RESTORE_INT(flags);
}
+#if defined(CONFIG_RTL_92D_SUPPORT) || defined(CONFIG_RTL_92C_SUPPORT)
+#ifdef __KERNEL__
void add_rssi_timer(unsigned long task_priv)
+#elif defined(__ECOS)
+void add_rssi_timer(void *task_priv)
+#endif
{
struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv;
struct stat_info *pstat = NULL;
@@ -3694,6 +4436,7 @@ void add_update_rssi(struct rtl8192cd_priv *priv, struct stat_info *pstat)
set_rssi_cmd(priv, pstat);
}
}
+#endif
void set_RATid_cmd(struct rtl8192cd_priv *priv, unsigned int macid, unsigned int rateid, unsigned int ratemask)
@@ -3736,10 +4479,12 @@ void set_RATid_cmd(struct rtl8192cd_priv *priv, unsigned int macid, unsigned int
signin_h2c_cmd(priv, content, ext_content);
}
+
+
//3 ============================================================
//3 EDCCA
//3 ============================================================
-
+#if 0
void check_EDCCA(struct rtl8192cd_priv *priv, short rssi)
{
if ((priv->pshare->rf_ft_var.edcca_thd) && (priv->pmib->dot11RFEntry.dot11channel==14
@@ -3761,7 +4506,7 @@ void check_EDCCA(struct rtl8192cd_priv *priv, short rssi)
priv->pshare->phw->EDCCA_on = 0;
}
}
-
+#endif
//3 ============================================================
//3 Antenna Diversity
@@ -4085,15 +4830,15 @@ void dm_SW_AntennaSwitch(struct rtl8192cd_priv *priv, char Step)
if(priv->pshare->TrafficLoad == TRAFFIC_HIGH) {
if(priv->pshare->DM_SWAT_Table.RSSI_Trying%2 == 0)
- mod_timer(&priv->pshare->swAntennaSwitchTimer, jiffies + 1); // 10 ms
+ mod_timer(&priv->pshare->swAntennaSwitchTimer, jiffies + RTL_MILISECONDS_TO_JIFFIES(10)); // 10 ms
else
- mod_timer(&priv->pshare->swAntennaSwitchTimer, jiffies + 8); // 80 ms
+ mod_timer(&priv->pshare->swAntennaSwitchTimer, jiffies + RTL_MILISECONDS_TO_JIFFIES(80)); // 80 ms
} else if(priv->pshare->TrafficLoad == TRAFFIC_LOW) {
if(priv->pshare->DM_SWAT_Table.RSSI_Trying%2 == 0)
- mod_timer(&priv->pshare->swAntennaSwitchTimer, jiffies + 4); // 40 ms
+ mod_timer(&priv->pshare->swAntennaSwitchTimer, jiffies + RTL_MILISECONDS_TO_JIFFIES(40)); // 40 ms
else
- mod_timer(&priv->pshare->swAntennaSwitchTimer, jiffies + 8); // 80 ms
+ mod_timer(&priv->pshare->swAntennaSwitchTimer, jiffies + RTL_MILISECONDS_TO_JIFFIES(80)); // 80 ms
}
}
@@ -4438,7 +5183,6 @@ int diversity_antenna_select(struct rtl8192cd_priv *priv, unsigned char *data)
RTL_W8(0xc58, RTL_R8(0xc58) | BIT(7)); // OFDM HW control
#endif
}
-
RTL_W8(0xa01, RTL_R8(0xa01) | BIT(7)); // CCK HW control
RTL_W32(0x80c, RTL_R32(0x80c) | BIT(21) ); // by tx desc
priv->pshare->rf_ft_var.CurAntenna = 0;
@@ -4548,6 +5292,9 @@ void DetectSTAExistance(struct rtl8192cd_priv *priv, struct tx_rpt *report, stru
const unsigned char TFRL_SetTime = 2; // Time to set Retry Limit (in second)
const unsigned char TFRL_RcvTime = 10; // Time to recover Retry Limit (in second)
+ if(OPMODE & WIFI_STATION_STATE)
+ return;
+
if( report->txok != 0 )
{ // Reset Counter
pstat->tx_conti_fail_cnt = 0;
@@ -4594,12 +5341,16 @@ void DetectSTAExistance(struct rtl8192cd_priv *priv, struct tx_rpt *report, stru
}
// Timer callback function to recover hardware retry limit register. Added by Annie, 2010-08-10.
+#ifdef __KERNEL__
void RetryLimitRecovery(unsigned long task_priv)
+#elif defined(__ECOS)
+void RetryLimitRecovery(void *task_priv)
+#endif
{
struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv;
if( priv->pshare->bRLShortened )
{
- RTL_W16(RL, (priv->pshare->RLShort&SRL_Mask)<<SRL_SHIFT|(priv->pshare->RLLong&LRL_Mask)<<LRL_SHIFT);
+ RTL_W16(RL, priv->pshare->RL_setting);
priv->pshare->bRLShortened = FALSE;
DEBUG_WARN( "== Recover RetryLimit to 0x%04X ==\n", RTL_R16(RL) );
}
@@ -4667,7 +5418,11 @@ void LeavingSTA_RLCheck(struct rtl8192cd_priv *priv)
AllOKTimes ++;
if( AllOKTimes >= TFRL_RcvTime )
+#ifdef __KERNEL__
RetryLimitRecovery((unsigned long)priv);
+#elif defined(__ECOS)
+ RetryLimitRecovery((void *)priv);
+#endif
}
else {
AllOKTimes = 0;
@@ -4676,5 +5431,4161 @@ void LeavingSTA_RLCheck(struct rtl8192cd_priv *priv)
#endif
+
+#ifdef CONFIG_RTL_92C_SUPPORT
+
+/*
+ * PA Analog Pre-distortion Calibration R06
+ */
+void APK_MAIN(struct rtl8192cd_priv *priv, unsigned int is2T)
+{
+ unsigned int regD[PATH_NUM];
+ unsigned int tmpReg, index, offset, path, i=0, pathbound = PATH_NUM, apkbound=6;
+ unsigned int BB_backup[APK_BB_REG_NUM];
+ unsigned int BB_REG[APK_BB_REG_NUM] = {0x904, 0xc04, 0x800, 0xc08, 0x874};
+ unsigned int BB_AP_MODE[APK_BB_REG_NUM] = {0x00000020, 0x00a05430, 0x02040000, 0x000800e4, 0x00204000};
+ unsigned int BB_normal_AP_MODE[APK_BB_REG_NUM] = {0x00000020, 0x00a05430, 0x02040000, 0x000800e4, 0x22204000};
+ unsigned int AFE_backup[APK_AFE_REG_NUM];
+ unsigned int AFE_REG[APK_AFE_REG_NUM] = { 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
+ 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec};
+ unsigned int MAC_backup[IQK_MAC_REG_NUM];
+ unsigned int MAC_REG[IQK_MAC_REG_NUM] = {0x522, 0x550, 0x551, 0x040};
+ unsigned int APK_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = {{0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c},
+ {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e}};
+ unsigned int APK_normal_RF_init_value[PATH_NUM][APK_BB_REG_NUM] =
+ { {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, //path settings equal to path b settings
+ {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} };
+
+ unsigned int APK_RF_value_0[PATH_NUM][APK_BB_REG_NUM] =
+ { {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d},
+ {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050}};
+
+ unsigned int APK_normal_RF_value_0[PATH_NUM][APK_BB_REG_NUM] =
+ { {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, //path settings equal to path b settings
+ {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} };
+
+ unsigned int AFE_on_off[PATH_NUM] = {0x04db25a4, 0x0b1b25a4}; //path A on path B off / path A off path B on
+ unsigned int APK_offset[PATH_NUM] = {0xb68, 0xb6c};
+ unsigned int APK_normal_offset[PATH_NUM] = {0xb28, 0xb98};
+ unsigned int APK_value[PATH_NUM] = {0x92fc0000, 0x12fc0000};
+ unsigned int APK_normal_value[PATH_NUM] = {0x92680000, 0x12680000};
+ char APK_delta_mapping[APK_BB_REG_NUM][13] = {{-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0}};
+ unsigned int APK_normal_setting_value_1[13] =
+ { 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28,
+ 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3,
+ 0x12680000, 0x00880000, 0x00880000 };
+ unsigned int APK_normal_setting_value_2[16] =
+ { 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3,
+ 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025,
+ 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008,
+ 0x00050006 };
+
+
+ unsigned int APK_normal_RF_init_value_old[PATH_NUM][APK_BB_REG_NUM] =
+ {{0x0852c, 0x5a52c, 0x0a52c, 0x5a52c, 0x4a52c}, //path settings equal to path b settings
+ {0x0852c, 0x5a52c, 0x0a52c, 0x5a52c, 0x4a52c}};
+ unsigned int APK_normal_RF_value_0_old[PATH_NUM][APK_BB_REG_NUM] =
+ {{0x52019, 0x52017, 0x52010, 0x5200d, 0x5200a}, //path settings equal to path b settings
+ {0x52019, 0x52017, 0x52010, 0x5200d, 0x5200a}};
+ unsigned int APK_normal_setting_value_1_old[13] =
+ {0x01017018, 0xf7ed8f84, 0x40372d20, 0x5b554e48, 0x6f6a6560,
+ 0x807c7873, 0x8f8b8884, 0x9d999693, 0xa9a6a3a0, 0xb5b2afac,
+ 0x12680000, 0x00880000, 0x00880000};
+ unsigned int APK_normal_setting_value_2_old[16] =
+ {0x00810100, 0x00400056, 0x002b0032, 0x001f0024, 0x0019001c,
+ 0x00150017, 0x00120013, 0x00100011, 0x000e000f, 0x000c000d,
+ 0x000b000c, 0x000a000b, 0x0009000a, 0x00090009, 0x00080008,
+ 0x00080008};
+ unsigned int AP_curve[PATH_NUM][APK_CURVE_REG_NUM];
+
+ unsigned int APK_result[PATH_NUM][APK_BB_REG_NUM]; //val_1_1a, val_1_2a, val_2a, val_3a, val_4a
+ unsigned int ThermalValue = 0;
+ int BB_offset, delta_V, delta_offset;
+ int newVerAPK = (IS_UMC_A_CUT_88C(priv)) ? 1 : 0;
+ unsigned int *pAPK_normal_setting_value_1 = APK_normal_setting_value_1, *pAPK_normal_setting_value_2 = APK_normal_setting_value_2 ;
+#ifdef HIGH_POWER_EXT_PA
+ unsigned int tmp0x870=0, tmp0x860=0, tmp0x864=0;
+
+ if(priv->pshare->rf_ft_var.use_ext_pa)
+ newVerAPK = 1;
+#endif
+
+ if(!newVerAPK) {
+ apkbound = 12;
+ pAPK_normal_setting_value_1 = APK_normal_setting_value_1_old;
+ pAPK_normal_setting_value_2 = APK_normal_setting_value_2_old;
+ }
+
+ if(!is2T)
+ pathbound = 1;
+
+ for(index = 0; index < PATH_NUM; index ++) {
+ APK_offset[index] = APK_normal_offset[index];
+ APK_value[index] = APK_normal_value[index];
+ AFE_on_off[index] = 0x6fdb25a4;
+ }
+
+ for(index = 0; index < APK_BB_REG_NUM; index ++) {
+ for(path = 0; path < pathbound; path++) {
+ if(newVerAPK) {
+ APK_RF_init_value[path][index] = APK_normal_RF_init_value[path][index];
+ APK_RF_value_0[path][index] = APK_normal_RF_value_0[path][index];
+ } else {
+ APK_RF_init_value[path][index] = APK_normal_RF_init_value_old[path][index];
+ APK_RF_value_0[path][index] = APK_normal_RF_value_0_old[path][index];
+ }
+
+ }
+ BB_AP_MODE[index] = BB_normal_AP_MODE[index];
+ }
+
+ /*
+ * save BB default value
+ */
+ for(index = 1; index < APK_BB_REG_NUM ; index++)
+ BB_backup[index] = PHY_QueryBBReg(priv, BB_REG[index], bMaskDWord);
+
+#ifdef HIGH_POWER_EXT_PA
+ if (priv->pshare->rf_ft_var.use_ext_pa) {
+ tmp0x870 = PHY_QueryBBReg(priv, 0x870, bMaskDWord);
+ tmp0x860 = PHY_QueryBBReg(priv, 0x860, bMaskDWord);
+ tmp0x864 = PHY_QueryBBReg(priv, 0x864, bMaskDWord);
+ }
+#endif
+
+ //save MAC default value
+ _PHY_SaveMACRegisters(priv, MAC_REG, MAC_backup);
+
+ //save AFE default value
+ _PHY_SaveADDARegisters(priv, AFE_REG, AFE_backup, APK_AFE_REG_NUM);
+
+ for(path = 0; path < pathbound; path++) {
+ /*
+ * save old AP curve
+ */
+ if(path == RF92CD_PATH_A) {
+ /*
+ * path A APK
+ * load APK setting
+ * path-A
+ */
+ offset = 0xb00;
+ for(index = 0; index < 11; index ++) {
+ PHY_SetBBReg(priv, offset, bMaskDWord, pAPK_normal_setting_value_1[index]);
+ offset += 0x04;
+ }
+ PHY_SetBBReg(priv, 0xb98, bMaskDWord, 0x12680000);
+
+ offset = 0xb68;
+ for(; index < 13; index ++) {
+ PHY_SetBBReg(priv, offset, bMaskDWord, pAPK_normal_setting_value_1[index]);
+ offset += 0x04;
+ }
+
+ /*
+ * page-B1
+ */
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x40000000);
+
+ /*
+ *path A
+ */
+ offset = 0xb00;
+ for(index = 0; index < 16; index++) {
+ PHY_SetBBReg(priv, offset, bMaskDWord, pAPK_normal_setting_value_2[index]);
+ offset += 0x04;
+ }
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x00000000);
+ } else if(path == RF92CD_PATH_B) {
+ /*
+ * path B APK
+ * load APK setting
+ * path-B
+ */
+ offset = 0xb70;
+ for(index = 0; index < 10; index ++) {
+ PHY_SetBBReg(priv, offset, bMaskDWord, pAPK_normal_setting_value_1[index]);
+ offset += 0x04;
+ }
+ PHY_SetBBReg(priv, 0xb28, bMaskDWord, 0x12680000);
+ PHY_SetBBReg(priv, 0xb98, bMaskDWord, 0x12680000);
+
+ offset = 0xb68;
+ index = 11;
+ for(; index < 13; index ++) {
+ //offset 0xb68, 0xb6c
+ PHY_SetBBReg(priv, offset, bMaskDWord, pAPK_normal_setting_value_1[index]);
+ offset += 0x04;
+ }
+
+ /*
+ * page-B1
+ */
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x40000000);
+
+ /*
+ * path B
+ */
+ offset = 0xb60;
+ for(index = 0; index < 16; index++) {
+ PHY_SetBBReg(priv, offset, bMaskDWord, pAPK_normal_setting_value_2[index]);
+ offset += 0x04;
+ }
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x00000000);
+ }
+
+ if(!newVerAPK) {
+ tmpReg = PHY_QueryRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0x3, bMaskDWord, 1);
+
+ AP_curve[path][0] = tmpReg & 0x1F; //[4:0]
+
+ tmpReg = PHY_QueryRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0x4, bMaskDWord, 1);
+ AP_curve[path][1] = (tmpReg & 0xF8000) >> 15; //[19:15]
+ AP_curve[path][2] = (tmpReg & 0x7C00) >> 10; //[14:10]
+ AP_curve[path][3] = (tmpReg & 0x3E0) >> 5; //[9:5]
+ }
+
+ /*
+ * save RF default value
+ */
+ regD[path] = PHY_QueryRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0xd, bMaskDWord, 1);
+
+ /*
+ * Path A AFE all on, path B AFE All off or vise versa
+ */
+ for(index = 0; index < APK_AFE_REG_NUM ; index++)
+ PHY_SetBBReg(priv, AFE_REG[index], bMaskDWord, AFE_on_off[path]);
+
+ /*
+ * BB to AP mode
+ */
+ if(path == RF92CD_PATH_A) {
+ for(index = 1; index < APK_BB_REG_NUM ; index++)
+ PHY_SetBBReg(priv, BB_REG[index], bMaskDWord, BB_AP_MODE[index]);
+ }
+
+#ifdef HIGH_POWER_EXT_PA
+ if (priv->pshare->rf_ft_var.use_ext_pa) {
+ PHY_SetBBReg(priv, 0x870, BIT(10), 1);
+ PHY_SetBBReg(priv, 0x870, BIT(26), 1);
+ PHY_SetBBReg(priv, 0x860, BIT(10), 0);
+ PHY_SetBBReg(priv, 0x864, BIT(10), 0);
+ }
+#endif
+
+ if(newVerAPK) {
+ if(path == RF92CD_PATH_A) {
+ PHY_SetBBReg(priv, 0xe30 , bMaskDWord, 0x01008c00);
+ PHY_SetBBReg(priv, 0xe34 , bMaskDWord, 0x01008c00);
+ } else if(path == RF92CD_PATH_B) {
+ PHY_SetBBReg(priv, 0xe50 , bMaskDWord, 0x01008c00);
+ PHY_SetBBReg(priv, 0xe54 , bMaskDWord, 0x01008c00);
+ }
+ }
+
+ //MAC settings
+ _PHY_MACSettingCalibration(priv, MAC_REG, MAC_backup);
+
+
+ if(path == RF92CD_PATH_A) {
+ //Path B to standby mode
+ PHY_SetRFReg(priv, RF92CD_PATH_B, 0x0, bMaskDWord, 0x10000);
+ } else {
+ //Path A to standby mode
+ PHY_SetRFReg(priv, RF92CD_PATH_A, 0x00, bMaskDWord, 0x10000);
+ PHY_SetRFReg(priv, RF92CD_PATH_A, 0x10, bMaskDWord, 0x1000f);
+ PHY_SetRFReg(priv, RF92CD_PATH_A, 0x11, bMaskDWord, 0x20103);
+ }
+
+ /*
+ * Check Thermal value delta
+ */
+ if (priv->pmib->dot11RFEntry.ther) {
+ ThermalValue = PHY_QueryRFReg(priv, RF92CD_PATH_A, 0x24, 0x1f, 1) & 0xff;
+ ThermalValue -= priv->pmib->dot11RFEntry.ther;
+ }
+
+ delta_offset = ((ThermalValue+14)/2);
+ if(delta_offset < 0)
+ delta_offset = 0;
+ else if (delta_offset > 12)
+ delta_offset = 12;
+
+ //AP calibration
+ for(index = 1; index < APK_BB_REG_NUM; index++) {
+ tmpReg = APK_RF_init_value[path][index];
+ if (priv->pmib->dot11RFEntry.ther) {
+ BB_offset = (tmpReg & 0xF0000) >> 16;
+
+ if(!(tmpReg & BIT(15))) //sign bit 0
+ BB_offset = -BB_offset;
+ delta_V = APK_delta_mapping[index][delta_offset];
+ BB_offset += delta_V;
+
+ if(BB_offset < 0) {
+ tmpReg = tmpReg & (~BIT(15));
+ BB_offset = -BB_offset;
+ } else {
+ tmpReg = tmpReg | BIT(15);
+ }
+ tmpReg = (tmpReg & 0xFFF0FFFF) | (BB_offset << 16);
+ }
+
+ if(newVerAPK)
+ PHY_SetRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0xc, bMaskDWord, 0x8992e);
+ else
+ PHY_SetRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0xc, bMaskDWord, 0x8992f);
+
+ PHY_SetRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0x0, bMaskDWord, APK_RF_value_0[path][index]);
+ PHY_SetRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0xd, bMaskDWord, tmpReg);
+
+ /*
+ * PA11+PAD01111, one shot
+ */
+ i = 0;
+ do {
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x80000000);
+ PHY_SetBBReg(priv, APK_offset[path], bMaskDWord, APK_value[0]);
+ delay_ms(3);
+ PHY_SetBBReg(priv, APK_offset[path], bMaskDWord, APK_value[1]);
+ delay_ms(20);
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x00000000);
+
+ if(!newVerAPK) {
+ tmpReg = PHY_QueryRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0xb, bMaskDWord, 1);
+ tmpReg = (tmpReg & 0x3E00) >> 9;
+ } else {
+ if(path == RF92CD_PATH_A)
+ tmpReg = PHY_QueryBBReg(priv, 0xbd8, 0x03E00000);
+ else
+ tmpReg = PHY_QueryBBReg(priv, 0xbd8, 0xF8000000);
+ }
+ i++;
+ } while((tmpReg > apkbound) && i < 4);
+
+ APK_result[path][index] = tmpReg;
+ }
+ }
+
+ /*
+ * reload MAC default value
+ */
+ _PHY_ReloadMACRegisters(priv, MAC_REG, MAC_backup);
+
+ /*
+ * reload BB default value
+ */
+ for(index = 1; index < APK_BB_REG_NUM ; index++)
+ PHY_SetBBReg(priv, BB_REG[index], bMaskDWord, BB_backup[index]);
+
+#ifdef HIGH_POWER_EXT_PA
+ if (priv->pshare->rf_ft_var.use_ext_pa) {
+ PHY_SetBBReg(priv, 0x870, bMaskDWord, tmp0x870);
+ PHY_SetBBReg(priv, 0x860, bMaskDWord, tmp0x860);
+ PHY_SetBBReg(priv, 0x864, bMaskDWord, tmp0x864);
+ }
+#endif
+
+ /*
+ * reload AFE default value
+ */
+ _PHY_ReloadADDARegisters(priv, AFE_REG, AFE_backup, 16);
+
+
+ /*
+ * reload RF path default value
+ */
+ for(path = 0; path < pathbound; path++) {
+ PHY_SetRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0xd, bMaskDWord, regD[path]);
+ if(path == RF92CD_PATH_B) {
+ PHY_SetRFReg(priv, RF92CD_PATH_A, 0x10, bMaskDWord, 0x1000f);
+ PHY_SetRFReg(priv, RF92CD_PATH_A, 0x11, bMaskDWord, 0x20101);
+ }
+
+ if(newVerAPK) {
+ if (APK_result[path][1] > 6)
+ APK_result[path][1] = 6;
+ } else {
+ if(APK_result[path][1] < 1)
+ APK_result[path][1] = 1;
+ else if (APK_result[path][1] > 5)
+ APK_result[path][1] = 5;
+
+ if(APK_result[path][2] < 2)
+ APK_result[path][2] = 2;
+ else if (APK_result[path][2] > 6)
+ APK_result[path][2] = 6;
+
+ if(APK_result[path][3] < 2)
+ APK_result[path][3] = 2;
+ else if (APK_result[path][3] > 6)
+ APK_result[path][3] = 6;
+
+ if(APK_result[path][4] < 5)
+ APK_result[path][4] = 5;
+ else if (APK_result[path][4] > 9)
+ APK_result[path][4] = 9;
+ }
+ }
+
+ for(path = 0; path < pathbound; path++) {
+ PHY_SetRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0x3, bMaskDWord,
+ ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (APK_result[path][1] << 5) | APK_result[path][1]));
+ if(newVerAPK) {
+ if(path == RF92CD_PATH_A)
+ PHY_SetRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0x4, bMaskDWord,
+ ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x00 << 5) | 0x05));
+ else
+ PHY_SetRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0x4, bMaskDWord,
+ ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x02 << 5) | 0x05));
+ PHY_SetRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0xe, bMaskDWord,
+ ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | 0x08));
+ } else {
+ PHY_SetRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0x4, bMaskDWord,
+ ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (APK_result[path][2] << 5) | APK_result[path][3]));
+ PHY_SetRFReg(priv, (RF92CD_RADIO_PATH_E)path, 0xe, bMaskDWord,
+ ((APK_result[path][4] << 15) | (APK_result[path][4] << 10) | (APK_result[path][4] << 5) | APK_result[path][4]));
+ }
+ }
+}
+
+
+
+/*
+return FALSE => do IQK again
+*/
+char _PHY_SimularityCompare(struct rtl8192cd_priv *priv, int result[][8], unsigned char c1, unsigned char c2)
+{
+ unsigned int i, j, diff, SimularityBitMap, bound = 0;
+ unsigned char final_candidate[2] = {0xFF, 0xFF}; //for path A and path B
+ char bResult = TRUE, is2T = (GET_CHIP_VER(priv) == VERSION_8192C ? 1 : 0);
+
+ bound = (is2T) ? 8 : 4;
+ SimularityBitMap = 0;
+
+ for( i = 0; i < bound; i++ ) {
+ diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] - result[c2][i]) : (result[c2][i] - result[c1][i]);
+ if (diff > MAX_TOLERANCE) {
+ if((i == 2 || i == 6) && !SimularityBitMap) {
+ if( result[c1][i]+ result[c1][i+1] == 0)
+ final_candidate[(i>>2)] = c2;
+ else if (result[c2][i]+result[c2][i+1] == 0)
+ final_candidate[(i>>2)] = c1;
+ else
+ SimularityBitMap |= (1<<i);
+ }
+ else
+ SimularityBitMap |= (1<<i);
+ }
+ }
+
+ if ( SimularityBitMap == 0) {
+ for( i = 0; i < (bound>>2); i++ ) {
+ if(final_candidate[i] != 0xFF) {
+ for( j = (i<<2); j < ((i+1)<<2)-2; j++)
+ result[3][j] = result[final_candidate[i]][j];
+ bResult = FALSE;
+ }
+ }
+ return bResult;
+ }
+ else if (!(SimularityBitMap & 0x03)) { //path A TX OK
+ for(i = 0; i < 2; i++)
+ result[3][i] = result[c1][i];
+ return FALSE;
+ }
+ else if (!(SimularityBitMap & 0x0c)) { //path A RX OK
+ for(i = 2; i < 4; i++)
+ result[3][i] = result[c1][i];
+ return FALSE;
+ }
+ else if (!(SimularityBitMap & 0x30) && is2T) { //path B TX OK
+ for(i = 4; i < 6; i++)
+ result[3][i] = result[c1][i];
+ return FALSE;
+ }
+ else if (!(SimularityBitMap & 0xc0) && is2T) { //path B RX OK
+ for(i = 6; i < 8; i++)
+ result[3][i] = result[c1][i];
+ return FALSE;
+ }
+ else
+ return FALSE;
+
+}
+
+
+//bit0 = 1 => Tx OK, bit1 = 1 => Rx OK
+unsigned char _PHY_PathA_IQK(struct rtl8192cd_priv *priv, char configPathB)
+{
+ unsigned int regEAC, regE94, regE9C, regEA4;
+ unsigned char result = 0x00;
+
+ //path-A IQK setting
+// RTPRINT(FINIT, INIT_IQK, ("Path-A IQK setting!\n"));
+ PHY_SetBBReg(priv, 0xe30, bMaskDWord, 0x10008c1f);
+ PHY_SetBBReg(priv, 0xe34, bMaskDWord, 0x10008c1f);
+ PHY_SetBBReg(priv, 0xe38, bMaskDWord, 0x82140102);
+ PHY_SetBBReg(priv, 0xe3c, bMaskDWord, ((configPathB |IS_UMC_B_CUT_88C(priv)) ? 0x28160202 : 0x28160502));
+
+#if 1
+ //path-B IQK setting
+ if(configPathB) {
+ PHY_SetBBReg(priv, 0xe50, bMaskDWord, 0x10008c22);
+ PHY_SetBBReg(priv, 0xe54, bMaskDWord, 0x10008c22);
+ PHY_SetBBReg(priv, 0xe58, bMaskDWord, 0x82140102);
+ PHY_SetBBReg(priv, 0xe5c, bMaskDWord, 0x28160202);
+ }
+#endif
+ //LO calibration setting
+ PHY_SetBBReg(priv, 0xe4c, bMaskDWord, 0x001028d1);
+
+ //One shot, path A LOK & IQK
+ PHY_SetBBReg(priv, 0xe48, bMaskDWord, 0xf9000000);
+ PHY_SetBBReg(priv, 0xe48, bMaskDWord, 0xf8000000);
+
+ // delay x ms
+ delay_ms(IQK_DELAY_TIME);
+
+ // Check failed
+ regEAC = PHY_QueryBBReg(priv, 0xeac, bMaskDWord);
+ regE94 = PHY_QueryBBReg(priv, 0xe94, bMaskDWord);
+ regE9C= PHY_QueryBBReg(priv, 0xe9c, bMaskDWord);
+ regEA4= PHY_QueryBBReg(priv, 0xea4, bMaskDWord);
+
+ if(!(regEAC & BIT(28)) &&
+ (((regE94 & 0x03FF0000)>>16) != 0x142) &&
+ (((regE9C & 0x03FF0000)>>16) != 0x42) )
+ result |= 0x01;
+ else //if Tx not OK, ignore Rx
+ return result;
+
+ if(!(regEAC & BIT(27)) && //if Tx is OK, check whether Rx is OK
+ (((regEA4 & 0x03FF0000)>>16) != 0x132) &&
+ (((regEAC & 0x03FF0000)>>16) != 0x36))
+ result |= 0x02;
+ else {
+// RTPRINT(FINIT, INIT_IQK, ("Path A Rx IQK fail!!\n"));
+ }
+
+ return result;
+}
+
+//bit0 = 1 => Tx OK, bit1 = 1 => Rx OK
+unsigned char _PHY_PathB_IQK(struct rtl8192cd_priv *priv)
+{
+ unsigned int regEAC, regEB4, regEBC, regEC4, regECC;
+ unsigned char result = 0x00;
+#if 0
+ //path-B IQK setting
+ RTPRINT(FINIT, INIT_IQK, ("Path-B IQK setting!\n"));
+ PHY_SetBBReg(pAdapter, 0xe50, bMaskDWord, 0x10008c22);
+ PHY_SetBBReg(pAdapter, 0xe54, bMaskDWord, 0x10008c22);
+ PHY_SetBBReg(pAdapter, 0xe58, bMaskDWord, 0x82140102);
+ PHY_SetBBReg(pAdapter, 0xe5c, bMaskDWord, 0x28160202);
+
+ //LO calibration setting
+ RTPRINT(FINIT, INIT_IQK, ("LO calibration setting!\n"));
+ PHY_SetBBReg(pAdapter, 0xe4c, bMaskDWord, 0x001028d1);
+#endif
+ //One shot, path B LOK & IQK
+// RTPRINT(FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n"));
+ PHY_SetBBReg(priv, 0xe60, bMaskDWord, 0x00000002);
+ PHY_SetBBReg(priv, 0xe60, bMaskDWord, 0x00000000);
+
+ // delay x ms
+ delay_ms(IQK_DELAY_TIME);
+
+ // Check failed
+ regEAC = PHY_QueryBBReg(priv, 0xeac, bMaskDWord);
+ regEB4 = PHY_QueryBBReg(priv, 0xeb4, bMaskDWord);
+ regEBC= PHY_QueryBBReg(priv, 0xebc, bMaskDWord);
+ regEC4= PHY_QueryBBReg(priv, 0xec4, bMaskDWord);
+ regECC= PHY_QueryBBReg(priv, 0xecc, bMaskDWord);
+
+ if(!(regEAC & BIT(31)) &&
+ (((regEB4 & 0x03FF0000)>>16) != 0x142) &&
+ (((regEBC & 0x03FF0000)>>16) != 0x42))
+ result |= 0x01;
+ else
+ return result;
+
+ if(!(regEAC & BIT(30)) &&
+ (((regEC4 & 0x03FF0000)>>16) != 0x132) &&
+ (((regECC & 0x03FF0000)>>16) != 0x36))
+ result |= 0x02;
+ else {
+// RTPRINT(FINIT, INIT_IQK, ("Path B Rx IQK fail!!\n"));
+ }
+
+ return result;
+
+}
+
+void _PHY_PathAFillIQKMatrix(struct rtl8192cd_priv *priv, char bIQKOK, int result[][8], unsigned char final_candidate, char bTxOnly)
+{
+ int Oldval_0, X, TX0_A, reg;
+ int Y, TX0_C;
+
+ if(final_candidate == 0xFF)
+ return;
+
+ else if(bIQKOK) {
+ Oldval_0 = (PHY_QueryBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
+
+ X = result[final_candidate][0];
+ if ((X & 0x00000200) != 0)
+ X = X | 0xFFFFFC00;
+ TX0_A = (X * Oldval_0) >> 8;
+ PHY_SetBBReg(priv, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A);
+ PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(31), ((X* Oldval_0>>7) & 0x1));
+
+ Y = result[final_candidate][1];
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+ TX0_C = (Y * Oldval_0) >> 8;
+ PHY_SetBBReg(priv, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C&0x3C0)>>6));
+ PHY_SetBBReg(priv, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C&0x3F));
+ PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(29), ((Y* Oldval_0>>7) & 0x1));
+
+ if(bTxOnly) {
+// RTPRINT(FINIT, INIT_IQK, ("_PHY_PathAFillIQKMatrix only Tx OK\n"));
+ return;
+ }
+
+ reg = result[final_candidate][2];
+ PHY_SetBBReg(priv, rOFDM0_XARxIQImbalance, 0x3FF, reg);
+
+ reg = result[final_candidate][3] & 0x3F;
+ PHY_SetBBReg(priv, rOFDM0_XARxIQImbalance, 0xFC00, reg);
+
+ reg = (result[final_candidate][3] >> 6) & 0xF;
+ PHY_SetBBReg(priv, 0xca0, 0xF0000000, reg);
+ }
+}
+
+
+void _PHY_PathBFillIQKMatrix(struct rtl8192cd_priv *priv, char bIQKOK, int result[][8], unsigned char final_candidate, char bTxOnly)
+{
+ int Oldval_1, X, TX1_A, reg;
+ int Y, TX1_C;
+
+ //RTPRINT(FINIT, INIT_IQK, ("Path B IQ Calibration %s !\n",(bIQKOK)?"Success":"Failed"));
+
+ if(final_candidate == 0xFF)
+ return;
+
+ else if(bIQKOK)
+ {
+ Oldval_1 = (PHY_QueryBBReg(priv, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
+
+ X = result[final_candidate][4];
+ if ((X & 0x00000200) != 0)
+ X = X | 0xFFFFFC00;
+ TX1_A = (X * Oldval_1) >> 8;
+ PHY_SetBBReg(priv, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A);
+ PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(27), ((X* Oldval_1>>7) & 0x1));
+
+ Y = result[final_candidate][5];
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+ TX1_C = (Y * Oldval_1) >> 8;
+ PHY_SetBBReg(priv, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C&0x3C0)>>6));
+ PHY_SetBBReg(priv, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C&0x3F));
+ PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(25), ((Y* Oldval_1>>7) & 0x1));
+
+ if(bTxOnly)
+ return;
+
+ reg = result[final_candidate][6];
+ PHY_SetBBReg(priv, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
+
+ reg = result[final_candidate][7] & 0x3F;
+ PHY_SetBBReg(priv, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
+
+ reg = (result[final_candidate][7] >> 6) & 0xF;
+ PHY_SetBBReg(priv, rOFDM0_AGCRSSITable, 0x0000F000, reg);
+ }
+}
+
+void _PHY_PathAStandBy(struct rtl8192cd_priv *priv)
+{
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x0);
+ PHY_SetBBReg(priv, 0x840, bMaskDWord, 0x00010000);
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x80800000);
+}
+
+void _PHY_IQCalibrate(struct rtl8192cd_priv *priv, int result[][8], unsigned char t, char is2T)
+{
+ unsigned int i;
+ unsigned char PathAOK, PathBOK;
+ unsigned int ADDA_REG[IQK_ADDA_REG_NUM] = { 0x85c, 0xe6c, 0xe70, 0xe74,
+ 0xe78, 0xe7c, 0xe80, 0xe84,
+ 0xe88, 0xe8c, 0xed0, 0xed4,
+ 0xed8, 0xedc, 0xee0, 0xeec };
+ unsigned int IQK_MAC_REG[IQK_MAC_REG_NUM] = {0x522, 0x550, 0x551, 0x040};
+
+ char isNormal = IS_TEST_CHIP(priv) ? 0 : 1;
+ unsigned int retryCount = 2;
+
+#ifdef MP_TEST
+ if(priv->pshare->rf_ft_var.mp_specific)
+ retryCount = 9;
+#endif
+
+ if(t==0) {
+ // Save ADDA parameters, turn Path A ADDA on
+ _PHY_SaveADDARegisters(priv, ADDA_REG, priv->pshare->ADDA_backup, APK_AFE_REG_NUM);
+ _PHY_SaveMACRegisters(priv, IQK_MAC_REG, priv->pshare->IQK_MAC_backup);
+ }
+
+ _PHY_PathADDAOn(priv, ADDA_REG, TRUE, is2T);
+
+ if(t==0) {
+ // Store 0xC04, 0xC08, 0x874 vale
+ priv->pshare->RegC04 = PHY_QueryBBReg(priv, 0xc04, bMaskDWord);
+ priv->pshare->RegC08 = PHY_QueryBBReg(priv, 0xc08, bMaskDWord);
+ priv->pshare->Reg874 = PHY_QueryBBReg(priv, 0x874, bMaskDWord);
+ }
+
+ PHY_SetBBReg(priv, 0x800, bMaskDWord, (PHY_QueryBBReg(priv, 0x800, bMaskDWord)& ~ BIT(24)));
+ PHY_SetBBReg(priv, 0xc04, bMaskDWord, 0x03a05600);
+ PHY_SetBBReg(priv, 0xc08, bMaskDWord, 0x000800e4);
+ PHY_SetBBReg(priv, 0x874, bMaskDWord, 0x22204000);
+
+ PHY_SetBBReg(priv, 0x870, BIT(10), 1);
+ PHY_SetBBReg(priv, 0x870, BIT(26), 1);
+ PHY_SetBBReg(priv, 0x860, BIT(10), 0);
+ PHY_SetBBReg(priv, 0x864, BIT(10), 0);
+
+ if(is2T) {
+ PHY_SetBBReg(priv, 0x840, bMaskDWord, 0x00010000);
+ PHY_SetBBReg(priv, 0x844, bMaskDWord, 0x00010000);
+ }
+
+ //MAC settings
+ _PHY_MACSettingCalibration(priv, IQK_MAC_REG, priv->pshare->IQK_MAC_backup);
+
+ //Page B init
+ if(isNormal)
+ PHY_SetBBReg(priv, 0xb68, bMaskDWord, 0x00080000);
+ else
+ PHY_SetBBReg(priv, 0xb68, bMaskDWord, 0x0f600000);
+
+ if(is2T) {
+ if(isNormal)
+ PHY_SetBBReg(priv, 0xb6c, bMaskDWord, 0x00080000);
+ else
+ PHY_SetBBReg(priv, 0xb6c, bMaskDWord, 0x0f600000);
+ }
+
+ // IQ calibration setting
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x80800000);
+ PHY_SetBBReg(priv, 0xe40, bMaskDWord, 0x01007c00);
+ PHY_SetBBReg(priv, 0xe44, bMaskDWord, 0x01004800);
+
+ for(i = 0 ; i < retryCount ; i++){
+ PathAOK = _PHY_PathA_IQK(priv, is2T);
+ if(PathAOK == 0x03){
+ result[t][0] = (PHY_QueryBBReg(priv, 0xe94, bMaskDWord)&0x3FF0000)>>16;
+ result[t][1] = (PHY_QueryBBReg(priv, 0xe9c, bMaskDWord)&0x3FF0000)>>16;
+ result[t][2] = (PHY_QueryBBReg(priv, 0xea4, bMaskDWord)&0x3FF0000)>>16;
+ result[t][3] = (PHY_QueryBBReg(priv, 0xeac, bMaskDWord)&0x3FF0000)>>16;
+ break;
+ }
+ else if (i == (retryCount-1) && PathAOK == 0x01) //Tx IQK OK
+ {
+ result[t][0] = (PHY_QueryBBReg(priv, 0xe94, bMaskDWord)&0x3FF0000)>>16;
+ result[t][1] = (PHY_QueryBBReg(priv, 0xe9c, bMaskDWord)&0x3FF0000)>>16;
+ }
+ }
+
+ if(0x00 == PathAOK){
+// RTPRINT(FINIT, INIT_IQK, ("Path A IQK failed!!\n"));
+ }
+
+ if(is2T){
+ _PHY_PathAStandBy(priv);
+
+ // Turn Path B ADDA on
+ _PHY_PathADDAOn(priv, ADDA_REG, FALSE, is2T);
+
+ for(i = 0 ; i < retryCount ; i++){
+ PathBOK = _PHY_PathB_IQK(priv);
+ if(PathBOK == 0x03){
+// RTPRINT(FINIT, INIT_IQK, ("Path B IQK Success!!\n"));
+ result[t][4] = (PHY_QueryBBReg(priv, 0xeb4, bMaskDWord)&0x3FF0000)>>16;
+ result[t][5] = (PHY_QueryBBReg(priv, 0xebc, bMaskDWord)&0x3FF0000)>>16;
+ result[t][6] = (PHY_QueryBBReg(priv, 0xec4, bMaskDWord)&0x3FF0000)>>16;
+ result[t][7] = (PHY_QueryBBReg(priv, 0xecc, bMaskDWord)&0x3FF0000)>>16;
+ break;
+ }
+ else if (i == (retryCount - 1) && PathBOK == 0x01) //Tx IQK OK
+ {
+// RTPRINT(FINIT, INIT_IQK, ("Path B Only Tx IQK Success!!\n"));
+ result[t][4] = (PHY_QueryBBReg(priv, 0xeb4, bMaskDWord)&0x3FF0000)>>16;
+ result[t][5] = (PHY_QueryBBReg(priv, 0xebc, bMaskDWord)&0x3FF0000)>>16;
+ }
+ }
+
+ if(0x00 == PathBOK){
+// RTPRINT(FINIT, INIT_IQK, ("Path B IQK failed!!\n"));
+ }
+ }
+
+ //Back to BB mode, load original value
+// RTPRINT(FINIT, INIT_IQK, ("IQK:Back to BB mode, load original value!\n"));
+ PHY_SetBBReg(priv, 0xc04, bMaskDWord, priv->pshare->RegC04);
+ PHY_SetBBReg(priv, 0x874, bMaskDWord, priv->pshare->Reg874);
+ PHY_SetBBReg(priv, 0xc08, bMaskDWord, priv->pshare->RegC08);
+
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0);
+
+ // Restore RX initial gain
+ PHY_SetBBReg(priv, 0x840, bMaskDWord, 0x00032ed3);
+
+ if(is2T)
+ PHY_SetBBReg(priv, 0x844, bMaskDWord, 0x00032ed3);
+
+ if(t!=0) {
+ // Reload ADDA power saving parameters
+ _PHY_ReloadADDARegisters(priv, ADDA_REG, priv->pshare->ADDA_backup, 16);
+
+ // Reload MAC parameters
+ _PHY_ReloadMACRegisters(priv, IQK_MAC_REG, priv->pshare->IQK_MAC_backup);
+ }
+}
+
+
+void PHY_IQCalibrate_92C(struct rtl8192cd_priv *priv)
+{
+ int result[4][8]; //last is final result
+ unsigned char i, final_candidate;
+ char bPathAOK, bPathBOK;
+ int RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC, RegTmp = 0;
+ char is12simular, is13simular, is23simular;
+ unsigned int temp_870, temp_860, temp_864, temp_800;
+
+#ifdef MP_TEST
+ if (!priv->pshare->rf_ft_var.mp_specific)
+#endif
+ {
+ if (priv->pshare->iqk_2g_done)
+ return;
+ priv->pshare->iqk_2g_done = 1;
+ }
+
+ temp_870 = PHY_QueryBBReg(priv, 0x870, bMaskDWord);
+ temp_860 = PHY_QueryBBReg(priv, 0x860, bMaskDWord);
+ temp_864 = PHY_QueryBBReg(priv, 0x864, bMaskDWord);
+ temp_800 = PHY_QueryBBReg(priv, 0x800, bMaskDWord);
+
+ memset(result, 0, sizeof(result));
+
+ final_candidate = 0xff;
+ bPathAOK = FALSE;
+ bPathBOK = FALSE;
+ is12simular = FALSE;
+ is23simular = FALSE;
+ is13simular = FALSE;
+
+ for (i=0; i<3; i++) {
+ _PHY_IQCalibrate(priv, result, i, (GET_CHIP_VER(priv) == VERSION_8192C ? 1 : 0));
+
+ if(i == 1) {
+ is12simular = _PHY_SimularityCompare(priv, result, 0, 1);
+ if(is12simular) {
+ final_candidate = 0;
+ break;
+ }
+ }
+
+ if(i == 2) {
+ is13simular = _PHY_SimularityCompare(priv, result, 0, 2);
+ if(is13simular) {
+ final_candidate = 0;
+ break;
+ }
+
+ is23simular = _PHY_SimularityCompare(priv, result, 1, 2);
+ if(is23simular)
+ final_candidate = 1;
+ else
+ {
+ for(i = 0; i < 8; i++)
+ RegTmp += result[3][i];
+
+ if(RegTmp != 0)
+ final_candidate = 3;
+ else
+ final_candidate = 0xFF;
+ }
+ }
+ }
+
+
+ RTL_W32(0x870, temp_870);
+ RTL_W32(0x860, temp_860);
+ RTL_W32(0x864, temp_864);
+ RTL_W32(0x800, temp_800);
+
+ //load 0xe30 IQC default value
+ if(GET_CHIP_VER(priv) == VERSION_8188C) {
+ RTL_W32(0xe30, 0x01008c00);
+ RTL_W32(0xe34, 0x01008c00);
+ }
+
+ for (i=0; i<4; i++) {
+ RegE94 = result[i][0];
+ RegE9C = result[i][1];
+ RegEA4 = result[i][2];
+ RegEAC = result[i][3];
+ RegEB4 = result[i][4];
+ RegEBC = result[i][5];
+ RegEC4 = result[i][6];
+ RegECC = result[i][7];
+ DEBUG_INFO("IQK: RegE94=%lx RegE9C=%lx RegEA4=%lx RegEAC=%lx RegEB4=%lx RegEBC=%lx RegEC4=%lx RegECC=%lx\n ", RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC);
+ }
+
+ if(final_candidate != 0xff) {
+ priv->pshare->RegE94 = RegE94 = result[final_candidate][0];
+ priv->pshare->RegE9C = RegE9C = result[final_candidate][1];
+ RegEA4 = result[final_candidate][2];
+ RegEAC = result[final_candidate][3];
+ priv->pshare->RegEB4 = RegEB4 = result[final_candidate][4];
+ priv->pshare->RegEBC = RegEBC = result[final_candidate][5];
+ RegEC4 = result[final_candidate][6];
+ RegECC = result[final_candidate][7];
+ DEBUG_INFO ("IQK: final_candidate is %x\n",final_candidate);
+ DEBUG_INFO ("IQK: RegE94=%lx RegE9C=%lx RegEA4=%lx RegEAC=%lx RegEB4=%lx RegEBC=%lx RegEC4=%lx RegECC=%lx\n ", RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC);
+ bPathAOK = bPathBOK = TRUE;
+ }
+ else {
+ priv->pshare->RegE94 = priv->pshare->RegEB4 = 0x100; //X default value
+ priv->pshare->RegE9C = priv->pshare->RegEBC = 0x0; //Y default value
+ }
+
+ if((RegE94 != 0)/*&&(RegEA4 != 0)*/)
+ _PHY_PathAFillIQKMatrix(priv, bPathAOK, result, final_candidate, (RegEA4 == 0)? 1 :0);
+ if(GET_CHIP_VER(priv) == VERSION_8192C){
+ if((RegEB4 != 0)/*&&(RegEC4 != 0)*/)
+ _PHY_PathBFillIQKMatrix(priv, bPathBOK, result, final_candidate, (RegEC4 == 0)? 1 :0);
+ }
+}
+
+#endif
+
+
+// 92d IQK
+#ifdef CONFIG_RTL_92D_SUPPORT
+void IQK_92D_5G_n(struct rtl8192cd_priv *priv)
+{
+ unsigned int temp_800, temp_c04, temp_874, temp_c08, temp_870,
+ temp_860, temp_864, temp_88c, temp_c50, temp_c58, temp_b30,
+ switch2PI=0, X, reg; //Oldval_0, Oldval_1, TX0_A, TX1_A;
+ u8 temp_522, temp_550, temp_551;
+ unsigned int cal_num=0, cal_retry=0, ADDA_backup[IQK_ADDA_REG_NUM];
+ int Y, result[8][3], result_final[8]={0,0,0,0,0,0,0,0}; //TX0_C, TX1_C;
+
+ unsigned int i, RX0REG0xe40[3], RX0REG0xe40_final=0, REG0xe40, REG0xe94, REG0xe9c, delay_count;
+ unsigned int REG0xeac, RX1REG0xe40[3], RX1REG0xe40_final=0, REG0xeb4, REG0xea4,REG0xec4;
+ unsigned char TX0IQKOK = FALSE, TX1IQKOK = FALSE;
+ unsigned int TX_X0, TX_Y0, TX_X1, TX_Y1, RX_X0, RX_Y0, RX_X1, RX_Y1;
+ unsigned int ADDA_REG[IQK_ADDA_REG_NUM] = {0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
+ 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec};
+#ifdef CONFIG_RTL_92D_DMDP
+ if (priv->pmib->dot11RFEntry.macPhyMode == DUALMAC_DUALPHY)
+ return IQK_92D_5G_phy0_n(priv);
+#endif
+
+ //always do IQK for MP mode
+#ifdef MP_TEST
+ if (!priv->pshare->rf_ft_var.mp_specific)
#endif
+ {
+ if (priv->pmib->dot11RFEntry.macPhyMode == SINGLEMAC_SINGLEPHY) {
+ if (priv->pshare->iqk_5g_done)
+ return;
+ priv->pshare->iqk_5g_done = 1;
+ }
+ }
+
+ printk(">> %s \n",__FUNCTION__);
+#if defined(CONFIG_RTL_8198) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
+ REG32(BSP_WDTCNR) |= 1 << 23;
+#elif defined(CONFIG_RTL_8198B)
+ REG32(BSP_WDTCNTRR) |= BSP_WDT_KICK;
+#endif
+ /*
+ * Save MAC default value
+ */
+ temp_522 = RTL_R8(0x522);
+ temp_550 = RTL_R8(0x550);
+ temp_551 = RTL_R8(0x551);
+
+ /*
+ * Save BB Parameter
+ */
+ temp_800 = RTL_R32(0x800);
+ temp_c04 = RTL_R32(0xc04);
+ temp_874 = RTL_R32(0x874);
+ temp_c08 = RTL_R32(0xc08);
+ temp_870 = RTL_R32(0x870);
+ temp_860 = RTL_R32(0x860);
+ temp_864 = RTL_R32(0x864);
+ temp_88c = RTL_R32(0x88c);
+ temp_c50 = RTL_R32(0xc50); // 01/11/2011 update
+ temp_c58 = RTL_R32(0xc58); // 01/11/2011 update
+ temp_b30 = RTL_R32(0xb30); // 03/03/2011 update
+
+ /*
+ * Save AFE Parameters
+ */
+ for( i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ ADDA_backup[i] = RTL_R32(ADDA_REG[i]);
+
+ /*
+ * ==============
+ * Path-A TX/RX IQK
+ * ==============
+ */
+ while (cal_num < 3) {
+ /*
+ * Path-A AFE all on
+ */
+ for( i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ RTL_W32(ADDA_REG[i], 0x04db25a4);
+
+ /*
+ * MAC register setting
+ */
+ RTL_W8(0x522, 0x3f);
+ RTL_W8(0x550, RTL_R8(0x550)& (~BIT(3)));
+ RTL_W8(0x551, RTL_R8(0x551)& (~BIT(3)));
+
+ /*
+ * IQK must be done in PI mode
+ */
+ if (!PHY_QueryBBReg(priv, 0x820, BIT(8)) || !PHY_QueryBBReg(priv, 0x828, BIT(8))) {
+ PHY_SetBBReg(priv, 0x820, bMaskDWord, 0x01000100);
+ PHY_SetBBReg(priv, 0x828, bMaskDWord, 0x01000100);
+ switch2PI++;
+ }
+
+ /*
+ * BB setting
+ */
+ PHY_SetBBReg(priv, 0x800, BIT(24), 0);
+ PHY_SetBBReg(priv, 0xc04, bMaskDWord, 0x03a05600);
+ PHY_SetBBReg(priv, 0xc08, bMaskDWord, 0x000800e4);
+ PHY_SetBBReg(priv, 0x874, bMaskDWord, 0x22208000);
+ PHY_SetBBReg(priv, 0x88c, BIT(23)|BIT(22)|BIT(21)|BIT(20), 0xf);
+ PHY_SetBBReg(priv, 0xb30, bMaskDWord, 0x00a00000); // 03/03/2011 update
+
+ /*
+ * AP or IQK
+ */
+ //PHY_SetBBReg(priv, 0xb68, bMaskDWord, 0x0f600000);
+ //PHY_SetBBReg(priv, 0xb6c, bMaskDWord, 0x0f600000);
+
+ // IQK-R03 2011/02/16 update
+
+ //path A AP setting for IQK
+ PHY_SetBBReg(priv, 0xb00, bMaskDWord, 0);
+ PHY_SetBBReg(priv, 0xb68, bMaskDWord, 0x20000000);
+ //path B AP setting for IQK
+ PHY_SetBBReg(priv, 0xb70, bMaskDWord, 0);
+ PHY_SetBBReg(priv, 0xb6c, bMaskDWord, 0x20000000);
+
+ /*
+ * IQK global setting
+ */
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x80800000);
+ PHY_SetBBReg(priv, 0xe40, bMaskDWord, 0x10007c00);
+ PHY_SetBBReg(priv, 0xe44, bMaskDWord, 0x01004800);
+
+ /*
+ * path-A IQK setting
+ */
+ PHY_SetBBReg(priv, 0xe30, bMaskDWord, 0x18008c1f);
+ PHY_SetBBReg(priv, 0xe34, bMaskDWord, 0x18008c1f);
+ PHY_SetBBReg(priv, 0xe38, bMaskDWord, 0x82140307); // 01/11/2011 update
+#ifdef USB_POWER_SUPPORT
+ PHY_SetBBReg(priv, 0xe3c, bMaskDWord, 0x68160c66);
+#else
+ PHY_SetBBReg(priv, 0xe3c, bMaskDWord, 0x68160960); // 01/11/2011 update
+#endif
+
+ /*
+ * path-B IQK setting
+ */
+ PHY_SetBBReg(priv, 0xe50, bMaskDWord, 0x18008c2f);
+ PHY_SetBBReg(priv, 0xe54, bMaskDWord, 0x18008c2f);
+ PHY_SetBBReg(priv, 0xe58, bMaskDWord, 0x82110000);
+ PHY_SetBBReg(priv, 0xe5c, bMaskDWord, 0x68110000);
+
+ /*
+ * LO calibration setting
+ */
+ PHY_SetBBReg(priv, 0xe4c, bMaskDWord, 0x00462911);
+
+#ifdef USB_POWER_SUPPORT
+ // path-A TRSW setting
+ PHY_SetBBReg(priv, 0x870, BIT(6)|BIT(5), 3);
+ PHY_SetBBReg(priv, 0x860, BIT(6)|BIT(5), 3);
+#else
+ /*
+ * path-A PA on
+ */
+ /*
+ PHY_SetBBReg(priv, 0x870, BIT(11)|BIT(10), 3);
+ PHY_SetBBReg(priv, 0x870, BIT(6)|BIT(5), 3);
+ PHY_SetBBReg(priv, 0x860, BIT(11)|BIT(10), 3);
+ */
+ PHY_SetBBReg(priv, 0x870, bMaskDWord, 0x07000f60); // 01/11/2011 update
+ PHY_SetBBReg(priv, 0x860, bMaskDWord, 0x66e60e30); // 01/11/2011 update
+#endif
+ /*
+ * One shot, path A LOK & IQK
+ */
+ PHY_SetBBReg(priv, 0xe48, bMaskDWord, 0xf9000000);
+ PHY_SetBBReg(priv, 0xe48, bMaskDWord, 0xf8000000);
+
+ /*
+ * Delay 10 ms
+ */
+ delay_ms(10);
+
+ delay_count = 0;
+ while (1){
+ REG0xeac = PHY_QueryBBReg(priv, 0xeac, bMaskDWord);
+ if ((REG0xeac&BIT(26))||(delay_count>20)){
+ break;
+ }else {
+ delay_ms(1);
+ delay_count++;
+ }
+ }
+ /*
+ * Check_TX_IQK_A_result
+ */
+ REG0xe40 = PHY_QueryBBReg(priv, 0xe40, bMaskDWord);
+ REG0xe94 = PHY_QueryBBReg(priv, 0xe94, bMaskDWord);
+ if(((REG0xeac&BIT(28)) == 0) && (((REG0xe94&0x3FF0000)>>16)!=0x142)) {
+ TX0IQKOK = TRUE;
+ REG0xe9c = PHY_QueryBBReg(priv, 0xe9c, bMaskDWord);
+ TX_X0 = (PHY_QueryBBReg(priv, 0xe94, bMaskDWord)&0x3FF0000)>>16;
+ TX_Y0 = (PHY_QueryBBReg(priv, 0xe9c, bMaskDWord)&0x3FF0000)>>16;
+ RX0REG0xe40[cal_num] = (REG0xe40 & 0xfc00fc00) | (TX_X0<<16) | TX_Y0;
+ DEBUG_INFO("TX_X0 %08x TX_Y0 %08x RX0REG0xe40 %08x\n", TX_X0, TX_Y0, RX0REG0xe40[cal_num]);
+ result[0][cal_num] = TX_X0;
+ result[1][cal_num] = TX_Y0;
+ } else {
+ TX0IQKOK = FALSE;
+ if (++cal_retry >= 10) {
+ printk("%s Path-A Tx/Rx Check\n",__FUNCTION__);
+ break;
+ }
+ }
+
+ /*
+ * Check_RX_IQK_A_result
+ */
+ if(TX0IQKOK == TRUE) {
+ REG0xeac = PHY_QueryBBReg(priv, 0xeac, bMaskDWord);
+ REG0xea4 = PHY_QueryBBReg(priv, 0xea4, bMaskDWord);
+ if(((REG0xeac&BIT(27)) == 0) && (((REG0xea4&0x3FF0000)>>16)!=0x132)) {
+ RX_X0 = (PHY_QueryBBReg(priv, 0xea4, bMaskDWord)&0x3FF0000)>>16;
+ RX_Y0 = (PHY_QueryBBReg(priv, 0xeac, bMaskDWord)&0x3FF0000)>>16;
+ DEBUG_INFO("RX_X0 %08x RX_Y0 %08x\n", RX_X0, RX_Y0);
+ result[2][cal_num] = RX_X0;
+ result[3][cal_num] = RX_Y0;
+ cal_num++;
+ } else {
+ PHY_SetBBReg(priv, 0xc14, bMaskDWord, 0x40000100);
+ PHY_SetBBReg(priv, 0xe34, bMaskDWord, 0x19008c00);
+ if (++cal_retry >= 10) {
+ printk("%s Path-A Tx/Rx Check\n",__FUNCTION__);
+ break;
+ }
+ }
+ }
+ }
+
+ if (cal_num == 3) {
+ result_final[0] = get_mean_of_2_close_value(result[0]);
+ result_final[1] = get_mean_of_2_close_value(result[1]);
+ result_final[2] = get_mean_of_2_close_value(result[2]);
+ result_final[3] = get_mean_of_2_close_value(result[3]);
+ RX0REG0xe40_final = 0x80000000 | get_mean_of_2_close_value(RX0REG0xe40);
+
+ priv->pshare->RegE94=result_final[0];
+ priv->pshare->RegE9C=result_final[1];
+ } else {
+ priv->pshare->RegE94=0x100;
+ priv->pshare->RegE9C=0x00;
+ }
+
+ /*
+ * Path-A PA off
+ */
+ PHY_SetBBReg(priv, 0x870, bMaskDWord, temp_870);
+ PHY_SetBBReg(priv, 0x860, bMaskDWord, temp_860);
+
+
+ /*
+ * ==============
+ * Path-B TX/RX IQK
+ * ==============
+ */
+ cal_num = cal_retry = 0;
+ while (cal_num < 3) {
+ /*
+ * Path-B AFE all on
+ */
+ for( i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ PHY_SetBBReg(priv, ADDA_REG[i], bMaskDWord, 0x0b1b25a4);
+
+ /*
+ * path-A IQK setting
+ */
+ PHY_SetBBReg(priv, 0xe30, bMaskDWord, 0x18008c1f);
+ PHY_SetBBReg(priv, 0xe34, bMaskDWord, 0x18008c1f);
+ PHY_SetBBReg(priv, 0xe38, bMaskDWord, 0x82110000);
+ PHY_SetBBReg(priv, 0xe3c, bMaskDWord, 0x68110000);
+
+ /*
+ * path-B IQK setting
+ */
+ PHY_SetBBReg(priv, 0xe50, bMaskDWord, 0x18008c22);
+ PHY_SetBBReg(priv, 0xe54, bMaskDWord, 0x18008c22);
+ PHY_SetBBReg(priv, 0xe58, bMaskDWord, 0x82140307); // 01/11/2011 update
+
+ // 01/11/2011 update
+#ifdef USB_POWER_SUPPORT
+ PHY_SetBBReg(priv, 0xe5c, bMaskDWord, 0x68160c66);
+#else
+ PHY_SetBBReg(priv, 0xe5c, bMaskDWord, 0x68160960); // 01/11/2011 update
+#endif
+
+ /*
+ * LO calibration setting
+ */
+ PHY_SetBBReg(priv, 0xe4c, bMaskDWord, 0x00462911);
+
+#ifdef USB_POWER_SUPPORT
+ PHY_SetBBReg(priv, 0x870, BIT(22)|BIT(21), 3);
+ PHY_SetBBReg(priv, 0x864, BIT(6)|BIT(5), 3);
+#else
+ /*
+ * path-B PA on
+ */
+ /*
+ PHY_SetBBReg(priv, 0x870, BIT(27)|BIT(26), 3);
+ PHY_SetBBReg(priv, 0x870, BIT(22)|BIT(21), 3);
+ PHY_SetBBReg(priv, 0x864, BIT(11)|BIT(10), 3);
+ */
+ PHY_SetBBReg(priv, 0x870, bMaskDWord, 0x0f600700);
+ PHY_SetBBReg(priv, 0x864, bMaskDWord, 0x061f0d30);
+#endif
+
+ /*
+ * One shot, path A LOK & IQK
+ */
+ PHY_SetBBReg(priv, 0xe60, bMaskDWord, 0x00000002);
+ PHY_SetBBReg(priv, 0xe60, bMaskDWord, 0x00000000);
+
+ /*
+ * Delay 10 ms
+ */
+ delay_ms(10);
+
+ delay_count = 0;
+ while (1){
+ REG0xeac = PHY_QueryBBReg(priv, 0xeac, bMaskDWord);
+ if ((REG0xeac&BIT(29))||(delay_count>20)){
+ break;
+ }else {
+ delay_ms(1);
+ delay_count++;
+ }
+ }
+ /*
+ * Check_TX_IQK_B_result
+ */
+ REG0xe40 = PHY_QueryBBReg(priv, 0xe40, bMaskDWord);
+ REG0xeac = PHY_QueryBBReg(priv, 0xeac, bMaskDWord);
+ REG0xeb4 = PHY_QueryBBReg(priv, 0xeb4, bMaskDWord);
+ if(((REG0xeac&BIT(31)) == 0) && ((REG0xeb4&0x3FF0000)!=0x142)) {
+ TX1IQKOK = TRUE;
+ TX_X1 = (PHY_QueryBBReg(priv, 0xeb4, bMaskDWord)&0x3FF0000)>>16;
+ TX_Y1 = (PHY_QueryBBReg(priv, 0xebc, bMaskDWord)&0x3FF0000)>>16;
+ RX1REG0xe40[cal_num] = (REG0xe40 & 0xfc00fc00) | (TX_X1<<16) | TX_Y1;
+ DEBUG_INFO("TX_X1 %08x TX_Y1 %08x RX1REG0xe40 %08x\n", TX_X1, TX_Y1, RX1REG0xe40[cal_num]);
+ result[4][cal_num] = TX_X1;
+ result[5][cal_num] = TX_Y1;
+ } else {
+ TX1IQKOK = FALSE;
+ if (++cal_retry >= 10) {
+ printk("%s Path-B Tx/Rx Check\n",__FUNCTION__);
+ break;
+ }
+ }
+
+ /*
+ * Check_RX_IQK_B_result
+ */
+ if(TX1IQKOK == TRUE) {
+ REG0xeac = PHY_QueryBBReg(priv, 0xeac, bMaskDWord);
+ REG0xec4 = PHY_QueryBBReg(priv, 0xec4, bMaskDWord);
+ if(((REG0xeac&BIT(30)) == 0) && (((REG0xec4&0x3FF0000)>>16)!=0x132)) {
+ RX_X1 = (PHY_QueryBBReg(priv, 0xec4, bMaskDWord)&0x3FF0000)>>16;
+ RX_Y1 = (PHY_QueryBBReg(priv, 0xecc, bMaskDWord)&0x3FF0000)>>16;
+ DEBUG_INFO("RX_X1 %08x RX_Y1 %08x\n", RX_X1, RX_Y1);
+ result[6][cal_num] = RX_X1;
+ result[7][cal_num] = RX_Y1;
+ cal_num++;
+ } else {
+ PHY_SetBBReg(priv, 0xc1c, bMaskDWord, 0x40000100);
+ PHY_SetBBReg(priv, 0xe54, bMaskDWord, 0x19008c00);
+ if (++cal_retry >= 10) {
+ printk("%s Path-B Tx/Rx Check\n",__FUNCTION__);
+ break;
+ }
+ }
+ }
+ }
+
+ if (cal_num == 3) {
+ result_final[4] = get_mean_of_2_close_value(result[4]);
+ result_final[5] = get_mean_of_2_close_value(result[5]);
+ result_final[6] = get_mean_of_2_close_value(result[6]);
+ result_final[7] = get_mean_of_2_close_value(result[7]);
+ RX1REG0xe40_final = 0x80000000 | get_mean_of_2_close_value(RX1REG0xe40);
+
+ priv->pshare->RegEB4=result_final[4];
+ priv->pshare->RegEBC=result_final[5];
+ } else {
+ priv->pshare->RegEB4=0x100;
+ priv->pshare->RegEBC=0x00;
+ }
+
+ /*
+ * Fill IQK result for Path A
+ */
+ if (result_final[0]) {
+ /*
+ Oldval_0 = (PHY_QueryBBReg(priv, 0xc80, bMaskDWord) >> 22) & 0x3FF;
+ X = result_final[0];
+ if ((X & 0x00000200) != 0)
+ X = X | 0xFFFFFC00;
+ TX0_A = (X * Oldval_0) >> 8;
+ PHY_SetBBReg(priv, 0xc80, 0x3FF, TX0_A);
+ PHY_SetBBReg(priv, 0xc4c, BIT(24), ((X* Oldval_0>>7) & 0x1));
+
+ Y = result_final[1];
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+ TX0_C = (Y * Oldval_0) >> 8;
+ PHY_SetBBReg(priv, 0xc94, 0xF0000000, ((TX0_C&0x3C0)>>6));
+ PHY_SetBBReg(priv, 0xc80, 0x003F0000, (TX0_C&0x3F));
+ PHY_SetBBReg(priv, 0xc4c, BIT(26), ((Y* Oldval_0>>7) & 0x1));
+ */
+
+ // IQK-R03 2011/02/16 update
+ X = result_final[0];
+ Y = result_final[1];
+ //printk("X=%x Y=%x\n",X,Y);
+ //Path-A OFDM_A
+ PHY_SetBBReg(priv, 0xe30, 0x03FF0000, X);
+ PHY_SetBBReg(priv, 0xc4c, BIT(24), 0);
+ //Path-A OFDM_C
+ PHY_SetBBReg(priv, 0xe30, 0x000003FF, Y);
+ PHY_SetBBReg(priv, 0xc4c, BIT(26), 0);
+
+ if(result_final[2]) {
+ reg = result_final[2];
+ PHY_SetBBReg(priv, 0xc14, 0x3FF, reg);
+ reg = result_final[3] & 0x3F;
+ PHY_SetBBReg(priv, 0xc14, 0xFC00, reg);
+
+ reg = (result_final[3] >> 6) & 0xF;
+ PHY_SetBBReg(priv, 0xca0, 0xF0000000, reg);
+
+ PHY_SetBBReg(priv, 0xe34, 0x03FF0000, result_final[2]); // X
+ PHY_SetBBReg(priv, 0xe34, 0x3FF, result_final[3]); //Y
+ }
+ }
+
+ /*
+ * Fill IQK result for Path B
+ */
+ if (result_final[4]) {
+ /*
+ Oldval_1 = (PHY_QueryBBReg(priv, 0xc88, bMaskDWord) >> 22) & 0x3FF;
+
+ X = result_final[4];
+ if ((X & 0x00000200) != 0)
+ X = X | 0xFFFFFC00;
+ TX1_A = (X * Oldval_1) >> 8;
+ PHY_SetBBReg(priv, 0xc88, 0x3FF, TX1_A);
+ PHY_SetBBReg(priv, 0xc4c, BIT(28), ((X* Oldval_1>>7) & 0x1));
+
+ Y = result_final[5];
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+ TX1_C = (Y * Oldval_1) >> 8;
+ PHY_SetBBReg(priv, 0xc9c, 0xF0000000, ((TX1_C&0x3C0)>>6));
+ PHY_SetBBReg(priv, 0xc88, 0x003F0000, (TX1_C&0x3F));
+ PHY_SetBBReg(priv, 0xc4c, BIT(30), ((Y* Oldval_1>>7) & 0x1));
+ */
+
+ // IQK-R03 2011/02/16 update
+ X = result_final[4];
+ Y = result_final[5];
+ //printk("X=%x Y=%x\n",X,Y);
+ //Path-A OFDM_A
+ PHY_SetBBReg(priv, 0xe50, 0x03FF0000, X);
+ PHY_SetBBReg(priv, 0xc4c, BIT(28), 0);
+ //Path-A OFDM_C
+ PHY_SetBBReg(priv, 0xe50, 0x000003FF, Y);
+ PHY_SetBBReg(priv, 0xc4c, BIT(30), 0);
+
+ if(result_final[6]) {
+ reg = result_final[6];
+ PHY_SetBBReg(priv, 0xc1c, 0x3FF, reg);
+
+ reg = result_final[7] & 0x3F;
+ PHY_SetBBReg(priv, 0xc1c, 0xFC00, reg);
+
+ reg = (result_final[7] >> 6) & 0xF;
+ PHY_SetBBReg(priv, 0xc78, 0x0000F000, reg);
+
+ PHY_SetBBReg(priv, 0xe54, 0x03FF0000, result_final[6]); // X
+ PHY_SetBBReg(priv, 0xe54, 0x3FF, result_final[7]); //Y
+ }
+ }
+
+ /*
+ * Path B PA off
+ */
+ PHY_SetBBReg(priv, 0x870, bMaskDWord, temp_870);
+ PHY_SetBBReg(priv, 0x864, bMaskDWord, temp_864);
+
+ /*
+ * Exit IQK mode
+ */
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0);
+ PHY_SetBBReg(priv, 0xc04, bMaskDWord, temp_c04);
+ PHY_SetBBReg(priv, 0xc08, bMaskDWord, temp_c08);
+ PHY_SetBBReg(priv, 0x874, bMaskDWord, temp_874);
+ PHY_SetBBReg(priv, 0x800, bMaskDWord, temp_800);
+ PHY_SetBBReg(priv, 0x88c, bMaskDWord, temp_88c);
+ PHY_SetBBReg(priv, 0xb30, bMaskDWord, temp_b30); // 03/03/2011 update
+ //PHY_SetBBReg(priv, 0x840, bMaskDWord, 0x00032fff); // 01/11/2011 update
+ //PHY_SetBBReg(priv, 0x844, bMaskDWord, 0x00032fff); // 01/11/2011 update
+
+ // IQK-R03 2011/02/16 update
+ //path A IQ path to DP block
+ PHY_SetBBReg(priv, 0xb00, bMaskDWord, 0x010170b8);
+ //path B IQ path to DP block
+ PHY_SetBBReg(priv, 0xb70, bMaskDWord, 0x010170b8);
+
+ //path AB to initial gain
+ PHY_SetBBReg(priv, 0xc50, bMaskDWord, 0x50); // 01/11/2011 update
+ PHY_SetBBReg(priv, 0xc50, bMaskDWord, temp_c50); // 01/11/2011 update
+ PHY_SetBBReg(priv, 0xc58, bMaskDWord, 0x50); // 01/11/2011 update
+ PHY_SetBBReg(priv, 0xc58, bMaskDWord, temp_c58); // 01/11/2011 update
+
+
+ /*
+ * Reload MAC default value
+ */
+ RTL_W8(0x550, temp_550);
+ RTL_W8(0x551, temp_551);
+ RTL_W8(0x522, temp_522);
+
+ /*
+ * Switch back to SI if needed, after IQK
+ */
+ if (switch2PI) {
+ PHY_SetBBReg(priv, 0x820, bMaskDWord, 0x01000000);
+ PHY_SetBBReg(priv, 0x828, bMaskDWord, 0x01000000);
+ }
+
+ /*
+ * Reload ADDA power saving parameters
+ */
+ for(i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ PHY_SetBBReg(priv, ADDA_REG[i], bMaskDWord, ADDA_backup[i]);
+
+
+#if 0 //def CLIENT_MODE
+ clnt_save_IQK_res(priv);
+#endif
+
+}
+
+
+void IQK_92D_2G(struct rtl8192cd_priv *priv)
+{
+ unsigned int cal_num=0, cal_retry=0, Oldval=0, temp_c04=0, temp_c08=0, temp_874=0, temp_eac;
+ unsigned int cal_e94, cal_e9c, cal_ea4, cal_eac, cal_eb4, cal_ebc, cal_ec4, cal_ecc;
+ unsigned int X, Y, val_e94[3], val_e9c[3], val_ea4[3], val_eac[3], val_eb4[3], val_ebc[3], val_ec4[3], val_ecc[3];
+ unsigned int ADDA_REG[IQK_ADDA_REG_NUM] = {0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
+ 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec};
+ unsigned int ADDA_backup[IQK_ADDA_REG_NUM], i;
+ u8 temp_522, temp_550, temp_551;
+ u32 temp_040, temp_800, temp_870, temp_860, temp_864, temp_88c;
+ u8 switch2PI = 0;
+
+#ifdef CONFIG_RTL_92D_DMDP
+ if (priv->pmib->dot11RFEntry.macPhyMode == DUALMAC_DUALPHY)
+ return IQK_92D_2G_phy1(priv);
+#endif
+
+ //always do IQK for MP mode
+#ifdef MP_TEST
+ if (!priv->pshare->rf_ft_var.mp_specific)
+#endif
+ {
+ if (priv->pmib->dot11RFEntry.macPhyMode == SINGLEMAC_SINGLEPHY) {
+ if (priv->pshare->iqk_2g_done)
+ return;
+ priv->pshare->iqk_2g_done = 1;
+ }
+ }
+
+ printk(">> %s \n",__FUNCTION__);
+
+ // Save ADDA power saving parameters
+ for( i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ ADDA_backup[i] = RTL_R32(ADDA_REG[i]);
+
+ /*
+ * Save MAC default value
+ */
+ temp_522 = RTL_R8(0x522);
+ temp_550 = RTL_R8(0x550);
+ temp_551 = RTL_R8(0x551);
+ temp_040 = RTL_R32(0x40);
+
+ // Save BB default
+ temp_800 = RTL_R32(0x800);
+ temp_870 = RTL_R32(0x870);
+ temp_860 = RTL_R32(0x860);
+ temp_864 = RTL_R32(0x864);
+ temp_88c = RTL_R32(0x88c);
+
+ // Path-A ADDA all on
+ for( i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ RTL_W32(ADDA_REG[i], 0x04db25a4);
+
+ // IQ&LO calibration Setting
+ //IQK must be done in PI mode
+ if (!PHY_QueryBBReg(priv, 0x820, BIT(8)) || !PHY_QueryBBReg(priv, 0x828, BIT(8))) {
+ PHY_SetBBReg(priv, 0x820, bMaskDWord, 0x01000100);
+ PHY_SetBBReg(priv, 0x828, bMaskDWord, 0x01000100);
+ switch2PI++;
+ }
+
+ //BB setting
+ temp_c04 = RTL_R32(0xc04);
+ temp_c08 = RTL_R32(0xc08);
+ temp_874 = RTL_R32(0x874);
+ PHY_SetBBReg(priv,0x800,BIT(24),0);
+ RTL_W32(0xc04, 0x03a05600);
+ RTL_W32(0xc08, 0x000800e4);
+ RTL_W32(0x874, 0x22204000);
+
+ PHY_SetBBReg(priv, 0x870, BIT(10), 1);
+ PHY_SetBBReg(priv, 0x870, BIT(26), 1);
+ PHY_SetBBReg(priv, 0x860, BIT(10), 0);
+ PHY_SetBBReg(priv, 0x864, BIT(10), 0);
+
+ PHY_SetBBReg(priv,0x88c,0x00f00000,0xf);
+ RTL_W32(0x840, 0x00010000);
+ RTL_W32(0x844, 0x00010000);
+
+ //MAC register setting
+ RTL_W8(0x522, 0x3f);
+ RTL_W8(0x550, RTL_R8(0x550)& (~BIT(3)));
+ RTL_W8(0x551, RTL_R8(0x551)& (~BIT(3)));
+ RTL_W32(0x40, 0);
+
+ //AP or IQK
+ RTL_W32(0xb68 , 0x0f600000);
+ RTL_W32(0xb6c , 0x0f600000);
+
+ // IQK setting
+ RTL_W32(0xe28, 0x80800000);
+ RTL_W32(0xe40, 0x01007c00);
+ RTL_W32(0xe44, 0x01004800);
+ // path-A IQK setting
+ RTL_W32(0xe30, 0x10008c1f);
+ RTL_W32(0xe34, 0x10008c1f);
+ RTL_W32(0xe38, 0x82140102);
+ RTL_W32(0xe3c, 0x28160206);
+ // path-B IQK setting
+ RTL_W32(0xe50, 0x10008c22);
+ RTL_W32(0xe54, 0x10008c22);
+ RTL_W32(0xe58, 0x82140102);
+ RTL_W32(0xe5c, 0x28160206);
+ // LO calibration setting
+ RTL_W32(0xe4c, 0x00462911);
+
+ // delay to ensure Path-A IQK success
+ delay_ms(10);
+
+ // step 4: One shot, path A LOK & IQK
+ while (cal_num < 3) {
+ // One shot, path A LOK & IQK
+ RTL_W32(0xe48, 0xf9000000);
+ RTL_W32(0xe48, 0xf8000000);
+ // delay 1ms
+ delay_ms(1);
+
+ // check fail bit and check abnormal condition, then fill BB IQ matrix
+ cal_e94 = (RTL_R32(0xe94) >> 16) & 0x3ff;
+ cal_e9c = (RTL_R32(0xe9c) >> 16) & 0x3ff;
+ cal_ea4 = (RTL_R32(0xea4) >> 16) & 0x3ff;
+ temp_eac = RTL_R32(0xeac);
+ cal_eac = (temp_eac >> 16) & 0x3ff;
+ if (!(temp_eac & BIT(28)) && !(temp_eac & BIT(27)) &&
+ (cal_e94 != 0x142) && (cal_e9c != 0x42) &&
+ (cal_ea4 != 0x132) && (cal_eac != 0x36)) {
+ val_e94[cal_num] = cal_e94;
+ val_e9c[cal_num] = cal_e9c;
+ val_ea4[cal_num] = cal_ea4;
+ val_eac[cal_num] = cal_eac;
+ cal_num++;
+ } else {
+ if (++cal_retry >= 10) {
+ printk("%s Path-A Check\n",__FUNCTION__);
+ break;
+ }
+ }
+ }
+
+ if (cal_num == 3) {
+ cal_e94 = get_mean_of_2_close_value(val_e94);
+ cal_e9c = get_mean_of_2_close_value(val_e9c);
+ cal_ea4 = get_mean_of_2_close_value(val_ea4);
+ cal_eac = get_mean_of_2_close_value(val_eac);
+
+ priv->pshare->RegE94=cal_e94;
+ priv->pshare->RegE9C=cal_e9c;
+
+ Oldval = (RTL_R32(0xc80) >> 22) & 0x3ff;
+
+ X = cal_e94;
+ PHY_SetBBReg(priv, 0xc80, 0x3ff, (X * Oldval)>>8);
+ PHY_SetBBReg(priv, 0xc4c, BIT(24), ((X * Oldval) >> 7) & 0x1);
+
+ Y = cal_e9c;
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+ PHY_SetBBReg(priv, 0xc94, 0xf0000000, (((Y * Oldval) >> 8) >> 6) & 0xf);
+ PHY_SetBBReg(priv, 0xc80, 0x003f0000, ((Y * Oldval) >> 8) & 0x3f);
+ PHY_SetBBReg(priv, 0xc4c, BIT(26), ((Y * Oldval) >> 7) & 0x1);
+
+ PHY_SetBBReg(priv, 0xc14, 0x3ff, cal_ea4);
+
+ PHY_SetBBReg(priv, 0xc14, 0xfc00, cal_eac & 0x3f);
+
+ PHY_SetBBReg(priv, 0xca0, 0xf0000000, (cal_eac >> 6) & 0xf);
+ }else {
+ priv->pshare->RegE94=0x100;
+ priv->pshare->RegE9C=0x00;
+ }
+
+ // step 5: Path-A standby mode
+ RTL_W32(0xe28, 0);
+ RTL_W32(0x840, 0x00010000);
+ RTL_W32(0xe28, 0x80800000);
+
+ // step 6: Path-B ADDA all on
+ for( i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ RTL_W32(ADDA_REG[i], 0x0b1b25a4);
+
+ // step 7: One shot, path B LOK & IQK
+ cal_num = 0;
+ cal_retry = 0;
+ while (cal_num < 3) {
+ // One shot, path B LOK & IQK
+ RTL_W32(0xe60, 2);
+ RTL_W32(0xe60, 0);
+ // delay 1ms
+ delay_ms(1);
+
+ // check fail bit and check abnormal condition, then fill BB IQ matrix
+ cal_eb4 = (RTL_R32(0xeb4) >> 16) & 0x3ff;
+ cal_ebc = (RTL_R32(0xebc) >> 16) & 0x3ff;
+ cal_ec4 = (RTL_R32(0xec4) >> 16) & 0x3ff;
+ cal_ecc = (RTL_R32(0xecc) >> 16) & 0x3ff;
+ temp_eac = RTL_R32(0xeac);
+ if (!(temp_eac & BIT(31)) && !(temp_eac & BIT(30)) &&
+ (cal_eb4 != 0x142) && (cal_ebc != 0x42) &&
+ (cal_ec4 != 0x132) && (cal_ecc != 0x36)) {
+ val_eb4[cal_num] = cal_eb4;
+ val_ebc[cal_num] = cal_ebc;
+ val_ec4[cal_num] = cal_ec4;
+ val_ecc[cal_num] = cal_ecc;
+ cal_num++;
+ } else {
+ if (++cal_retry >= 10) {
+ printk("%s Path-B Check\n",__FUNCTION__);
+ break;
+ }
+ }
+ }
+
+ if (cal_num == 3) {
+ cal_eb4 = get_mean_of_2_close_value(val_eb4);
+ cal_ebc = get_mean_of_2_close_value(val_ebc);
+ cal_ec4 = get_mean_of_2_close_value(val_ec4);
+ cal_ecc = get_mean_of_2_close_value(val_ecc);
+
+ priv->pshare->RegEB4=cal_eb4;
+ priv->pshare->RegEBC=cal_ebc;
+
+ Oldval = (RTL_R32(0xc88) >> 22) & 0x3ff;
+
+ X = cal_eb4;
+ PHY_SetBBReg(priv, 0xc88, 0x3ff, (X * Oldval) >> 8 );
+ PHY_SetBBReg(priv, 0xc4c, BIT(28), ((X * Oldval) >> 7) & 0x1);
+
+ Y = cal_ebc;
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+ PHY_SetBBReg(priv, 0xc9c, 0xf0000000, (((Y * Oldval) >> 8 ) >> 6) & 0xf);
+ PHY_SetBBReg(priv, 0xc88, 0x003f0000, ((Y * Oldval) >> 8 ) & 0x3f);
+ PHY_SetBBReg(priv, 0xc4c, BIT(30), ((Y * Oldval) >> 7) & 0x1);
+
+ PHY_SetBBReg(priv, 0xc1c, 0x3ff, cal_ec4);
+
+ PHY_SetBBReg(priv, 0xc1c, 0xfc00, cal_ecc & 0x3f);
+
+ PHY_SetBBReg(priv, 0xc78, 0xf000, (cal_ecc >> 6) & 0xf);
+ }else {
+ priv->pshare->RegEB4=0x100;
+ priv->pshare->RegEBC=0x00;
+ }
+
+ // step 8: back to BB mode, load original values
+ RTL_W32(0xe28, 0);
+ RTL_W32(0xc04, temp_c04);
+ RTL_W32(0xc08, temp_c08);
+ RTL_W32(0x874, temp_874);
+ RTL_W32(0x800, temp_800);
+ RTL_W32(0x88c, temp_88c);
+ RTL_W32(0x840, 0x32fff);
+ RTL_W32(0x844, 0x32fff);
+ RTL_W32(0x870, temp_870);
+ RTL_W32(0x860, temp_860);
+ RTL_W32(0x864, temp_864);
+
+ /*
+ * Switch back to SI if needed, after IQK
+ */
+ if (switch2PI) {
+ PHY_SetBBReg(priv, 0x820, bMaskDWord, 0x01000000);
+ PHY_SetBBReg(priv, 0x828, bMaskDWord, 0x01000000);
+ }
+
+#if defined(CONFIG_RTL_8198) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
+ REG32(BSP_WDTCNR) |= 1 << 23;
+#elif defined(CONFIG_RTL_8198B)
+ REG32(BSP_WDTCNTRR) |= BSP_WDT_KICK;
+#endif
+
+ /*
+ * Reload ADDA power saving parameters
+ */
+ for(i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ PHY_SetBBReg(priv, ADDA_REG[i], bMaskDWord, ADDA_backup[i]);
+
+ /*
+ * Reload MAC default value
+ */
+ RTL_W8(0x550, temp_550);
+ RTL_W8(0x551, temp_551);
+ RTL_W32(0x40, temp_040);
+ RTL_W8(0x522, temp_522);
+
+
+#if 0 //def CLIENT_MODE
+ clnt_save_IQK_res(priv);
+#endif
+
+}
+#ifdef CONFIG_RTL_92D_DMDP
+
+void IQK_92D_2G_phy1(struct rtl8192cd_priv *priv)
+{
+ unsigned int cal_num=0, cal_retry=0, Oldval=0, temp_c04=0, temp_c08=0, temp_874=0, temp_eac;
+ unsigned int cal_e94, cal_e9c, cal_ea4, cal_eac;
+ unsigned int X, Y, val_e94[3], val_e9c[3], val_ea4[3], val_eac[3];
+ unsigned int ADDA_REG[IQK_ADDA_REG_NUM] = {0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
+ 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec};
+ unsigned int ADDA_backup[IQK_ADDA_REG_NUM], i;
+ u8 temp_522, temp_550, temp_551;
+ u32 temp_040, temp_870, temp_860, temp_864, temp_800, temp_88c;
+ u8 switch2PI = 0;
+
+
+#ifdef MP_TEST
+ if (!priv->pshare->rf_ft_var.mp_specific)
+#endif
+ {
+ if (priv->pshare->iqk_2g_done)
+ return;
+ priv->pshare->iqk_2g_done = 1;
+ }
+
+ printk(">> %s \n",__FUNCTION__);
+
+ // Save ADDA power saving parameters
+ for( i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ ADDA_backup[i] = RTL_R32(ADDA_REG[i]);
+
+ /*
+ * Save MAC default value
+ */
+ temp_522 = RTL_R8(0x522);
+ temp_550 = RTL_R8(0x550);
+ temp_551 = RTL_R8(0x551);
+ temp_040 = RTL_R32(0x40);
+
+ // Save BB default
+ temp_800 = RTL_R32(0x800);
+ temp_870 = RTL_R32(0x870);
+ temp_860 = RTL_R32(0x860);
+ temp_864 = RTL_R32(0x864);
+ temp_88c = RTL_R32(0x88c);
+
+ // Path-A ADDA all on
+ for( i = 0 ; i < IQK_ADDA_REG_NUM ; i++) {
+#ifdef NON_INTR_ANTDIV
+ if (DMDP_PHY_QueryBBReg(0, 0xb30,BIT(27)))
+ RTL_W32(ADDA_REG[i], 0x04db25a4);
+ else
+#endif
+ RTL_W32(ADDA_REG[i], 0x0b1b25a4);
+ }
+
+
+ // IQ&LO calibration Setting
+
+ /*
+ * IQK must be done in PI mode
+ */
+ if (!PHY_QueryBBReg(priv, 0x820, BIT(8)) || !PHY_QueryBBReg(priv, 0x828, BIT(8))) {
+ PHY_SetBBReg(priv, 0x820, bMaskDWord, 0x01000100);
+ PHY_SetBBReg(priv, 0x828, bMaskDWord, 0x01000100);
+ switch2PI++;
+ }
+
+ //BB setting
+ temp_c04 = RTL_R32(0xc04);
+ temp_c08 = RTL_R32(0xc08);
+ temp_874 = RTL_R32(0x874);
+ PHY_SetBBReg(priv, 0x800, BIT(24), 0);
+ RTL_W32(0xc04, 0x03a05600);
+ RTL_W32(0xc08, 0x000800e4);
+ RTL_W32(0x874, 0x22204000);
+
+ PHY_SetBBReg(priv, 0x870, BIT(10), 1);
+ PHY_SetBBReg(priv, 0x870, BIT(26), 1);
+ PHY_SetBBReg(priv, 0x860, BIT(10), 0);
+ PHY_SetBBReg(priv, 0x864, BIT(10), 0);
+
+ PHY_SetBBReg(priv,0x88c,0x00f00000,0xf);
+
+ RTL_W32(0x840, 0x00010000);
+
+ //MAC register setting
+ RTL_W8(0x522, 0x3f);
+ RTL_W8(0x550, RTL_R8(0x550)& (~BIT(3)));
+ RTL_W8(0x551, RTL_R8(0x551)& (~BIT(3)));
+ RTL_W32(0x40, 0);
+
+ //AP or IQK
+ RTL_W32(0xb68 , 0x0f600000);
+ RTL_W32(0xb6c , 0x0f600000);
+
+ // IQK setting
+ RTL_W32(0xe28, 0x80800000);
+ RTL_W32(0xe40, 0x01007c00);
+ RTL_W32(0xe44, 0x01004800);
+
+ // path-A IQK setting
+ RTL_W32(0xe30, 0x10008c22);
+ RTL_W32(0xe34, 0x10008c22);
+ RTL_W32(0xe38, 0x82140102);
+ RTL_W32(0xe3c, 0x28160206);
+
+ // LO calibration setting
+ RTL_W32(0xe4c, 0x00462911);
+
+ // delay to ensure Path-A IQK success
+ delay_ms(10);
+
+ // step 4: One shot, path A LOK & IQK
+ while (cal_num < 3) {
+ // One shot, path A LOK & IQK
+ RTL_W32(0xe48, 0xf9000000);
+ RTL_W32(0xe48, 0xf8000000);
+ // delay 1ms
+ delay_ms(1);
+
+ // check fail bit and check abnormal condition, then fill BB IQ matrix
+ cal_e94 = (RTL_R32(0xe94) >> 16) & 0x3ff;
+ cal_e9c = (RTL_R32(0xe9c) >> 16) & 0x3ff;
+ cal_ea4 = (RTL_R32(0xea4) >> 16) & 0x3ff;
+ temp_eac = RTL_R32(0xeac);
+ cal_eac = (temp_eac >> 16) & 0x3ff;
+ if (!(temp_eac & BIT(28)) && !(temp_eac & BIT(27)) &&
+ (cal_e94 != 0x142) && (cal_e9c != 0x42) &&
+ (cal_ea4 != 0x132) && (cal_eac != 0x36)) {
+ val_e94[cal_num] = cal_e94;
+ val_e9c[cal_num] = cal_e9c;
+ val_ea4[cal_num] = cal_ea4;
+ val_eac[cal_num] = cal_eac;
+ cal_num++;
+ } else {
+ if (++cal_retry >= 10) {
+ printk("%s Path-A Check\n",__FUNCTION__);
+ break;
+ }
+ }
+ }
+
+ if (cal_num == 3) {
+ cal_e94 = get_mean_of_2_close_value(val_e94);
+ cal_e9c = get_mean_of_2_close_value(val_e9c);
+ cal_ea4 = get_mean_of_2_close_value(val_ea4);
+ cal_eac = get_mean_of_2_close_value(val_eac);
+
+ priv->pshare->RegE94=cal_e94;
+ priv->pshare->RegE9C=cal_e9c;
+
+ Oldval = (RTL_R32(0xc80) >> 22) & 0x3ff;
+
+ X = cal_e94;
+ PHY_SetBBReg(priv, 0xc80, 0x3ff, (X * Oldval) >> 8);
+ PHY_SetBBReg(priv, 0xc4c, BIT(24), ((X * Oldval) >> 7) & 0x1);
+
+ Y = cal_e9c;
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+ PHY_SetBBReg(priv, 0xc94, 0xf0000000, (((Y * Oldval) >> 8) >> 6) & 0xf);
+ PHY_SetBBReg(priv, 0xc80, 0x003f0000, ((Y * Oldval) >> 8) & 0x3f);
+ PHY_SetBBReg(priv, 0xc4c, BIT(26), ((Y * Oldval) >> 7) & 0x1);
+
+ PHY_SetBBReg(priv, 0xc14, 0x3ff, cal_ea4);
+
+ PHY_SetBBReg(priv, 0xc14, 0xfc00, cal_eac & 0x3f);
+
+ PHY_SetBBReg(priv, 0xca0, 0xf0000000, (cal_eac >> 6) & 0xf);
+ }else {
+ priv->pshare->RegE94=0x100;
+ priv->pshare->RegE9C=0x00;
+ }
+
+ // back to BB mode, load original values
+ RTL_W32(0xe28, 0);
+ RTL_W32(0xc04, temp_c04);
+ RTL_W32(0xc08, temp_c08);
+ RTL_W32(0x874, temp_874);
+ RTL_W32(0x800, temp_800);
+
+ RTL_W32(0x88c, temp_88c);
+ RTL_W32(0x840, 0x32fff);
+ RTL_W32(0x870, temp_870);
+ RTL_W32(0x860, temp_860);
+ RTL_W32(0x864, temp_864);
+
+ // return to SI mode
+ if (switch2PI) {
+ RTL_W32(0x820, 0x01000000);
+ RTL_W32(0x828, 0x01000000);
+ }
+
+#if defined(CONFIG_RTL_8198) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
+ REG32(BSP_WDTCNR) |= 1 << 23;
+#elif defined(CONFIG_RTL_8198B)
+ REG32(BSP_WDTCNTRR) |= BSP_WDT_KICK;
+#endif
+
+ /*
+ * Reload ADDA power saving parameters
+ */
+ for(i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ PHY_SetBBReg(priv, ADDA_REG[i], bMaskDWord, ADDA_backup[i]);
+
+ /*
+ * Reload MAC default value
+ */
+ RTL_W8(0x550, temp_550);
+ RTL_W8(0x551, temp_551);
+ RTL_W32(0x40, temp_040);
+ RTL_W8(0x522, temp_522);
+
+}
+
+
+void IQK_92D_5G_phy0_n(struct rtl8192cd_priv *priv)
+{
+ unsigned int temp_800, temp_c04, temp_874, temp_c08, temp_870, temp_860, temp_88c, temp_c50, temp_b30,
+ switch2PI=0, X, reg; //, Oldval_0, TX0_A;
+ u8 temp_522, temp_550, temp_551;
+ unsigned int cal_num=0, cal_retry=0, ADDA_backup[IQK_ADDA_REG_NUM];
+ int Y, result[8][3], result_final[8]; //, TX0_C;
+
+ unsigned int i, RX0REG0xe40[3], RX0REG0xe40_final=0, REG0xe40, REG0xe94, REG0xe9c, delay_count;
+ unsigned int REG0xeac, REG0xea4;
+ unsigned char TX0IQKOK = FALSE;
+ unsigned int TX_X0, TX_Y0, RX_X0, RX_Y0;
+ unsigned int ADDA_REG[IQK_ADDA_REG_NUM] = {0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
+ 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec};
+
+#ifdef MP_TEST
+ if (!priv->pshare->rf_ft_var.mp_specific)
+#endif
+ {
+ if (priv->pshare->iqk_5g_done)
+ return;
+ priv->pshare->iqk_5g_done = 1;
+ }
+
+ printk(">> %s \n",__FUNCTION__);
+#if defined(CONFIG_RTL_8198) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
+ REG32(BSP_WDTCNR) |= 1 << 23;
+#elif defined(CONFIG_RTL_8198B)
+ REG32(BSP_WDTCNTRR) |= BSP_WDT_KICK;
+#endif
+ /*
+ * Save MAC default value
+ */
+ temp_522 = RTL_R8(0x522);
+ temp_550 = RTL_R8(0x550);
+ temp_551 = RTL_R8(0x551);
+
+ /*
+ * Save BB Parameter
+ */
+ temp_800 = RTL_R32(0x800);
+ temp_c04 = RTL_R32(0xc04);
+ temp_874 = RTL_R32(0x874);
+ temp_c08 = RTL_R32(0xc08);
+ temp_870 = RTL_R32(0x870);
+ temp_860 = RTL_R32(0x860);
+ temp_88c = RTL_R32(0x88c);
+ temp_c50 = RTL_R32(0xc50);
+ temp_b30 = RTL_R32(0xb30); // 03/03/2011 update
+
+ /*
+ * Save AFE Parameters
+ */
+ for( i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ ADDA_backup[i] = RTL_R32(ADDA_REG[i]);
+
+ /*
+ * ==============
+ * Path-A TX/RX IQK
+ * ==============
+ */
+ while (cal_num < 3) {
+ /*
+ * Path-A AFE all on
+ */
+ for( i = 0 ; i < IQK_ADDA_REG_NUM ; i++) {
+#ifdef NON_INTR_ANTDIV
+ if (DMDP_PHY_QueryBBReg(0, 0xb30,BIT(27)))
+ RTL_W32(ADDA_REG[i], 0x0b1b25a4);
+ else
+#endif
+ RTL_W32(ADDA_REG[i], 0x04db25a4);
+ }
+
+ /*
+ * MAC register setting
+ */
+ RTL_W8(0x522, 0x3f);
+ RTL_W8(0x550, RTL_R8(0x550)& (~BIT(3)));
+ RTL_W8(0x551, RTL_R8(0x551)& (~BIT(3)));
+
+ /*
+ * IQK must be done in PI mode
+ */
+ if (!PHY_QueryBBReg(priv, 0x820, BIT(8)) || !PHY_QueryBBReg(priv, 0x828, BIT(8))) {
+ PHY_SetBBReg(priv, 0x820, bMaskDWord, 0x01000100);
+ PHY_SetBBReg(priv, 0x828, bMaskDWord, 0x01000100);
+ switch2PI++;
+ }
+
+ /*
+ * BB setting
+ */
+ PHY_SetBBReg(priv, 0x800, BIT(24), 0);
+ PHY_SetBBReg(priv, 0xc04, bMaskDWord, 0x03a05600);
+ PHY_SetBBReg(priv, 0xc08, bMaskDWord, 0x000800e4);
+ PHY_SetBBReg(priv, 0x874, bMaskDWord, 0x22208000);
+ PHY_SetBBReg(priv, 0x88c, BIT(23)|BIT(22)|BIT(21)|BIT(20), 0xf);
+ PHY_SetBBReg(priv, 0xb30, bMaskDWord, 0x00a00000); // 03/03/2011 update
+
+ /*
+ * AP or IQK
+ */
+ //PHY_SetBBReg(priv, 0xb68, bMaskDWord, 0x0f600000);
+ //PHY_SetBBReg(priv, 0xb6c, bMaskDWord, 0x0f600000);
+
+ // IQK-R03 2011/02/16 update
+ PHY_SetBBReg(priv, 0xb00, bMaskDWord, 0);
+ PHY_SetBBReg(priv, 0xb68, bMaskDWord, 0x20000000);
+
+ /*
+ * IQK global setting
+ */
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x80800000);
+ PHY_SetBBReg(priv, 0xe40, bMaskDWord, 0x10007c00);
+ PHY_SetBBReg(priv, 0xe44, bMaskDWord, 0x01004800);
+
+ /*
+ * path-A IQK setting
+ */
+ PHY_SetBBReg(priv, 0xe30, bMaskDWord, 0x18008c1f);
+ PHY_SetBBReg(priv, 0xe34, bMaskDWord, 0x18008c1f);
+ PHY_SetBBReg(priv, 0xe38, bMaskDWord, 0x82140307); // 01/11/2011 update
+
+#ifdef USB_POWER_SUPPORT
+ PHY_SetBBReg(priv, 0xe3c, bMaskDWord, 0x68160c66);
+#else
+ PHY_SetBBReg(priv, 0xe3c, bMaskDWord, 0x68160960); // 01/11/2011 update
+#endif
+ /*
+ * LO calibration setting
+ */
+ PHY_SetBBReg(priv, 0xe4c, bMaskDWord, 0x00462911);
+
+#ifdef USB_POWER_SUPPORT
+ // PHY0 TRSW seting
+ PHY_SetBBReg(priv, 0x870, BIT(6)|BIT(5), 3);
+ PHY_SetBBReg(priv, 0x860, BIT(6)|BIT(5), 3);
+#else
+ /*
+ * path-A PA on
+ */
+ /*
+ PHY_SetBBReg(priv, 0x870, BIT(11)|BIT(10), 3);
+ PHY_SetBBReg(priv, 0x870, BIT(6)|BIT(5), 3);
+ PHY_SetBBReg(priv, 0x860, BIT(11)|BIT(10), 3);
+ */
+ PHY_SetBBReg(priv, 0x870, bMaskDWord, 0x07000f60); // 01/11/2011 update
+ PHY_SetBBReg(priv, 0x860, bMaskDWord, 0x66e60e30); // 01/11/2011 update
+#endif
+ /*
+ * One shot, path A LOK & IQK
+ */
+ PHY_SetBBReg(priv, 0xe48, bMaskDWord, 0xf9000000);
+ PHY_SetBBReg(priv, 0xe48, bMaskDWord, 0xf8000000);
+
+ /*
+ * Delay 10 ms
+ */
+ delay_ms(10);
+
+ delay_count = 0;
+ while (1){
+ REG0xeac = PHY_QueryBBReg(priv, 0xeac, bMaskDWord);
+ if ((REG0xeac&BIT(26))||(delay_count>20)){
+ break;
+ }else {
+ delay_ms(1);
+ delay_count++;
+ }
+ }
+
+ /*
+ * Check_TX_IQK_A_result
+ */
+ REG0xe40 = PHY_QueryBBReg(priv, 0xe40, bMaskDWord);
+ REG0xeac = PHY_QueryBBReg(priv, 0xeac, bMaskDWord);
+ REG0xe94 = PHY_QueryBBReg(priv, 0xe94, bMaskDWord);
+ if(((REG0xeac&BIT(28)) == 0) && (((REG0xe94&0x3FF0000)>>16)!=0x142)) {
+ TX0IQKOK = TRUE;
+ REG0xe9c = PHY_QueryBBReg(priv, 0xe9c, bMaskDWord);
+ TX_X0 = (PHY_QueryBBReg(priv, 0xe94, bMaskDWord)&0x3FF0000)>>16;
+ TX_Y0 = (PHY_QueryBBReg(priv, 0xe9c, bMaskDWord)&0x3FF0000)>>16;
+ RX0REG0xe40[cal_num] = (REG0xe40 & 0xfc00fc00) | (TX_X0<<16) | TX_Y0;
+ DEBUG_INFO("TX_X0 %08x TX_Y0 %08x RX0REG0xe40 %08x\n", TX_X0, TX_Y0, RX0REG0xe40[cal_num]);
+ result[0][cal_num] = TX_X0;
+ result[1][cal_num] = TX_Y0;
+ } else {
+ TX0IQKOK = FALSE;
+ if (++cal_retry >= 10) {
+ printk("%s Path-A Tx/Rx Check\n",__FUNCTION__);
+ break;
+ }
+ }
+
+ /*
+ * Check_RX_IQK_A_result
+ */
+ if(TX0IQKOK == TRUE) {
+ REG0xeac = PHY_QueryBBReg(priv, 0xeac, bMaskDWord);
+ REG0xea4 = PHY_QueryBBReg(priv, 0xea4, bMaskDWord);
+ if(((REG0xeac&BIT(27)) == 0) && (((REG0xea4&0x3FF0000)>>16)!=0x132)) {
+ RX_X0 = (PHY_QueryBBReg(priv, 0xea4, bMaskDWord)&0x3FF0000)>>16;
+ RX_Y0 = (PHY_QueryBBReg(priv, 0xeac, bMaskDWord)&0x3FF0000)>>16;
+ DEBUG_INFO("RX_X0 %08x RX_Y0 %08x\n", RX_X0, RX_Y0);
+ result[2][cal_num] = RX_X0;
+ result[3][cal_num] = RX_Y0;
+ cal_num++;
+ } else {
+ PHY_SetBBReg(priv, 0xc14, bMaskDWord, 0x40000100);
+ PHY_SetBBReg(priv, 0xe34, bMaskDWord, 0x19008c00);
+ if (++cal_retry >= 10) {
+ printk("%s Path-A Tx/Rx Check\n",__FUNCTION__);
+ break;
+ }
+ }
+ }
+ }
+
+ if (cal_num == 3) {
+ result_final[0] = get_mean_of_2_close_value(result[0]);
+ result_final[1] = get_mean_of_2_close_value(result[1]);
+ result_final[2] = get_mean_of_2_close_value(result[2]);
+ result_final[3] = get_mean_of_2_close_value(result[3]);
+ RX0REG0xe40_final = 0x80000000 | get_mean_of_2_close_value(RX0REG0xe40);
+
+ priv->pshare->RegE94=result_final[0];
+ priv->pshare->RegE9C=result_final[1];
+ } else {
+ priv->pshare->RegE94=0x100;
+ priv->pshare->RegE9C=0x00;
+ }
+
+ /*
+ * Fill IQK result for Path A
+ */
+ if (result_final[0]) {
+ /*
+ Oldval_0 = (PHY_QueryBBReg(priv, 0xc80, bMaskDWord) >> 22) & 0x3FF;
+ X = result_final[0];
+ if ((X & 0x00000200) != 0)
+ X = X | 0xFFFFFC00;
+ TX0_A = (X * Oldval_0) >> 8;
+ PHY_SetBBReg(priv, 0xc80, 0x3FF, TX0_A);
+ PHY_SetBBReg(priv, 0xc4c, BIT(24), ((X* Oldval_0>>7) & 0x1));
+
+ Y = result_final[1];
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+ TX0_C = (Y * Oldval_0) >> 8;
+ PHY_SetBBReg(priv, 0xc94, 0xF0000000, ((TX0_C&0x3C0)>>6));
+ PHY_SetBBReg(priv, 0xc80, 0x003F0000, (TX0_C&0x3F));
+ PHY_SetBBReg(priv, 0xc4c, BIT(26), ((Y* Oldval_0>>7) & 0x1));
+ */
+
+ // IQK-R03 2011/02/16 update
+ X = result_final[0];
+ Y = result_final[1];
+ //printk("X=%x Y=%x\n",X,Y);
+ //Path-A OFDM_A
+ PHY_SetBBReg(priv, 0xe30, 0x03FF0000, X);
+ PHY_SetBBReg(priv, 0xc4c, BIT(24), 0);
+ //Path-A OFDM_C
+ PHY_SetBBReg(priv, 0xe30, 0x000003FF, Y);
+ PHY_SetBBReg(priv, 0xc4c, BIT(26), 0);
+
+
+ if(result_final[2]) {
+ reg = result_final[2];
+ PHY_SetBBReg(priv, 0xc14, 0x3FF, reg);
+
+ reg = result_final[3] & 0x3F;
+ PHY_SetBBReg(priv, 0xc14, 0xFC00, reg);
+
+ reg = (result_final[3] >> 6) & 0xF;
+ PHY_SetBBReg(priv, 0xca0, 0xF0000000, reg);
+
+ PHY_SetBBReg(priv, 0xe34, 0x03FF0000, result_final[2]); // X
+ PHY_SetBBReg(priv, 0xe34, 0x3FF, result_final[3]); //Y
+ }
+ }
+
+ /*
+ * Path-A PA off
+ */
+ PHY_SetBBReg(priv, 0x870, bMaskDWord, temp_870);
+ PHY_SetBBReg(priv, 0x860, bMaskDWord, temp_860);
+
+ /*
+ * Exit IQK mode
+ */
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0);
+ PHY_SetBBReg(priv, 0xc04, bMaskDWord, temp_c04);
+ PHY_SetBBReg(priv, 0xc08, bMaskDWord, temp_c08);
+ PHY_SetBBReg(priv, 0x874, bMaskDWord, temp_874);
+ PHY_SetBBReg(priv, 0x800, bMaskDWord, temp_800);
+ PHY_SetBBReg(priv, 0x88c, bMaskDWord, temp_88c);
+ PHY_SetBBReg(priv, 0xb30, bMaskDWord, temp_b30); // 03/03/2011 update
+ //PHY_SetBBReg(priv, 0x840, bMaskDWord, 0x00032fff); // 01/11/2011 update
+
+ //PHY0 IQ path to DP block
+ PHY_SetBBReg(priv, 0xb00, bMaskDWord, 0x010170b8);
+
+ PHY_SetBBReg(priv, 0xc50, bMaskDWord, 0x50);
+ PHY_SetBBReg(priv, 0xc50, bMaskDWord, temp_c50);
+
+ /*
+ * Reload MAC default value
+ */
+ RTL_W8(0x550, temp_550);
+ RTL_W8(0x551, temp_551);
+ RTL_W8(0x522, temp_522);
+
+ /*
+ * Switch back to SI if needed, after IQK
+ */
+ if (switch2PI) {
+ PHY_SetBBReg(priv, 0x820, bMaskDWord, 0x01000000);
+ PHY_SetBBReg(priv, 0x828, bMaskDWord, 0x01000000);
+ }
+
+ /*
+ * Reload ADDA power saving parameters
+ */
+ for(i = 0 ; i < IQK_ADDA_REG_NUM ; i++)
+ PHY_SetBBReg(priv, ADDA_REG[i], bMaskDWord, ADDA_backup[i]);
+}
+#endif
+
+#ifdef SW_LCK_92D
+
+#define TARGET_CHNL_NUM_5G 221
+#define TARGET_CHNL_NUM_2G 14
+#define CV_CURVE_CNT 64
+
+unsigned int CurveIndex_5G[TARGET_CHNL_NUM_5G]={0};
+unsigned int CurveIndex_2G[TARGET_CHNL_NUM_2G]={0};
+
+static unsigned int TargetChnl_5G[TARGET_CHNL_NUM_5G] = {
+25141, 25116, 25091, 25066, 25041,
+25016, 24991, 24966, 24941, 24917,
+24892, 24867, 24843, 24818, 24794,
+24770, 24765, 24721, 24697, 24672,
+24648, 24624, 24600, 24576, 24552,
+24528, 24504, 24480, 24457, 24433,
+24409, 24385, 24362, 24338, 24315,
+24291, 24268, 24245, 24221, 24198,
+24175, 24151, 24128, 24105, 24082,
+24059, 24036, 24013, 23990, 23967,
+23945, 23922, 23899, 23876, 23854,
+23831, 23809, 23786, 23764, 23741,
+23719, 23697, 23674, 23652, 23630,
+23608, 23586, 23564, 23541, 23519,
+23498, 23476, 23454, 23432, 23410,
+23388, 23367, 23345, 23323, 23302,
+23280, 23259, 23237, 23216, 23194,
+23173, 23152, 23130, 23109, 23088,
+23067, 23046, 23025, 23003, 22982,
+22962, 22941, 22920, 22899, 22878,
+22857, 22837, 22816, 22795, 22775,
+22754, 22733, 22713, 22692, 22672,
+22652, 22631, 22611, 22591, 22570,
+22550, 22530, 22510, 22490, 22469,
+22449, 22429, 22409, 22390, 22370,
+22350, 22336, 22310, 22290, 22271,
+22251, 22231, 22212, 22192, 22173,
+22153, 22134, 22114, 22095, 22075,
+22056, 22037, 22017, 21998, 21979,
+21960, 21941, 21921, 21902, 21883,
+21864, 21845, 21826, 21807, 21789,
+21770, 21751, 21732, 21713, 21695,
+21676, 21657, 21639, 21620, 21602,
+21583, 21565, 21546, 21528, 21509,
+21491, 21473, 21454, 21436, 21418,
+21400, 21381, 21363, 21345, 21327,
+21309, 21291, 21273, 21255, 21237,
+21219, 21201, 21183, 21166, 21148,
+21130, 21112, 21095, 21077, 21059,
+21042, 21024, 21007, 20989, 20972,
+25679, 25653, 25627, 25601, 25575,
+25549, 25523, 25497, 25471, 25446,
+25420, 25394, 25369, 25343, 25318,
+25292, 25267, 25242, 25216, 25191,
+25166 };
+
+static unsigned int TargetChnl_2G[TARGET_CHNL_NUM_2G] = { // channel 1~14
+26084, 26030, 25976, 25923, 25869, 25816, 25764,
+25711, 25658, 25606, 25554, 25502, 25451, 25328
+};
+
+void _PHY_CalcCurvIndex(struct rtl8192cd_priv *priv, unsigned int *TargetChnl,
+ unsigned int *CurveCountVal, char is5G, unsigned int *CurveIndex)
+{
+ unsigned int smallestABSVal = 0xffffffff, u4tmp;
+ unsigned char i, j;
+ unsigned char chnl_num = is5G?(TARGET_CHNL_NUM_5G) : (TARGET_CHNL_NUM_2G);
+
+
+ for(i=0; i<chnl_num; i++)
+ {
+ //if(is5G && !IsLegal5GChannel(pAdapter, i+1))
+ //continue;
+
+ CurveIndex[i] = 0;
+ for(j=0; j<(CV_CURVE_CNT*2); j++)
+ {
+ u4tmp = RTL_ABS(TargetChnl[i], CurveCountVal[j]);
+ //if (i==115)
+ //printk("cv[%d]=%x\n", j, u4tmp);
+ if(u4tmp < smallestABSVal)
+ {
+ CurveIndex[i] = j;
+ smallestABSVal = u4tmp;
+ }
+ }
+
+ smallestABSVal = 0xffffffff;
+ }
+}
+
+void phy_ReloadLCKSetting(struct rtl8192cd_priv *priv)
+{
+ unsigned int eRFPath = priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G? RF92CD_PATH_A:(priv->pmib->dot11RFEntry.macPhyMode==SINGLEMAC_SINGLEPHY?RF92CD_PATH_B:RF92CD_PATH_A);
+ unsigned int u4tmp = 0;
+// unsigned char bNeedPowerDownRadio = FALSE;
+ unsigned int channel = priv->pshare->RegRF18[eRFPath]&0xff;
+ //unsigned int channel = PHY_QueryRFReg(priv, eRFPath, rRfChannel, 0xff, 1);
+
+ DEBUG_INFO("====>phy_ReloadLCKSetting interface %d path %d ch %d [0x%05x]\n", priv->pshare->wlandev_idx, eRFPath, channel, priv->pshare->RegRF28[eRFPath]);
+
+ //only for 92D C-cut SMSP
+ if(GET_CHIP_VER(priv)!=VERSION_8192D
+#ifdef CONFIG_RTL_92C_SUPPORT
+ || IS_TEST_CHIP(priv)
+#endif
+ )
+ return;
+
+ if(priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G)
+ {
+ //Path-A for 5G
+ u4tmp = CurveIndex_5G[channel-1];
+ //printk("%s ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n",__FUNCTION__, u4tmp);
+#ifdef CONFIG_RTL_92D_DMDP
+ if(priv->pmib->dot11RFEntry.macPhyMode == DUALMAC_DUALPHY && priv->pshare->wlandev_idx == 1)
+ {
+ priv->pshare->RegRF28[RF92CD_PATH_A] = RTL_SET_MASK(priv->pshare->RegRF28[RF92CD_PATH_A],0x3f800,u4tmp,11); //DMDP_PHY_SetRFReg(0, RF92CD_PATH_A, 0x28, 0x3f800, u4tmp);
+ DMDP_PHY_SetRFReg(0, RF92CD_PATH_A, 0x28, bMask20Bits, priv->pshare->RegRF28[RF92CD_PATH_A]);
+ }else
+#endif
+ {
+ priv->pshare->RegRF28[eRFPath] = RTL_SET_MASK(priv->pshare->RegRF28[eRFPath],0x3f800,u4tmp,11); //PHY_SetRFReg(priv, eRFPath, 0x28, 0x3f800, u4tmp);
+ PHY_SetRFReg(priv, eRFPath, 0x28, bMask20Bits, priv->pshare->RegRF28[eRFPath]);
+ }
+ DEBUG_INFO("%s ver 3 set RF-B, 2G, 0x28 = 0x%05x [0x%05x]!!\n", __FUNCTION__, PHY_QueryRFReg(priv, eRFPath, 0x28, bMask20Bits, 1), priv->pshare->RegRF28[eRFPath]);
+ }
+ else if(priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G)
+ {
+ u4tmp = CurveIndex_2G[channel-1];
+ //printk("%s ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", __FUNCTION__, u4tmp);
+#ifdef CONFIG_RTL_92D_DMDP
+ if(priv->pmib->dot11RFEntry.macPhyMode == DUALMAC_DUALPHY && priv->pshare->wlandev_idx == 0)
+ {
+ priv->pshare->RegRF28[RF92CD_PATH_A] = RTL_SET_MASK(priv->pshare->RegRF28[RF92CD_PATH_A],0x3f800,u4tmp,11); //DMDP_PHY_SetRFReg(1, RF92CD_PATH_A, 0x28, 0x3f800, u4tmp);
+ DMDP_PHY_SetRFReg(1, RF92CD_PATH_A, 0x28, bMask20Bits, priv->pshare->RegRF28[RF92CD_PATH_A]);
+ }else
+#endif
+ {
+ priv->pshare->RegRF28[eRFPath] = RTL_SET_MASK(priv->pshare->RegRF28[eRFPath],0x3f800,u4tmp,11); // PHY_SetRFReg(priv, eRFPath, 0x28, 0x3f800, u4tmp);
+ PHY_SetRFReg(priv, eRFPath, 0x28, bMask20Bits, priv->pshare->RegRF28[eRFPath]);
+ }
+ DEBUG_INFO("%s ver 3 set RF-B, 2G, 0x28 = 0x%05x [0x%05x]!!\n", __FUNCTION__, PHY_QueryRFReg(priv, eRFPath, 0x28, bMask20Bits, 1), priv->pshare->RegRF28[eRFPath]);
+ }
+
+}
+
+/* Software LCK */
+void PHY_LCCalibrate_92D(struct rtl8192cd_priv *priv)
+{
+ unsigned char tmpReg;
+ unsigned int RF_mode[2];
+ unsigned int eRFPath, curMaxRFPath;
+ unsigned int i;
+ unsigned int curveCountVal[CV_CURVE_CNT*2]={0};
+ unsigned short timeout = 800, timecount = 0;
+
+ if (priv->pmib->dot11RFEntry.macPhyMode == DUALMAC_DUALPHY)
+ curMaxRFPath = RF92CD_PATH_B;
+ else
+ curMaxRFPath = RF92CD_PATH_MAX;
+
+ //Check continuous TX and Packet TX
+ tmpReg = RTL_R8(0xd03);
+
+ if ((tmpReg & 0x70) != 0) // Deal with contisuous TX case
+ RTL_W8(0xd03, tmpReg&0x8F); // disable all continuous TX
+ else // Deal with Packet TX case
+ RTL_W8(TXPAUSE, 0xFF); // block all queues
+
+ PHY_SetBBReg(priv, rFPGA0_AnalogParameter4, 0xF00000, 0x0F);
+
+ for(eRFPath = RF92CD_PATH_A; eRFPath < curMaxRFPath; eRFPath++) {
+ // 1. Read original RF mode
+ RF_mode[eRFPath] = PHY_QueryRFReg(priv, eRFPath, 0x00, bMask20Bits, 1);
+
+ // 2. Set RF mode = standby mode
+ PHY_SetRFReg(priv, eRFPath, 0x00, 0x70000, 0x01);
+
+ // switch CV-curve control by LC-calibration
+ PHY_SetRFReg(priv, eRFPath, 0x2B, BIT(17), 0x0);
+
+ // jenyu suggest
+ PHY_SetRFReg(priv, eRFPath, 0x28, BIT(8), 0x1);
+
+ //4. Set LC calibration begin
+ PHY_SetRFReg(priv, eRFPath, 0x18, BIT(15), 0x01);
+
+ while(!(PHY_QueryRFReg(priv, eRFPath, 0x2A, BIT(11), 1) &&
+ timecount <= timeout)){
+ //DEBUG_INFO("PHY_LCK delay for %d ms=2\n", timecount);
+ delay_ms(50);
+ timecount+=50;
+ }
+
+ //u4tmp = PHY_QueryRFReg(priv, eRFPath, 0x28, bMask20Bits, 1);
+
+ memset((void *)curveCountVal, 0, CV_CURVE_CNT*2);
+
+ //Set LC calibration off
+ PHY_SetRFReg(priv, eRFPath, 0x18, BIT(15), 0x00);
+
+ // jenyu suggest
+ PHY_SetRFReg(priv, eRFPath, 0x28, BIT(8), 0x0);
+
+ //save Curve-counting number
+ for(i=0; i<CV_CURVE_CNT; i++)
+ {
+ unsigned int readVal=0, readVal2=0;
+
+ PHY_SetRFReg(priv, eRFPath, 0x3F, 0x7f, i);
+
+ PHY_SetRFReg(priv, eRFPath, 0x4D, bMask20Bits, 0);
+
+ readVal = PHY_QueryRFReg(priv, eRFPath, 0x4F, bMask20Bits, 1);
+
+ curveCountVal[2*i+1] = (readVal & 0xfffe0) >> 5;
+
+ readVal2 = PHY_QueryRFReg(priv, eRFPath, 0x50, 0xffc00, 1);
+
+ curveCountVal[2*i] = (((readVal & 0x1F) << 10) | readVal2);
+ }
+
+ if(eRFPath == RF92CD_PATH_A
+#ifdef CONFIG_RTL_92D_DMDP
+ && priv->pshare->wlandev_idx == 0
+#endif
+ )
+ _PHY_CalcCurvIndex(priv, TargetChnl_5G, curveCountVal, TRUE, CurveIndex_5G);
+ else
+ _PHY_CalcCurvIndex(priv, TargetChnl_2G, curveCountVal, FALSE, CurveIndex_2G);
+
+ // switch CV-curve control mode
+ PHY_SetRFReg(priv, eRFPath, 0x2B, BIT(17), 0x1);
+
+ // store 0x28 for Reload_LCK
+ priv->pshare->RegRF28[eRFPath] = PHY_QueryRFReg(priv, eRFPath, 0x28, bMask20Bits, 1);
+ }
+
+ //Restore original situation
+ for(eRFPath = RF92CD_PATH_A; eRFPath < curMaxRFPath; eRFPath++)
+ {
+ PHY_SetRFReg(priv, eRFPath, 0x00, bMask20Bits, RF_mode[eRFPath]);
+ }
+
+ if((tmpReg&0x70) != 0)
+ {
+ //Path-A
+ RTL_W8(0xd03, tmpReg);
+ }
+ else // Deal with Packet TX case
+ {
+ RTL_W8(TXPAUSE, 0x00);
+ }
+
+ PHY_SetBBReg(priv, rFPGA0_AnalogParameter4, 0xF00000, 0x00);
+
+ phy_ReloadLCKSetting(priv);
+
+}
+
+#else
+/* Hardware LCK */
+static void PHY_LCCalibrate_92D(struct rtl8192cd_priv *priv)
+{
+ unsigned char tmpReg;
+ unsigned int RF_mode[2], tmpu4Byte[2];
+
+ unsigned int eRFPath, curMaxRFPath;
+ unsigned char timeout = 800, timecount = 0;
+
+ if (priv->pmib->dot11RFEntry.macPhyMode == DUALMAC_DUALPHY)
+ curMaxRFPath = RF92CD_PATH_B;
+ else
+ curMaxRFPath = RF92CD_PATH_MAX;
+
+
+ // Check continuous TX and Packet TX
+ tmpReg = RTL_R8(0xd03);
+
+ if ((tmpReg & 0x70) != 0) // Deal with contisuous TX case
+ RTL_W8(0xd03, tmpReg&0x8F); // disable all continuous TX
+ else // Deal with Packet TX case
+ RTL_W8(TXPAUSE, 0xFF); // block all queues
+
+ PHY_SetBBReg(priv, rFPGA0_AnalogParameter4, 0xF00000, 0x0F);
+
+ for(eRFPath = RF92CD_PATH_A; eRFPath < curMaxRFPath; eRFPath++) {
+ // 1. Read original RF mode
+ RF_mode[eRFPath] = PHY_QueryRFReg(priv, eRFPath, 0x00, bMask20Bits, 1);
+
+ // 2. Set RF mode = standby mode
+ PHY_SetRFReg(priv, eRFPath, 0x00, 0x70000, 0x01);
+
+ tmpu4Byte[eRFPath] = PHY_QueryRFReg(priv, eRFPath, 0x28, bMask20Bits, 1);
+ PHY_SetRFReg(priv, eRFPath, 0x28, 0x700, 0x07);
+
+ //4. Set LC calibration begin
+ PHY_SetRFReg(priv, eRFPath, 0x18, 0x08000, 0x01);
+ }
+
+#if (defined(CONFIG_RTL_8198) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)) && defined(CONFIG_RTL_92D_SUPPORT)
+ REG32(BSP_WDTCNR) |= 1 << 23;
+#elif defined(CONFIG_RTL_8198B) && defined(CONFIG_RTL_92D_SUPPORT)
+ REG32(BSP_WDTCNTRR) |= BSP_WDT_KICK;
+#endif
+
+ for(eRFPath = RF92CD_PATH_A; eRFPath < curMaxRFPath; eRFPath++) {
+ while(!(PHY_QueryRFReg(priv, eRFPath, 0x2A, BIT(11), 1) &&
+ timecount <= timeout)){
+ DEBUG_INFO("PHY_LCK delay for %d ms=2\n", timecount);
+ delay_ms(50);
+ timecount+=50;
+ }
+ }
+
+ for(eRFPath = RF92CD_PATH_A; eRFPath < curMaxRFPath; eRFPath++) {
+ PHY_SetRFReg(priv, eRFPath, 0x28, bMask20Bits, tmpu4Byte[eRFPath]);
+ priv->pshare->RegRF28[eRFPath] = tmpu4Byte[eRFPath];
+ PHY_SetRFReg(priv, eRFPath, 0x00, bMask20Bits, RF_mode[eRFPath]);
+ }
+
+ // Restore original situation
+ if ((tmpReg & 0x70) != 0) // Deal with contisuous TX case
+ RTL_W8(0xd03, tmpReg);
+ else // Deal with Packet TX case
+ RTL_W8(TXPAUSE, 0x00);
+
+ PHY_SetBBReg(priv, rFPGA0_AnalogParameter4, 0xF00000, 0x0);
+
+}
+
+
+#endif //LCK_SW
+
+#ifdef DPK_92D
+
+#if 1 //copy from driver of station team
+#define RF_AC 0x00
+
+#define rPdp_AntA 0xb00
+#define rBndA 0xb30
+#define rPdp_AntB 0xb70
+#define rBndB 0xba0
+
+#define RF_MODE1 0x10
+#define RF_MODE2 0x11
+
+#define rTxAGC_B_CCK11_A_CCK2_11 0x86c
+
+#define RF_TX_G3 0x22
+
+#define RF_TXPA_G1 0x31 // RF TX PA control
+#define RF_TXPA_G2 0x32 // RF TX PA control
+#define RF_TXPA_G3 0x33 // RF TX PA control
+#define RF_LOBF_9 0x38
+#define RF_RXRF_A3 0x3C
+#define RF_TRSW 0x3F
+
+#define RF_TXPA_G1 0x31 // RF TX PA control
+#define RF_TXPA_G2 0x32 // RF TX PA control
+#define RF_TXPA_G3 0x33 // RF TX PA control
+#define RF_LOBF_9 0x38
+#define RF_RXRF_A3 0x3C
+#define RF_TRSW 0x3F
+
+#define RF_TXRF_A2 0x41
+#define RF_TXPA_G4 0x46
+#define RF_TXPA_A4 0x4B
+
+#define RF_IQADJ_G1 0x01
+#define RF_IQADJ_G2 0x02
+#define RF_BS_PA_APSET_G1_G4 0x03
+#define RF_BS_PA_APSET_G5_G8 0x04
+#define RF_POW_TRSW 0x05
+
+#define DP_OFFSET_NUM 9
+#define DP_AP_CUREVE_SELECT_NUM 3
+#define DP_gain_loss 1
+#define DP_PA_BIAS_NUM 4
+
+#define rTxAGC_B_CCK1_55_Mcs32 0x838
+
+#define RF_TXBIAS 0x16
+#endif
+
+#define DPK_DEBUG(fmt,args...)
+
+#define DP_BB_REG_NUM 7
+//#define DP_BB_REG_NUM_A 11
+//#define DP_BB_REG_NUM_B 10
+#define DP_BB_REG_NUM_A 10
+#define DP_BB_REG_NUM_B 9
+
+#define DP_BB_REG_NUM_settings 6
+#define DP_BB_REG_NUM_loop 30
+#define DP_BB_REG_NUM_loop_tx 12
+#define DP_BB_REG_NUM_loop_rx 8
+#define DP_BB_REG_NUM_loop_pa 4
+#define DP_RF_REG_NUM 4
+#define DP_SRAM_NUM 16
+//#define DP_SRAM_NUM_db 22
+#define DP_SRAM_NUM_db 86
+
+#define DP_PATH_NUM 2
+#define DP_PA_MODEL_NUM 32
+#define DP_PA_MODEL_RUN_NUM 8
+#define DP_PA_MODEL_PER_RUN_NUM 4
+#define DP_RETRY_LIMIT 10
+#define DP_DPK_NUM 3
+#define DP_DPK_VALUE_NUM 2
+#if 1
+#define DP_GAIN_LOSS_BOUND_NUM 14
+#else
+#define DP_GAIN_LOSS_BOUND_NUM 8
+#endif
+#define DP_OFFSET_NUM 9
+//#define DP_AP_CUREVE_SELECT_NUM 2 // 3
+#define DP_gain_loss 1
+
+
+void rtl8192cd_DPK_timer(unsigned long task_priv)
+{
+ struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv;
+
+ if (!(priv->drv_state & DRV_STATE_OPEN))
+ return;
+
+ if (priv->pshare->pwr_trk_ongoing){
+ DPK_DEBUG("==>_PHY_DigitalPredistortion() TxPowerTrackingInProgress() delay 100ms\n");
+ mod_timer(&priv->pshare->DPKTimer, jiffies + RTL_MILISECONDS_TO_JIFFIES(100));
+ }else{
+ PHY_DPCalibrate(priv);
+ }
+}
+
+void _PHY_DPK_polling(struct rtl8192cd_priv *priv)
+{
+ unsigned int delaycount = 0, delaybound = 30, delay = 800;
+ unsigned int u4tmp;
+
+ delaycount = 0;
+
+ do{
+ delay_us(delay);
+
+ u4tmp = PHY_QueryBBReg(priv, 0xdf4, bMaskDWord);
+ //RTPRINT(FINIT, INIT_IQK, ("0xdf4 = 0x%x, delay %d us\n", u4tmp, delaycount*delay+800));
+ delaycount++;
+ delay = 100;
+ u4tmp = (u4tmp & BIT(26)) >> 26;
+ }while(u4tmp == 0x01 && delaycount < delaybound);
+
+}
+
+// if AP curve check fail return FALSE
+int _PHY_DPK_AP_curve_check(struct rtl8192cd_priv *priv, unsigned int *PA_power, unsigned int RegiesterNum)
+{
+ unsigned int PA_power_temp[DP_PA_MODEL_NUM], i = 0, index = 5,
+ base = 532, ref1, ref2;
+ int power_I, power_Q;
+
+ //store I, Q
+
+ for(i = 0; i < DP_PA_MODEL_NUM; i++){
+ power_I = (PA_power[i] >> 8);
+ if(power_I & BIT(7))
+ power_I |= bMaskH3Bytes;
+
+ power_Q = PA_power[i] & bMaskByte0;
+ if(power_Q & BIT(7))
+ power_Q |= bMaskH3Bytes;
+
+ PA_power_temp[i] = power_I*power_I+power_Q*power_Q;
+ }
+
+ ref1 = PA_power_temp[0];
+ for(i = 0; i < index; i++)
+ ref1 = (ref1 > PA_power_temp[i])?ref1:PA_power_temp[i];
+
+ ref2 = PA_power_temp[index];
+ for(i = index; i < index*2; i++)
+ ref2 = (ref2 > PA_power_temp[i])?ref2:PA_power_temp[i];
+
+ DPK_DEBUG("==>_PHY_DPK_AP_cureve_check ref1 = 0x%x ref2 = 0x%x\n", ref1, ref2);
+
+ if(ref1 == 0)
+ return FALSE;
+
+ return ((ref2 << 9)/ref1) < base;
+}
+
+// if DPK fail return FALSE
+int _PHY_DPK_check(struct rtl8192cd_priv *priv, unsigned int *PA_power, unsigned int RegiesterNum)
+{
+ unsigned int base = 407, PA_power_temp[2], i = 0;
+ int power_I, power_Q;
+
+ while(i ==0 || i == (RegiesterNum-1))
+ {
+ power_I = (PA_power[i] >> 8);
+ if(power_I & BIT(7))
+ power_I |= bMaskH3Bytes;
+
+ power_Q = PA_power[i] & bMaskByte0;
+ if(power_Q & BIT(7))
+ power_Q |= bMaskH3Bytes;
+
+ PA_power_temp[i==0?0:1] = power_I*power_I+ power_Q*power_Q;
+
+ DPK_DEBUG("==>_PHY_DPK_check pa_power_temp[%d] 0x%x\n", i, PA_power_temp[i==0?0:1]);
+
+ if(i == 0)
+ i = RegiesterNum -1;
+ else if (i == RegiesterNum -1)
+ break;
+ }
+
+ //normalization
+ if(PA_power_temp[0] == 0)
+ return TRUE;
+ else
+ return (((PA_power_temp[1] << 9) /PA_power_temp[0]) <= base);
+
+}
+
+int _PHY_Find_Tx_Power_Index(struct rtl8192cd_priv *priv, unsigned int *PA_power, unsigned char path, unsigned char bPlus3db, char bDecreaseTxIndex, unsigned char *tx_index_out)
+{
+ unsigned char i, tx_index = bDecreaseTxIndex?0x0f:0x15;
+ unsigned int tmpReg[11], tmpBase, RegNum = 11, base = /*323*/256;
+ unsigned int PA_power_normal[11];
+// unsigned int check_base =bPlus3db?(400-base):(323-base);
+ unsigned int check_base =bPlus3db?400:323;
+
+ int power_I, power_Q;
+ int index = -1;
+
+ DPK_DEBUG("==>tx_index minus %d bplus3db %d\n", base, bPlus3db);
+
+ _PHY_DPK_polling(priv);
+
+ if(path == RF92CD_PATH_A)
+ {
+ PHY_SetBBReg(priv, 0xb00, bMaskDWord, 0x01017018);
+ tmpReg[0] = PHY_QueryBBReg(priv, 0xbdc, bMaskDWord);
+ tmpReg[1] = PHY_QueryBBReg(priv, 0xbe8, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb00, bMaskDWord, 0x01017019);
+ tmpReg[2] = PHY_QueryBBReg(priv, 0xbdc, bMaskDWord);
+ tmpReg[3] = PHY_QueryBBReg(priv, 0xbe0, bMaskDWord);
+ tmpReg[4] = PHY_QueryBBReg(priv, 0xbe8, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb00, bMaskDWord, 0x0101701a);
+ tmpReg[5] = PHY_QueryBBReg(priv, 0xbe0, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb00, bMaskDWord, 0x0101701b);
+ tmpReg[6] = PHY_QueryBBReg(priv, 0xbdc, bMaskDWord);
+ tmpReg[7] = PHY_QueryBBReg(priv, 0xbe8, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb00, bMaskDWord, 0x0101701c);
+ tmpReg[8] = PHY_QueryBBReg(priv, 0xbe8, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb00, bMaskDWord, 0x0101701e);
+ tmpReg[9] = PHY_QueryBBReg(priv, 0xbdc, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb00, bMaskDWord, 0x0101701f);
+ tmpReg[10] = PHY_QueryBBReg(priv, 0xbe8, bMaskDWord);
+
+ //RTPRINT(FINIT, INIT_IQK, ("==>_PHY_Find_Tx_Power_Index path A\n"));
+
+ }
+ else if(path == RF92CD_PATH_B)
+ {
+ PHY_SetBBReg(priv, 0xb70, bMaskDWord, 0x01017018);
+ tmpReg[0] = PHY_QueryBBReg(priv, 0xbec, bMaskDWord);
+ tmpReg[1] = PHY_QueryBBReg(priv, 0xbf8, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb70, bMaskDWord, 0x01017019);
+ tmpReg[2] = PHY_QueryBBReg(priv, 0xbec, bMaskDWord);
+ tmpReg[3] = PHY_QueryBBReg(priv, 0xbf0, bMaskDWord);
+ tmpReg[4] = PHY_QueryBBReg(priv, 0xbf8, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb70, bMaskDWord, 0x0101701a);
+ tmpReg[5] = PHY_QueryBBReg(priv, 0xbf4, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb70, bMaskDWord, 0x0101701b);
+ tmpReg[6] = PHY_QueryBBReg(priv, 0xbec, bMaskDWord);
+ tmpReg[7] = PHY_QueryBBReg(priv, 0xbf8, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb70, bMaskDWord, 0x0101701c);
+ tmpReg[8] = PHY_QueryBBReg(priv, 0xbf8, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb70, bMaskDWord, 0x0101701e);
+ tmpReg[9] = PHY_QueryBBReg(priv, 0xbec, bMaskDWord);
+
+ PHY_SetBBReg(priv, 0xb70, bMaskDWord, 0x0101701f);
+ tmpReg[10] = PHY_QueryBBReg(priv, 0xbf8, bMaskDWord);
+
+ //RTPRINT(FINIT, INIT_IQK, ("==>_PHY_Find_Tx_Power_Index path B\n"));
+
+ }
+
+ for(i = 0; i < RegNum; i++)
+ {
+ power_I = (tmpReg[i] >> 8);
+ if(power_I & BIT(7))
+ power_I |= bMaskH3Bytes;
+
+ power_Q = tmpReg[i] & bMaskByte0;
+ if(power_Q & BIT(7))
+ power_Q |= bMaskH3Bytes;
+
+ PA_power[i] = power_I*power_I+ power_Q*power_Q;
+ }
+
+ //normalization
+ tmpBase = PA_power[0];
+ //RTPRINT(FINIT, INIT_IQK, ("==>PA_power START normalized\n"));
+
+ if(tmpBase == 0)
+ DPK_DEBUG("==>PA_power[0] is ZERO !!!!!\n");
+
+ for(i = 0; i < RegNum; i++)
+ {
+ if(tmpBase != 0)
+ PA_power[i] = (PA_power[i] << 9) /tmpBase;
+ else
+ PA_power[i] = (PA_power[i] << 9) ;
+ PA_power_normal[i] = PA_power[i];
+ PA_power[i] = (PA_power[i] > base)?(PA_power[i] - base):(base - PA_power[i]);
+ DPK_DEBUG("==>PA_power normalized index %d value 0x%x\n", i, PA_power[i]);
+ }
+
+ //choose min for TX index to do DPK
+ base = bMaskDWord;
+ for(i = 0; i < RegNum; i++)
+ {
+ if(PA_power[i] < base)
+ {
+ base = PA_power[i];
+ index = i;
+ }
+ }
+
+ if(index == -1)
+ {
+ tx_index = 0x1c;
+ index = 0x1f - tx_index;
+ }
+ else
+ {
+ tx_index += index;
+ }
+
+ DPK_DEBUG("==>tx_index result 0x%x PA_power[%d] = 0x%x\n", tx_index, index, PA_power[index]);
+
+ *tx_index_out = tx_index;
+
+ //Check pattern reliability
+ if(((PA_power_normal[index] > check_base) && (tx_index == 0x1f)) ||
+ ((PA_power_normal[10] > base) && (!bPlus3db)) ||
+ ((tx_index < 0x1a) && (!bPlus3db)) ||
+ ((tx_index < 0x13) && (bDecreaseTxIndex))
+ )
+ return FALSE;
+ else
+ return TRUE;
+// return tx_index;
+
+}
+
+unsigned char _PHY_Find_Rx_Power_Index(struct rtl8192cd_priv *priv, unsigned char tx_index, unsigned char rx_index, unsigned char path, char *bDecreaseTxIndex)
+{
+// u1Byte rx_index = 0x04;
+ unsigned int tmpReg;
+ int power_I, power_Q, tmp;
+ unsigned char bPlus = FALSE, bMinus = FALSE;
+ unsigned short offset[2][2] = {{ //path, offset
+ 0xb28, 0xbe8},{
+ 0xb98, 0xbf8}};
+
+ while (TRUE){
+ tmpReg = 0x52000 | tx_index | (rx_index << 5);
+ PHY_SetRFReg(priv, path, RF_AC, bMask20Bits, tmpReg);
+ //RTPRINT(FINIT, INIT_IQK, ("==>RF 0ffset 0 = 0x%x readback = 0x%x\n", tmpReg,
+ //PHY_QueryRFReg(pAdapter, path, RF_AC, bRFRegOffsetMask)));
+
+ //----send one shot signal----//
+ PHY_SetBBReg(priv, offset[path][0], bMaskDWord, 0x80080000); //0xb28, 0xb98
+ PHY_SetBBReg(priv, offset[path][0], bMaskDWord, 0x00080000);
+
+ _PHY_DPK_polling(priv);
+
+ tmpReg = PHY_QueryBBReg(priv, offset[path][1], bMaskDWord);
+ power_I = ((tmpReg & bMaskByte1) >> 8);
+ power_Q = tmpReg & bMaskByte0;
+
+ if(power_I & BIT(7))
+ {
+ power_I |= bMaskH3Bytes;
+ power_I = 0-power_I; //absolute value
+ }
+
+ if(power_Q & BIT(7))
+ {
+ power_Q |= bMaskH3Bytes;
+ power_Q = 0-power_Q;
+ }
+ //RTPRINT(FINIT, INIT_IQK, ("==>rx_index 0x%x I = 0x%x Q = 0x%x offset 0xbe8 = 0x%x\n", rx_index, power_I, power_Q, tmpReg));
+
+ tmp = (power_I > power_Q)? power_I:power_Q;
+
+#if 0
+ if((rx_index == 0 && tmp > 0x6f)||(rx_index == 31 && tmp < 0x50))
+ break;
+#endif
+
+ if((tmp<= 0x6f && tmp >= 0x50) )
+ {
+ break;
+ }
+ else if(tmp < 0x50)
+ {
+ bPlus = TRUE;
+ if(bMinus)
+ {
+ rx_index++;
+ break;
+ }
+// rx_index++;
+ rx_index += 2;
+ }
+ else if (tmp > 0x6f)
+ {
+ bMinus = TRUE;
+ if(bPlus)
+ {
+ rx_index--;
+ break;
+ }
+// rx_index--;
+ rx_index -= 2;
+ }
+
+ if(rx_index == 0 || rx_index == 31)
+ break;
+
+ }
+ if(rx_index == 0 && tmp > 0x6f)
+ *bDecreaseTxIndex = TRUE;
+
+ DPK_DEBUG("==>rx_index FINAL 0x%x I = 0x%x Q = 0x%x\n", rx_index, power_I, power_Q);
+
+ return rx_index;
+
+}
+
+void PHY_DPCalibrate(struct rtl8192cd_priv *priv)
+{
+ char is2T = ((priv->pmib->dot11RFEntry.macPhyMode != DUALMAC_DUALPHY) ?1 :0);
+
+ unsigned int tmpReg, value32/*, checkbit*/;
+ unsigned int AFE_backup[IQK_ADDA_REG_NUM];
+ static unsigned int AFE_REG[IQK_ADDA_REG_NUM] = {
+ rFPGA0_XCD_SwitchControl, 0xe6c, 0xe70, 0xe74, 0xe78,
+ 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c,
+ 0xed0, 0xed4, 0xed8, 0xedc, 0xee0,
+ 0xeec};
+
+ static unsigned int BB_backup[DP_BB_REG_NUM];
+ static unsigned int BB_REG[DP_BB_REG_NUM] = {
+ rOFDM0_TRxPathEnable, rFPGA0_RFMOD,
+ rOFDM0_TRMuxPar, rFPGA0_XCD_RFInterfaceSW,
+ rFPGA0_AnalogParameter4, rFPGA0_XAB_RFInterfaceSW,
+ rTxAGC_B_CCK11_A_CCK2_11
+ };
+
+ static unsigned int BB_backup_A[DP_BB_REG_NUM_A];
+ static unsigned int BB_REG_A[DP_BB_REG_NUM_A] = {
+ rFPGA0_XA_RFInterfaceOE, rTxAGC_A_Rate18_06,
+ rTxAGC_A_Rate54_24, rTxAGC_A_CCK1_Mcs32,
+ 0xe0c, rTxAGC_A_Mcs03_Mcs00,
+ rTxAGC_A_Mcs07_Mcs04, rTxAGC_A_Mcs11_Mcs08,
+ rTxAGC_A_Mcs15_Mcs12, rOFDM0_XAAGCCore1/*,
+ rBndA*/
+ };
+
+
+ static unsigned int BB_backup_B[DP_BB_REG_NUM_B];
+ static unsigned int BB_REG_B[DP_BB_REG_NUM_B] = {
+ rFPGA0_XB_RFInterfaceOE, rTxAGC_B_Rate18_06,
+ rTxAGC_B_Rate54_24, rTxAGC_B_CCK1_55_Mcs32,
+ rTxAGC_B_Mcs03_Mcs00, rTxAGC_B_Mcs07_Mcs04,
+ rTxAGC_B_Mcs11_Mcs08, rTxAGC_B_Mcs15_Mcs12,
+ rOFDM0_XBAGCCore1 /*, rBndB*/
+ };
+
+ static unsigned int BB_settings[DP_BB_REG_NUM_settings] = {
+ 0x00a05430, 0x02040000, 0x000800e4, 0x22208000,
+ 0xccf000c0/*, 0x07600760*/};
+
+ static unsigned int BB_REG_loop[DP_PATH_NUM][DP_BB_REG_NUM_loop] = {
+ {0xb00, 0xb04, 0xb28, 0xb68,
+ 0xb08, 0xb0c, 0xb10, 0xb14,
+ 0xb18, 0xb1c, 0xb20, 0xb24,
+ 0xe28, 0xb00, 0xb04, 0xb08,
+ 0xb0c, 0xb10, 0xb14, 0xb18,
+ 0xb1c, 0xb20, 0xb24, 0xb28,
+ 0xb2c, rBndA, 0xb34, 0xb38,
+ 0xb3c, 0xe28},
+ {0xb70, 0xb74, 0xb98, 0xb6C,
+ 0xb78, 0xb7c, 0xb80, 0xb84,
+ 0xb88, 0xb8c, 0xb90, 0xb94,
+ 0xe28, 0xb60, 0xb64, 0xb68,
+ 0xb6c, 0xb70, 0xb74, 0xb78,
+ 0xb7c, 0xb80, 0xb84, 0xb88,
+ 0xb8c, 0xb90, 0xb94, 0xb98,
+ 0xb9c, 0xe28}
+ };
+
+ static unsigned int BB_settings_loop[DP_BB_REG_NUM_loop] = {
+ 0x01017e18, 0xf76d9f84, 0x00080000, 0x11880000,
+ 0x41382e21, 0x5b554f48, 0x6f6b6661, 0x817d7874,
+ 0x908c8884, 0x9d9a9793, 0xaaa7a4a1, 0xb6b3b0ad,
+ 0x40000000, 0x7d327c18, 0x7e057db3, 0x7e5f7e37,
+ 0x7e967e7c, 0x7ebe7eac, 0x7ed77ecc, 0x7eee7ee4,
+ 0x7f017ef9, 0x7f0e7f07, 0x7f1c7f15, 0x7f267f20,
+ 0x7f2f7f2a, 0x7f377f34, 0x7f3e7f3b, 0x7f457f42,
+ 0x7f4b7f48, 0x00000000
+ };
+
+ static unsigned int BB_settings_loop_3db[DP_BB_REG_NUM_loop] = {
+ 0x01017e18, 0xf76d9f84, 0x00080000, 0x11880000,
+ 0x5b4e402e, 0x7f776f65, 0x9c968f88, 0xb5afa8a3,
+ 0xcac4bfb9, 0xdcd8d4ce, 0xeeeae6e2, 0xfffbf7f2,
+ 0x40000000, 0x7dfe7d32, 0x7e967e59, 0x7ed77eba,
+ 0x7efd7eeb, 0x7f1a7f0e, 0x7f2d7f25, 0x7f3c7f36,
+ 0x7f4a7f44, 0x7f547f4e, 0x7f5d7f58, 0x7f657f60,
+ 0x7f6a7f68, 0x7f717f6e, 0x7f767f73, 0x7f7b7f78,
+ 0x7f7f7f7d, 0x00000000
+ };
+
+ static unsigned int BB_settings_loop_tx[DP_BB_REG_NUM_loop] = {
+ 0x01017e18, 0xf76d9f84, 0x00080000, 0x11880000,
+ 0x21212121, 0x21212121, 0x21212121, 0x21212121,
+ 0x21212121, 0x21212121, 0x21212121, 0x21212121,
+ 0x40000000, 0x7c187c18, 0x7c187c18, 0x7c187c18,
+ 0x7c187c18, 0x7c187c18, 0x7c187c18, 0x7c187c18,
+ 0x7c187c18, 0x7c187c18, 0x7c187c18, 0x7c187c18,
+ 0x7c187c18, 0x7c187c18, 0x7c187c18, 0x7c187c18,
+ 0x7c187c18, 0x00000000
+ };
+
+ static unsigned int BB_settings_loop_tx_3db[DP_BB_REG_NUM_loop] = {
+ 0x01017e18, 0xf76d9f84, 0x00080000, 0x11880000,
+ 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e,
+ 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e,
+ 0x40000000, 0x7d327d32, 0x7d327d32, 0x7d327d32,
+ 0x7d327d32, 0x7d327d32, 0x7d327d32, 0x7d327d32,
+ 0x7d327d32, 0x7d327d32, 0x7d327d32, 0x7d327d32,
+ 0x7d327d32, 0x7d327d32, 0x7d327d32, 0x7d327d32,
+ 0x7d327d32, 0x00000000
+ };
+
+
+ //for find 2dB loss point
+ static unsigned int BB_settings_loop_tx_2[DP_BB_REG_NUM_loop] = {
+ 0x01017e18, 0xf76d9f84, 0x00080000, 0x11880000,
+ 0x41382e21, 0x5b554f48, 0x6f6b6661, 0x817d7874,
+ 0x908c8884, 0x9d9a9793, 0xaaa7a4a1, 0xb6b3b0ad,
+ 0x40000000, 0x7d327c18, 0x7e057db3, 0x7e5f7e37,
+ 0x7e967e7c, 0x7ebe7eac, 0x7ed77ecc, 0x7eee7ee4,
+ 0x7f017ef9, 0x7f0e7f07, 0x7f1c7f15, 0x7f267f20,
+ 0x7f2f7f2a, 0x7f377f34, 0x7f3e7f3b, 0x7f457f42,
+ 0x7f4b7f48, 0x00000000
+ };
+
+ //for find 2dB loss point
+ static unsigned int BB_settings_loop_tx_2_3db[DP_BB_REG_NUM_loop] = {
+ 0x01017e18, 0xf76d9f84, 0x00080000, 0x11880000,
+ 0x5b4e402e, 0x7f776f65, 0x9c968f88, 0xb5afa8a3,
+ 0xcac4bfb9, 0xdcd8d4ce, 0xeeeae6e2, 0xfffbf7f2,
+ 0x40000000, 0x7dfe7d32, 0x7e967e59, 0x7ed77eba,
+ 0x7efd7eeb, 0x7f1a7f0e, 0x7f2d7f25, 0x7f3c7f36,
+ 0x7f4a7f44, 0x7f547f4e, 0x7f5d7f58, 0x7f657f60,
+ 0x7f6a7f68, 0x7f717f6e, 0x7f767f73, 0x7f7b7f78,
+ 0x7f7f7f7d, 0x00000000
+ };
+
+
+ static unsigned int BB_settings_loop_rx[DP_BB_REG_NUM_loop_rx] = {
+ 0x01017e18, 0xf76d9f84, 0x00080000, 0x11880000,
+ 0x21212121, 0x40000000, 0x7c187c18, 0x00000000
+ };
+
+ static unsigned int BB_settings_loop_rx_3db[DP_BB_REG_NUM_loop_rx] = {
+ 0x01017e18, 0xf76d9f84, 0x00080000, 0x11880000,
+ 0x2e2e2e2e, 0x40000000, 0x7d327d32, 0x00000000
+ };
+
+ static unsigned int BB_settings_loop_pa[DP_BB_REG_NUM_loop_pa] = {
+ 0x02096eb8, 0xf76d9f84, 0x00044499, 0x02880140
+ };
+
+ static unsigned int BB_settings_loop_dp[DP_BB_REG_NUM_loop_pa] = {
+ 0x01017098, 0x776d9f84, 0x00000000, 0x08080000
+ };
+
+ unsigned int *BB_settings_temp;
+
+ static unsigned char Sram_db_settings[DP_SRAM_NUM_db] = {
+ 0xfe, 0xf0, 0xe3, 0xd6, 0xca,
+ 0xbf, 0xb4, 0xaa, 0xa0, 0x97,
+ 0x8f, 0x87, 0x7f, 0x78, 0x71,
+ 0x6b, 0x65, 0x5f, 0x5a, 0x55,
+ 0x50, 0x4c, 0x47, 0x43, 0x40,
+ 0x3c, 0x39, 0x35, 0x32, 0x2f,
+ 0x2d, 0x2a, 0x28, 0x26, 0x23,
+ 0x21, 0x20, 0x1e, 0x1c, 0x1a,
+ 0x19, 0x18, 0x16, 0x16, 0x14,
+ 0x13, 0x12, 0x11, 0x10, 0x0f,
+ 0x0e, 0x0d, 0x0c, 0x0c, 0x0b,
+ 0x0a, 0x0a, 0x09, 0x09, 0x08,
+ 0x08, 0x07, 0x07, 0x06, 0x06,
+ 0x06, 0x05, 0x05, 0x05, 0x04,
+ 0x04, 0x04, 0x04, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x01
+ };
+
+ //unsigned int pwsf[DP_SRAM_NUM];
+
+ static unsigned int offset[2][DP_OFFSET_NUM] = {{ //path, offset
+ 0xe34, 0xb28, 0xb00, 0xbdc, 0xbc0,
+ 0xbe8, rOFDM0_XATxIQImbalance, rBndA,
+ 0xb68},{
+ 0xe54, 0xb98, 0xb70, 0xbec, 0xbc4,
+ 0xbf8, rOFDM0_XBTxIQImbalance, rBndB,
+ 0xb6c}};
+
+ //unsigned char OFDM_min_index = 6, OFDM_min_index_internalPA = 3;
+ unsigned char OFDM_index[2];
+ //unsigned char retrycount = 0, retrybound = 1;
+
+ unsigned int RF_backup[DP_PATH_NUM][DP_RF_REG_NUM];
+ static unsigned int RF_REG[DP_RF_REG_NUM] = {
+ RF_TX_G3, RF_TXPA_A4, RF_RXRF_A3,
+ RF_BS_PA_APSET_G1_G4/*, RF_BS_PA_APSET_G5_G8,
+ RF_BS_PA_APSET_G9_G11*/};
+
+ static unsigned int RF_AP_curve_select[DP_AP_CUREVE_SELECT_NUM] = {
+ 0x7bdef, 0x94a52, 0xa5294/*, 0xb5ad6*/ };
+
+ static unsigned int RF_PA_BIAS[3][DP_PA_BIAS_NUM] = {{ //40MHz / 20MHz, original
+ 0xe189f, 0xa189f, 0x6189f, 0x2189f },{
+ 0xe087f, 0xa087f, 0x6087f, 0x2087f },{
+ 0xe1874, 0xa1874, 0x61874, 0x21874}};
+
+ unsigned int PA_model_backup[DP_PATH_NUM][DP_PA_MODEL_NUM];
+
+ unsigned int PA_power[DP_PATH_NUM][DP_PA_MODEL_RUN_NUM*2];
+
+#if DP_gain_loss == 1
+
+ int power_I, power_Q, coef;
+
+ int gain_loss_backup[DP_PATH_NUM][DP_PA_MODEL_NUM]; //I,Q
+
+ static unsigned int gain_loss_bound[DP_GAIN_LOSS_BOUND_NUM] = {
+ 63676, 60114 , 56751 , 53577 , 49145,
+ 47750, 45079 , 42557 , 40177 , 37929 ,
+ 35807 , 33804 , 31913, 30128
+ };
+
+ static int gain_loss_coef[DP_GAIN_LOSS_BOUND_NUM+1] = {
+ 512, 527, 543, 558, 573,
+ 589, 609, 625, 645, 666,
+ 681, 701, 722, 742, 768
+ };
+
+// BOOLEAN bNegative = FALSE;
+// unsigned char index_for_zero_db = 24, AP_curve_index = 0;
+ unsigned char GainLossIndex = 0; //0db, 0x40
+ char SramIndex = 24;
+ unsigned char /*index_for_zero_db = 6,*/ AP_curve_index = 0;
+
+#else
+
+ unsigned char index_for_zero_db = 6, AP_curve_index = 0;
+ int power_I, power_Q;
+ static unsigned int gain_loss_bound[DP_GAIN_LOSS_BOUND_NUM] = {
+ 61870, 55142, 49145, 43801, 39037,
+ 34792, 31008, 27636
+ };
+#endif
+
+ unsigned int MAC_backup[IQK_MAC_REG_NUM];
+ static unsigned int MAC_REG[IQK_MAC_REG_NUM] = {
+ 0x522, 0x550, 0x551, 0x040};
+
+ //unsigned int AFE_on_off[PATH_NUM] = {
+ // 0x04db25a4, 0x0b1b25a4}; //path A on path B path A off path B on
+
+ unsigned char path_num, /*path_bound,*/ path = RF92CD_PATH_A, i, j, tx_index, rx_index;
+ int index, index_1, index_repeat;
+
+ char bInternalPA = FALSE;
+#if (DP_gain_loss != 1)
+ char SkipStep5 = FALSE;
+#endif
+ char bPlus3db = FALSE, bDecreaseTxIndex = FALSE, bDecreaseTxIndexWithRx = FALSE;
+
+
+ DPK_DEBUG("==>_PHY_DigitalPredistortion() interface index %d is2T = %d\n", priv->pshare->wlandev_idx, is2T); //anchin
+
+ DPK_DEBUG("_PHY_DigitalPredistortion for %s\n", (is2T ? "2T2R" : "1T1R"));
+
+ DPK_DEBUG("==>_PHY_DigitalPredistortion() current thermal meter = 0x%x PG thermal meter = 0x%x bPlus3db %d\n",
+ priv->pshare->ThermalValue_DPKtrack, priv->pmib->dot11RFEntry.ther, bPlus3db);
+
+ if ((priv->pmib->dot11RFEntry.phyBandSelect!= PHY_BAND_5G)||(GET_CHIP_VER(priv)!=VERSION_8192D))
+ return;
+
+ bInternalPA = priv->pshare->rf_ft_var.use_intpa92d;
+
+ if(!is2T)
+ path_num = 1;
+ else
+ path_num = 2;
+
+ if(!bInternalPA) {
+ DPK_DEBUG("==>_PHY_DigitalPredistortion() NOT internal5G\n");
+ return;
+ }
+
+ if(priv->pshare->pwr_trk_ongoing){
+ DPK_DEBUG("==>_PHY_DigitalPredistortion() TxPowerTrackingInProgress() delay 100ms\n");
+ mod_timer(&priv->pshare->DPKTimer, jiffies + RTL_MILISECONDS_TO_JIFFIES(100));
+ return;
+ }
+
+ OFDM_index[RF92CD_PATH_A] = priv->pshare->OFDM_index[RF92CD_PATH_A];
+ OFDM_index[RF92CD_PATH_B] = priv->pshare->OFDM_index[RF92CD_PATH_B];
+
+ DPK_DEBUG("original index 0x%x \n", priv->pshare->OFDM_index[0]);
+
+ priv->pshare->bDPKworking = TRUE;
+
+ //save global setting
+ //save BB default value
+ _PHY_SaveADDARegisters(priv, BB_REG, BB_backup, DP_BB_REG_NUM);
+
+ //save MAC default value
+ _PHY_SaveMACRegisters(priv, MAC_REG, MAC_backup);
+
+ //save AFE default value
+ _PHY_SaveADDARegisters(priv, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
+
+ //save path A default value
+ //save path A BB default value
+ _PHY_SaveADDARegisters(priv, BB_REG_A, BB_backup_A, DP_BB_REG_NUM_A);
+
+ //save path B BB default value
+ if(is2T)
+ _PHY_SaveADDARegisters(priv, BB_REG_B, BB_backup_B, DP_BB_REG_NUM_B);
+
+ //save pathA/B RF default value
+ for(path=0; path<path_num; path++){
+ for(index=0; index<DP_RF_REG_NUM; index++)
+ RF_backup[path][index] = PHY_QueryRFReg(priv, path, RF_REG[index], bMaskDWord, 1);
+ }
+
+ //BB register setting
+ for(index = 0; index < DP_BB_REG_NUM_settings; index++)
+ PHY_SetBBReg(priv, BB_REG[index], bMaskDWord, BB_settings[index]);
+
+ //BB path A debug setting
+ PHY_SetBBReg(priv, rFPGA1_DebugSelect, bMaskDWord, 0x00000302);
+
+ //BB pah A register setting: fix TRSW to TX, external PA on, external LAN off
+ if(!bInternalPA)
+ {
+ PHY_SetBBReg(priv, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x07600f60);
+ PHY_SetBBReg(priv, rFPGA0_XA_RFInterfaceOE, ~(BIT8|BIT9), 0x66e60a30);
+ }
+ else
+ {
+ PHY_SetBBReg(priv, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x07600760);
+ PHY_SetBBReg(priv, rFPGA0_XA_RFInterfaceOE, ~(BIT8|BIT9), 0x66e60230);
+ }
+ PHY_SetBBReg(priv, rBndA, 0xF00000, 0x0a);
+
+ //BB pah B register setting: fix TRSW to TX, external PA off, external LNA off
+ if(is2T)
+ {
+ if(!bInternalPA)
+ {
+ PHY_SetBBReg(priv, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x0f600f60);
+ PHY_SetBBReg(priv, rFPGA0_XB_RFInterfaceOE, bMaskDWord, 0x061f0130);
+ }
+ else
+ {
+ PHY_SetBBReg(priv, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x07600760);
+ PHY_SetBBReg(priv, rFPGA0_XB_RFInterfaceOE, bMaskDWord, 0x061f0130);
+ }
+ PHY_SetBBReg(priv, rBndB, 0xF00000, 0x0a);
+ }
+
+ //MAC register setting
+ _PHY_MACSettingCalibration(priv, MAC_REG, MAC_backup);
+
+ //path A/B DPK
+ //Path-A/B AFE all on
+ for(path=0; path<path_num; path++)
+ {
+
+ //if(is2T && !pHalData->InternalPA5G[path])
+ //continue;
+
+ if(path == RF92CD_PATH_B)
+ {
+ //BB pah A register setting:fix TRSW to TX;external LNA off
+ if(!bInternalPA)
+ {
+ PHY_SetBBReg(priv, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x0f600f60);
+ PHY_SetBBReg(priv, rFPGA0_XA_RFInterfaceOE, ~(BIT8|BIT9), 0x66e60230);
+ }
+ else
+ {
+ PHY_SetBBReg(priv, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x07600760);
+ PHY_SetBBReg(priv, rFPGA0_XA_RFInterfaceOE, ~(BIT8|BIT9), 0x66e60230);
+ }
+ PHY_SetBBReg(priv, rBndA, 0xF00000, 0x0a);
+
+ //BB pah B register setting:fix TRSW to TX;external LNA off
+ if(is2T)
+ {
+ if(!bInternalPA)
+ {
+ PHY_SetBBReg(priv, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x0f600f60);
+ PHY_SetBBReg(priv, rFPGA0_XB_RFInterfaceOE, bMaskDWord, 0x061f0930);
+ }
+ else
+ {
+ PHY_SetBBReg(priv, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x07600760);
+ PHY_SetBBReg(priv, rFPGA0_XB_RFInterfaceOE, bMaskDWord, 0x061f0130);
+ }
+ PHY_SetBBReg(priv, rBndB, 0xF00000, 0x0a);
+ }
+ }
+
+ AP_curve_index = 1;
+ rx_index = 0x06;
+ bPlus3db = FALSE;
+ bDecreaseTxIndex = FALSE;
+
+ if(path == RF92CD_PATH_A)
+ {
+ _PHY_PathADDAOn(priv, AFE_REG, TRUE, is2T);
+ }
+ else
+ {
+ _PHY_PathADDAOn(priv, AFE_REG, FALSE, is2T);
+ }
+
+ if(path == RF92CD_PATH_B)
+ PHY_SetBBReg(priv, rFPGA1_DebugSelect, bMaskDWord, 0x00000303);
+
+ //path A/B RF setting
+ //internal lopback off
+ if(path == RF92CD_PATH_A && !bInternalPA)
+ {
+ PHY_SetRFReg(priv, RF92CD_PATH_A, RF_MODE1, bMask20Bits, 0x5007f);
+ PHY_SetRFReg(priv, RF92CD_PATH_A, RF_MODE2, bMask20Bits, 0x6f1f9);
+ }
+ else if(path == RF92CD_PATH_B)
+ {
+ PHY_SetRFReg(priv, RF92CD_PATH_A, RF_MODE1, bMask20Bits, 0x1000f);
+ PHY_SetRFReg(priv, RF92CD_PATH_A, RF_MODE2, bMask20Bits, 0x60103);
+ }
+
+ PHY_SetRFReg(priv, path, RF_RXRF_A3, bMask20Bits, 0xef456);
+
+ //Path A/B to standby mode
+ PHY_SetRFReg(priv, path==RF92CD_PATH_A?RF92CD_PATH_B:RF92CD_PATH_A,
+ RF_AC, bMask20Bits, 0x10000);
+
+ //set DPK PA bias table
+ index = priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40?0:1;
+ if(path == RF92CD_PATH_A)
+ {
+ for(i = 0; i < path_num; i++)
+ {
+ for(j = 0; j < DP_PA_BIAS_NUM; j++)
+ PHY_SetRFReg(priv, i, RF_TXBIAS, bMask20Bits, RF_PA_BIAS[index][j]);
+ }
+ }
+
+Step1:
+
+ DPK_DEBUG("==>AP curve select 0x%x bplus3db %d path%s!!\n", RF_AP_curve_select[AP_curve_index], bPlus3db, path==RF92CD_PATH_A?"A":"B");
+
+ //RF setting for AP curve selection
+ //default AP curve = 15
+ PHY_SetRFReg(priv, path, RF_BS_PA_APSET_G1_G4, bMask20Bits, RF_AP_curve_select[AP_curve_index]);
+
+ //////////////////////////////////////////////////
+ // step 1: find RF TX/RX index
+ /////////////////////////////////////////////////
+ //find RF TX index
+ //=============================
+ // PAGE_B for Path-A PM setting
+ //=============================
+ // open inner loopback @ b00[19]:od 0xb00 0x01097018
+ if(bPlus3db)
+ BB_settings_temp = &(BB_settings_loop_tx_3db[0]);
+ else
+ BB_settings_temp = &(BB_settings_loop_tx[0]);
+ _PHY_SetADDARegisters(priv, BB_REG_loop[path], BB_settings_temp, DP_BB_REG_NUM_loop);
+
+ if(bDecreaseTxIndex)
+ tx_index = 0x19;
+ else
+ tx_index = 0x1f;
+ bDecreaseTxIndexWithRx = FALSE;
+
+ //Set Tx GAC = 0x1f, than find Rx AGC
+ rx_index = _PHY_Find_Rx_Power_Index(priv, tx_index, rx_index, path, &bDecreaseTxIndexWithRx);
+ if(bDecreaseTxIndexWithRx)
+ {
+ if(bDecreaseTxIndex)
+ {
+ PHY_SetBBReg(priv, offset[path][2], bMaskDWord, 0x01017098); //0xb00, 0xb70
+ PHY_SetBBReg(priv, offset[path][8], bMaskDWord, 0x28080000); //0xb68, 0xb6c
+
+ for(i = 3; i < DP_RF_REG_NUM; i++)
+ PHY_SetRFReg(priv, path, RF_REG[i], bMask20Bits, RF_backup[path][i]);
+
+ //set original DPK bias table
+ for(j = 0; j < DP_PA_BIAS_NUM; j++)
+ PHY_SetRFReg(priv, path, RF_TXBIAS, bMask20Bits, RF_PA_BIAS[2][j]);
+ continue;
+ }
+ else
+ {
+ bDecreaseTxIndex = TRUE;
+ goto Step1;
+ }
+ }
+
+ //find 2dB loss point
+ //=============================
+ // PAGE_B for Path-A PM setting
+ //=============================
+ // open inner loopback @ b00[19]:od 0xb00 0x01097018
+ if(bPlus3db)
+ BB_settings_temp = &(BB_settings_loop_tx_2_3db[0]);
+ else
+ BB_settings_temp = &(BB_settings_loop_tx_2[0]);
+ _PHY_SetADDARegisters(priv, BB_REG_loop[path], BB_settings_temp, DP_BB_REG_NUM_loop);
+
+ //RF setting
+ PHY_SetRFReg(priv, path, RF_AC, bMask20Bits, 0x52000 | tx_index | (rx_index << 5));
+
+ //----send one shot signal----//
+ PHY_SetBBReg(priv, offset[path][1], bMaskDWord, 0x80080000); //0xb28, 0xb98
+ PHY_SetBBReg(priv, offset[path][1], bMaskDWord, 0x00080000);
+
+ //get power
+ if(!_PHY_Find_Tx_Power_Index(priv, PA_power[path], path, bPlus3db, bDecreaseTxIndex, &tx_index))
+ {
+ if(/*tx_index == 0x1f &&*/ !bPlus3db)
+ {
+ if(bDecreaseTxIndex)
+ {
+ if(tx_index < 0x11)
+ {
+ PHY_SetBBReg(priv, offset[path][2], bMaskDWord, 0x01017098); //0xb00, 0xb70
+ PHY_SetBBReg(priv, offset[path][8], bMaskDWord, 0x28080000); //0xb68, 0xb6c
+
+ for(i = 3; i < DP_RF_REG_NUM; i++)
+ PHY_SetRFReg(priv, path, RF_REG[i], bMask20Bits, RF_backup[path][i]);
+
+ //set original DPK bias table
+ for(j = 0; j < DP_PA_BIAS_NUM; j++)
+ PHY_SetRFReg(priv, path, RF_TXBIAS, bMask20Bits, RF_PA_BIAS[2][j]);
+
+ continue;
+ }
+ else
+ {
+ //RTPRINT(FINIT, INIT_IQK, ("==>Check pattern reliability path%s SUCCESS tx_index = 0x1b!!!!\n", path==RF90_PATH_A?"A":"B"));
+ }
+ }
+ else if(tx_index < 0x1a)
+ {
+ bDecreaseTxIndex = TRUE;
+ goto Step1;
+ }
+ else
+ {
+ bPlus3db = TRUE;
+ goto Step1;
+ }
+ }
+ else if(tx_index == 0x1f)
+ {
+ DPK_DEBUG("==>Check pattern reliability path%s FAIL!!!!\n", path==RF92CD_PATH_A?"A":"B");
+ PHY_SetBBReg(priv, offset[path][2], bMaskDWord, 0x01017098); //0xb00, 0xb70
+ PHY_SetBBReg(priv, offset[path][8], bMaskDWord, 0x28080000); //0xb68, 0xb6c
+
+ for(i = 3; i < DP_RF_REG_NUM; i++)
+ PHY_SetRFReg(priv, path, RF_REG[i], bMask20Bits, RF_backup[path][i]);
+
+ //set original DPK bias table
+ for(j = 0; j < DP_PA_BIAS_NUM; j++)
+ PHY_SetRFReg(priv, path, RF_TXBIAS, bMask20Bits, RF_PA_BIAS[2][j]);
+
+ continue;
+ }
+
+
+ }
+ else
+ {
+ DPK_DEBUG("==>Check pattern reliability path%s SUCCESS!!!!\n", path==RF92CD_PATH_A?"A":"B");
+ }
+
+ //find RF RX index
+ //=============================
+ // PAGE_B for Path-A PM setting
+ //=============================
+ // open inner loopback @ b00[19]:od 0xb00 0x01097018
+ if(bPlus3db)
+ BB_settings_temp = &(BB_settings_loop_rx_3db[0]);
+ else
+ BB_settings_temp = &(BB_settings_loop_rx[0]);
+
+ for(i = 0; i < 4; i++)
+ PHY_SetBBReg(priv, BB_REG_loop[path][i], bMaskDWord, BB_settings_temp[i]);
+ for(; i < 12; i++)
+ PHY_SetBBReg(priv, BB_REG_loop[path][i], bMaskDWord, BB_settings_temp[4]);
+ PHY_SetBBReg(priv, BB_REG_loop[path][i], bMaskDWord, BB_settings_temp[5]);
+ for(; i < 29; i++)
+ PHY_SetBBReg(priv, BB_REG_loop[path][i], bMaskDWord, BB_settings_temp[6]);
+ PHY_SetBBReg(priv, BB_REG_loop[path][i], bMaskDWord, BB_settings_temp[7]);
+
+ rx_index = _PHY_Find_Rx_Power_Index(priv, tx_index, rx_index, path, &bDecreaseTxIndex);
+
+ //////////////////////////////////////
+ //2.measure PA model
+ //////////////////////////////////////
+ //=========================================
+ //PAGE_B for Path-A PAS setting //=========================================
+ // open inner loopback @ b00[19]:10 od 0xb00 0x01097018
+ if(bPlus3db)
+ BB_settings_temp = &(BB_settings_loop_3db[0]);
+ else
+ BB_settings_temp = &(BB_settings_loop[0]);
+ _PHY_SetADDARegisters(priv, BB_REG_loop[path], BB_settings_temp, DP_BB_REG_NUM_loop);
+
+ //LNA VDD to gnd
+ PHY_SetRFReg(priv,path, RF_AC, bMask20Bits, 0x52000 | tx_index | (rx_index << 5));
+
+ //----send one shot signal----//
+ // Path A
+ PHY_SetBBReg(priv, offset[path][1], bMaskDWord, 0x80080000); //0xb28, 0xb98
+ PHY_SetBBReg(priv, offset[path][1], bMaskDWord, 0x00080000);
+
+ PHY_SetRFReg(priv, RF92CD_PATH_A, RF_T_METER, BIT17|BIT16, 0x03);
+
+ _PHY_DPK_polling(priv);
+
+ priv->pshare->ThermalValue_DPKstore = (unsigned char)PHY_QueryRFReg(priv, RF92CD_PATH_A, RF_T_METER, 0xf800, 1); //0x42: RF Reg[15:11] 92D
+
+ // read PA model and save to PA_model_A[32]
+ for(i = 0; i < DP_PA_MODEL_RUN_NUM; i++)
+ {
+ PHY_SetBBReg(priv, offset[path][2], bMaskDWord, 0x01017018+i); //0xb00, 0xb70
+ for(index = 0; index < DP_PA_MODEL_PER_RUN_NUM; index++)
+ {
+ PA_model_backup[path][i*4+index] = PHY_QueryBBReg(priv, offset[path][3]+index*4, bMaskDWord); //0xbdc, 0xbec
+ DPK_DEBUG("==>PA_model_backup index %d value 0x%x()\n", i*4+index, PA_model_backup[path][i*4+index]);
+ }
+ }
+
+#if 0
+ //find appropriate AP curve
+ if(AP_curve_index != (DP_AP_CUREVE_SELECT_NUM-1))
+ {
+ if(!_PHY_DPK_AP_curve_check(priv, PA_model_backup[path], DP_PA_MODEL_NUM))
+ {
+ DPK_DEBUG("==>find appropriate AP curve 0x%x path%s FAIL!!!!\n", RF_AP_curve_select[AP_curve_index], path==RF92CD_PATH_A?"A":"B");
+ AP_curve_index++;
+ if(AP_curve_index < DP_AP_CUREVE_SELECT_NUM)
+ goto Step1;
+ }
+ else
+ {
+ DPK_DEBUG("==>find appropriate AP curve path%s SUCCESS!!!!\n", path==RF92CD_PATH_A?"A":"B");
+ }
+ }
+#endif
+
+ //check PA model
+ if(!_PHY_DPK_check(priv, PA_model_backup[path], DP_PA_MODEL_NUM))
+ {
+ PHY_SetBBReg(priv, offset[path][2], bMaskDWord, 0x01017098); // add in 2011-06-02
+ PHY_SetBBReg(priv, offset[path][8], bMaskDWord, 0x28080000); //0xb68, 0xb6c
+
+ for(i = 3; i < DP_RF_REG_NUM; i++)
+ PHY_SetRFReg(priv, path, RF_REG[i], bMaskDWord, RF_backup[path][i]);
+ DPK_DEBUG("==>PA model path%s FAIL!!!!\n", path==RF92CD_PATH_A?"A":"B");
+ priv->pshare->bDPKdone[path] = FALSE;
+ //set original DPK bias table
+ for(j = 0; j < DP_PA_BIAS_NUM; j++)
+ PHY_SetRFReg(priv, path, RF_TXBIAS, bMask20Bits, RF_PA_BIAS[2][j]);
+
+ continue;
+ }
+ else
+ {
+ DPK_DEBUG("==>PA model path%s SUCCESS!!!!\n", path==RF92CD_PATH_A?"A":"B");
+// priv->pshare->bDPKdone[path] = TRUE;
+// priv->pshare->bDPKstore = TRUE;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // step 3: fill PA model to DP Calibration
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ //fill BB TX index for the DPK reference
+ DPK_DEBUG("==>fill PA model to DP Calibration\n");
+
+ if(path == RF92CD_PATH_A){
+ for(index = 0; index < DP_PA_MODEL_RUN_NUM; index++){
+ if(index != 3){
+ PHY_SetBBReg(priv, 0xe00+index*4, bMaskDWord, 0x3c3c3c3c);
+ } else {
+ PHY_SetBBReg(priv, 0xe00+index*4, bMaskDWord, 0x03903c3c);
+ }
+ }
+ PHY_SetBBReg(priv, 0x86c, bMaskDWord, 0x3c3c3c3c);
+ }else if (path == RF92CD_PATH_B){
+ for(index = 0; index < 4; index++) {
+ PHY_SetBBReg(priv, 0x830+index*4, bMaskDWord, 0x3c3c3c3c);
+ }
+ for(index = 0; index < 2; index++) {
+ PHY_SetBBReg(priv, 0x848+index*4, bMaskDWord, 0x3c3c3c3c);
+ }
+ for(index = 0; index < 2; index++) {
+ PHY_SetBBReg(priv, 0x868+index*4, bMaskDWord, 0x3c3c3c3c);
+ }
+ }
+
+ // SRAM boundary setting
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x40000000);
+
+ if(priv->pshare->phw->bNewTxGainTable)
+ PHY_SetBBReg(priv, offset[path][4], bMaskDWord, 0x0008421f); //0xbc0, 0xbc4
+ else
+ PHY_SetBBReg(priv, offset[path][4], bMaskDWord, 0x0009ce7f); //0xbc0, 0xbc4
+
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x00000000);
+
+ _PHY_SetADDARegisters(priv, BB_REG_loop[path], BB_settings_loop_pa, DP_BB_REG_NUM_loop_pa);
+
+ // fill PA model to page B1 registers
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x40000000);
+ for(index = 0; index < (DP_PA_MODEL_NUM/2); index++){ //path A = 0xb00, path B = 0xb60
+ PHY_SetBBReg(priv, 0xb00+index*4+path*0x60, bMaskDWord,
+ (PA_model_backup[path][index*2+1] << 16) | PA_model_backup[path][index*2]);
+ }
+ PHY_SetBBReg(priv, 0xe28, bMaskDWord, 0x00000000);
+
+ //one shot
+ PHY_SetBBReg(priv, offset[path][1], bMaskDWord, 0x80044499); //0xb28, 0xb98
+ PHY_SetBBReg(priv, offset[path][1], bMaskDWord, 0x00044499);
+
+ _PHY_DPK_polling(priv);
+
+#if 1
+ //////////////////////////////////////////////////////
+ // step 4: calculate gain loss caused by DP
+ //////////////////////////////////////////////////////
+ PHY_SetBBReg(priv, offset[path][2], bMaskDWord, 0x0029701f); //0xb00, 0xb70
+ tmpReg = PHY_QueryBBReg(priv, offset[path][5], bMaskDWord); //0xbe8, 0xbf8
+
+ power_I = (tmpReg >> 16);
+ if(power_I & BIT(15))
+ power_I |= bMaskLWord; ////////ZZZZZZZZZZZZZZZZZZ
+
+ power_Q = tmpReg & bMaskLWord;
+ if(power_Q & BIT(15))
+ power_Q |= bMaskHWord;
+
+ DPK_DEBUG("0x%x = 0x%x power_I = 0x%x power_Q = 0x%x\n", offset[path][5], tmpReg, power_I, power_Q);
+
+ tmpReg = power_I*power_I + power_Q*power_Q;
+
+ DPK_DEBUG("gain loss = 0x%x \n", tmpReg);
+
+ if(tmpReg < 26090)
+ {
+ PHY_SetBBReg(priv, offset[path][2], bMaskDWord, 0x01017098); //0xb00, 0xb70
+ PHY_SetBBReg(priv, offset[path][8], bMaskDWord, 0x28080000); //0xb68, 0xb6c
+
+ for(i = 3; i < DP_RF_REG_NUM; i++)
+ PHY_SetRFReg(priv, path, RF_REG[i], bMask20Bits, RF_backup[path][i]);
+ priv->pshare->bDPKdone[path] = FALSE;
+ //set original DPK bias table
+ for(j = 0; j < DP_PA_BIAS_NUM; j++)
+ PHY_SetRFReg(priv, path, RF_TXBIAS, bMask20Bits, RF_PA_BIAS[2][j]);
+
+ continue;
+ }
+ else
+ {
+ priv->pshare->bDPKdone[path] = TRUE;
+ priv->pshare->bDPKstore = TRUE;
+ }
+
+ for(i = 0; i < DP_GAIN_LOSS_BOUND_NUM; i++)
+ {
+#if DP_gain_loss == 1
+ if(tmpReg > gain_loss_bound[i]/* || i == (DP_GAIN_LOSS_BOUND_NUM -1)*/)
+#else
+ if(tmpReg > gain_loss_bound[i] || i == (DP_GAIN_LOSS_BOUND_NUM -1))
+#endif
+ {
+#if DP_gain_loss == 0
+ if(i == 0)
+ break;
+
+ index = OFDM_index[path] > i?OFDM_index[path]-i:0;
+ if(index < OFDM_min_index_internalPA)
+ index = OFDM_min_index_internalPA;
+ PHY_SetBBReg(priv, offset[path][6], bMaskDWord, OFDMSwingTable[index]); //0xc80, 0xc88
+ DPK_DEBUG("original index 0x%x gain_loss minus index 0x%x\n", priv->pshare->OFDM_index[0], i);
+#endif
+ break;
+ }
+ }
+
+#if DP_gain_loss == 1
+
+ DPK_DEBUG("gain_loss Compensated coefficient %d\n", gain_loss_coef[i]);
+ coef = gain_loss_coef[i];
+ GainLossIndex = i;
+ priv->pshare->OFDM_min_index_internalPA_DPK[path] = GainLossIndex == 0?0:(GainLossIndex/2+GainLossIndex%2);
+
+ //read DP LUT value from register
+ for(i = 0; i < DP_PA_MODEL_RUN_NUM; i++)
+ {
+ PHY_SetBBReg(priv, offset[path][2], bMaskDWord, 0x00297018+i); //0xb00, 0xb70
+ for(index = 0; index < DP_PA_MODEL_PER_RUN_NUM; index++)
+ {
+ tmpReg = (i == 0 && index==0)?0x01000000:PHY_QueryBBReg(priv, offset[path][3]+index*4, bMaskDWord); //0xbdc, 0xbec
+
+ gain_loss_backup[1][i*4+index] = (tmpReg >> 16); //I
+ if(gain_loss_backup[1][i*4+index] & BIT(15))
+ gain_loss_backup[1][i*4+index] |= bMaskHWord;
+
+ gain_loss_backup[0][i*4+index] = (tmpReg & bMaskLWord); //Q
+ if(gain_loss_backup[0][i*4+index] & BIT(15))
+ gain_loss_backup[0][i*4+index] |= bMaskHWord;
+ DPK_DEBUG("==>DP LUT index %d value 0x%x() I = 0x%x, Q = 0x%x\n", i*4+index, tmpReg, gain_loss_backup[1][i*4+index], gain_loss_backup[0][i*4+index]);
+
+ //gain * LUT
+ for(j = 0; j < 2; j++)
+ {
+ // RTPRINT(FINIT, INIT_IQK, ("==>0DP LUT sram %s index %d value %d()\n", j == 0?"Q":"I", i*4+index, gain_loss_backup[j][i*4+index]));
+
+ gain_loss_backup[j][i*4+index] = (gain_loss_backup[j][i*4+index] * coef) / (int)(512);
+ // RTPRINT(FINIT, INIT_IQK, ("==>1DP LUT sram %s index %d value 0x%x()\n", j == 0?"Q":"I", i*4+index, gain_loss_backup[j][i*4+index]));
+
+ gain_loss_backup[j][i*4+index] = gain_loss_backup[j][i*4+index] >= (int)(512)?(int)(511):gain_loss_backup[j][i*4+index] < (int)(-512)?(int)(-512):gain_loss_backup[j][i*4+index];
+ // RTPRINT(FINIT, INIT_IQK, ("==>2DP LUT sram %s index %d value 0x%x()\n", j == 0?"Q":"I", i*4+index, gain_loss_backup[j][i*4+index]));
+
+ gain_loss_backup[j][i*4+index] = gain_loss_backup[j][i*4+index] >> 2;
+ // RTPRINT(FINIT, INIT_IQK, ("==>3DP LUT sram %s index %d value 0x%x()\n", j == 0?"Q":"I", i*4+index, gain_loss_backup[j][i*4+index]));
+
+ }
+ tmpReg = ((gain_loss_backup[1][i*4+index] & bMaskByte0) << 8 ) | ((gain_loss_backup[0][i*4+index] & bMaskByte0));
+ gain_loss_backup[0][i*4+index] = tmpReg & bMaskLWord;
+ DPK_DEBUG("==>DP LUT sram index %d value 0x%x()\n", i*4+index, tmpReg);
+ }
+ }
+
+ //write DP LUT into sram
+ for(i = 0; i < DP_PA_MODEL_NUM; i++)
+ {
+ value32 = (path==RF92CD_PATH_A?((i%2 == 0)?0x01000000:0x02000000):
+ ((i%2 == 0)?0x04000000:0x08000000)) |
+ gain_loss_backup[0][(DP_PA_MODEL_NUM-1)-i] |( (i/2) << 16);
+ DPK_DEBUG("0xb2c value = 0x%x\n", value32);
+ PHY_SetBBReg(priv, 0xb2c , bMaskDWord, value32);
+ }
+// PHY_SetBBReg(priv, 0xb2c , bMaskDWord, 0x00000000);
+
+#endif
+
+#endif
+
+ ///////////////////////////////////////////////////////////////
+ // step 5: Enable Digital Predistortion
+ ///////////////////////////////////////////////////////////////
+ // LUT from sram
+#if DP_gain_loss == 1
+ {
+ _PHY_SetADDARegisters(priv, BB_REG_loop[path], BB_settings_loop_dp, DP_BB_REG_NUM_loop_pa);
+
+ // pwsf boundary
+ PHY_SetBBReg(priv, offset[path][7], bMaskDWord, 0x000fffff); //0xb30, 0xba0
+
+ // write pwsf to sram
+ //find tx_index index value
+ SramIndex = 24; //restore default value
+ SramIndex -= GainLossIndex;
+ if(bPlus3db)
+ SramIndex += 3*4;
+
+ SramIndex = SramIndex >= DP_SRAM_NUM_db?DP_SRAM_NUM_db-1:(SramIndex<0?0:SramIndex);
+
+ DPK_DEBUG("tx_index = 0x%x, sram value 0x%x gainloss index %d bPlus3db %d\n", tx_index, Sram_db_settings[SramIndex], GainLossIndex, bPlus3db);
+
+ index = 0x1f - tx_index;
+ if(SramIndex >= index*4)
+ {
+ index = SramIndex - index*4;
+ index_repeat = -2;
+ SramIndex = -2;
+ }
+ else
+ {
+ index_repeat = index - SramIndex/4;
+ SramIndex %= 4;
+ index = 0;
+ }
+
+ index = index >= DP_SRAM_NUM_db?DP_SRAM_NUM_db-1:index;
+ if(index_repeat == 1)
+ index_1 = SramIndex;
+ else
+ index_1 = index < (DP_SRAM_NUM_db-1)?(index_repeat==-2?index+1*4:index):index;
+
+ DPK_DEBUG("0x1f value = 0x%x, index 0x%x repeat %d SramIndex %d\n", Sram_db_settings[index], index, index_repeat, SramIndex);
+
+ for(i = 0; i < DP_SRAM_NUM; i++)
+ {
+ value32 = (path==RF92CD_PATH_A?0x10000000:0x20000000) | (i << 16) |
+ (Sram_db_settings[index_1] << 8 )| Sram_db_settings[index];
+ DPK_DEBUG("0xb2c value = 0x%x\n", value32);
+
+ PHY_SetBBReg(priv, 0xb2c , bMaskDWord, value32);
+ if(index_repeat >= 0)
+ index_repeat -= 2;
+ else if(index_repeat == -1)
+ index_repeat = -2;
+
+ if((index < (DP_SRAM_NUM_db-1)-1))
+ {
+ if(index_repeat == -2)
+ {
+ index+=2*4;
+ index_1 = index < (DP_SRAM_NUM_db-1)?index+1*4:index;
+ }
+ if(index_repeat == 0)
+ {
+ index = SramIndex;
+ index_1 = index < (DP_SRAM_NUM_db-1)?index+1*4:index;
+ }
+ else if(index_repeat == 1)
+ {
+ index_1 = SramIndex;
+ }
+ else if(index_repeat == -1)
+ {
+ index = index_1+1*4;
+ index_1 = index < (DP_SRAM_NUM_db-1)?index+1*4:index;
+ }
+ }
+ else
+ {
+ index = index_1 = (DP_SRAM_NUM_db-1);
+ }
+
+ index = index < DP_SRAM_NUM_db?index:DP_SRAM_NUM_db-1;
+ index_1 = index_1 < DP_SRAM_NUM_db?index_1:DP_SRAM_NUM_db-1;
+ }
+ }
+#else
+ if(!SkipStep5)
+ {
+ _PHY_SetADDARegisters(priv, BB_REG_loop[path], BB_settings_loop_dp, DP_BB_REG_NUM_loop_pa);
+
+ // pwsf boundary
+ PHY_SetBBReg(priv, offset[path][7], bMaskDWord, 0x000fffff); //0xb30, 0xba0
+
+ // write pwsf to sram
+ //find RF0x1f index value
+ if(bPlus3db)
+ tx_index += 3;
+
+// tx_index = 0x21;
+
+ index = 0x1f - tx_index;
+ if(index_for_zero_db >= index)
+ {
+ index = index_for_zero_db - index;
+ index_repeat = -2;
+ }
+ else
+ {
+ index_repeat = index - index_for_zero_db;
+ index = 0;
+ }
+
+ index = index >= DP_SRAM_NUM_db?DP_SRAM_NUM_db-1:index;
+ index_1 = index < (DP_SRAM_NUM_db-1)?(index_repeat==-2?index+1:index):index;
+
+ DPK_DEBUG("0x1f value = 0x%x, index 0x%x repeat %d\n", Sram_db_settings[index], index, index_repeat);
+
+ for(i = 0; i < DP_SRAM_NUM; i++)
+ {
+ value32 = (path==RF92CD_PATH_A?0x10000000:0x20000000) | (i << 16) |
+ (Sram_db_settings[index_1] << 8 )| Sram_db_settings[index];
+ DPK_DEBUG("0xb2c value = 0x%x\n", value32);
+
+ PHY_SetBBReg(priv, 0xb2c , bMaskDWord, value32);
+ if(index_repeat >= 0)
+ index_repeat -= 2;
+ else if(index_repeat == -1)
+ index_repeat = -2;
+
+ if((index < (DP_SRAM_NUM_db-1)-1))
+ {
+ if(index_repeat == -2)
+ {
+ index += 2;
+ index_1 = index < (DP_SRAM_NUM_db-1)?index+1:index;
+ }
+ if(index_repeat == 0)
+ {
+ index_1 = index < (DP_SRAM_NUM_db-1)?index+1:index;
+ }
+ else if(index_repeat == -1)
+ {
+ index++;
+ index_1 = index < (DP_SRAM_NUM_db-1)?index+1:index;
+ }
+ }
+ else
+ {
+ index = index_1 = (DP_SRAM_NUM_db-1);
+ }
+ }
+ }
+#endif
+ }
+
+ //reload RF default value
+ for(path = 0; path<path_num; path++){
+ for( i = 2 ; i < 3 ; i++){
+ PHY_SetRFReg(priv, path, RF_REG[i], bMask20Bits, RF_backup[path][i]);
+ }
+ }
+
+ //Reload standby mode default value (if path B excute DPK)
+ if(is2T && priv->pshare->phw->InternalPA5G[RF92CD_PATH_B])
+ {
+ PHY_SetRFReg(priv, RF92CD_PATH_A, RF_MODE1, bMask20Bits, 0x1000f);
+ PHY_SetRFReg(priv, RF92CD_PATH_A, RF_MODE2, bMask20Bits, 0x60101);
+ }
+
+ //reload BB default value
+ for(index=0; index<DP_BB_REG_NUM; index++)
+ PHY_SetBBReg(priv, BB_REG[index], bMaskDWord, BB_backup[index]);
+
+ //external LNA on
+ PHY_SetBBReg(priv, rBndA, 0xF00000, 0x00);
+
+ if(is2T)
+ PHY_SetBBReg(priv, rBndB, 0xF00000, 0x00);
+
+ //Reload path A BB default value
+ _PHY_ReloadADDARegisters(priv, BB_REG_A, BB_backup_A, DP_BB_REG_NUM_A);
+
+
+#if 1 //Return to Rx mode after dpk
+ //printk("BB_REG_A[9] 0x%x BB_backup_A[9] 0x%x\n\n", BB_REG_A[9], BB_backup_A[9]);
+ PHY_SetBBReg(priv, BB_REG_A[9], bMaskByte0, 0x50);
+ PHY_SetBBReg(priv, BB_REG_A[9], bMaskDWord, BB_backup_A[9]);
+#endif
+
+ //Reload path B default value
+ if(is2T)
+ _PHY_ReloadADDARegisters(priv, BB_REG_B, BB_backup_B, DP_BB_REG_NUM_B);
+
+#if 1 //Return to Rx mode after dpk
+ //printk("BB_REG_B[8] 0x%x BB_backup_B[8] 0x%x\n\n", BB_REG_B[8], BB_backup_B[8]);
+ PHY_SetBBReg(priv, BB_REG_B[8], bMaskByte0, 0x50);
+ PHY_SetBBReg(priv, BB_REG_B[8], bMaskDWord, BB_backup_B[8]);
+#endif
+
+ //reload AFE default value
+ _PHY_ReloadADDARegisters(priv, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
+
+ //reload MAC default value
+ _PHY_ReloadMACRegisters(priv, MAC_REG, MAC_backup);
+
+ priv->pshare->bDPKworking = FALSE;
+
+ DPK_DEBUG("<==_PHY_DigitalPredistortion()\n");
+}
+
+#endif
+#endif
+
+#endif