Path: blob/master/ALFA-W1F1/RTL8814AU/hal/phydm/phydm_antdect.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13* The full GNU General Public License is included in this distribution in the14* file called LICENSE.15*16* Contact Information:17* wlanfae <[email protected]>18* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,19* Hsinchu 300, Taiwan.20*21* Larry Finger <[email protected]>22*23*****************************************************************************/2425/* ************************************************************26* include files27* ************************************************************ */2829#include "mp_precomp.h"30#include "phydm_precomp.h"3132#ifdef CONFIG_ANT_DETECTION3334/* @IS_ANT_DETECT_SUPPORT_SINGLE_TONE(adapter)35* IS_ANT_DETECT_SUPPORT_RSSI(adapter)36* IS_ANT_DETECT_SUPPORT_PSD(adapter) */3738/* @1 [1. Single Tone method] =================================================== */3940/*@41* Description:42* Set Single/Dual Antenna default setting for products that do not do detection in advance.43*44* Added by Joseph, 2012.03.2245* */46void odm_sw_ant_div_construct_scan_chnl(47void *adapter,48u8 scan_chnl)49{50}5152u8 odm_sw_ant_div_select_scan_chnl(53void *adapter)54{55return 0;56}5758void odm_single_dual_antenna_default_setting(59void *dm_void)60{61struct dm_struct *dm = (struct dm_struct *)dm_void;62struct sw_antenna_switch *dm_swat_table = &dm->dm_swat_table;63void *adapter = dm->adapter;6465u8 bt_ant_num = BT_GetPgAntNum(adapter);66/* Set default antenna A and B status */67if (bt_ant_num == 2) {68dm_swat_table->ANTA_ON = true;69dm_swat_table->ANTB_ON = true;7071} else if (bt_ant_num == 1) {72/* Set antenna A as default */73dm_swat_table->ANTA_ON = true;74dm_swat_table->ANTB_ON = false;7576} else77RT_ASSERT(false, ("Incorrect antenna number!!\n"));78}7980/* @2 8723A ANT DETECT81*82* Description:83* Implement IQK single tone for RF DPK loopback and BB PSD scanning.84* This function is cooperated with BB team Neil.85*86* Added by Roger, 2011.12.1587* */88boolean89odm_single_dual_antenna_detection(90void *dm_void,91u8 mode)92{93struct dm_struct *dm = (struct dm_struct *)dm_void;94void *adapter = dm->adapter;95struct sw_antenna_switch *dm_swat_table = &dm->dm_swat_table;96u32 current_channel, rf_loop_reg;97u8 n;98u32 reg88c, regc08, reg874, regc50, reg948, regb2c, reg92c, reg930, reg064, afe_rrx_wait_cca;99u8 initial_gain = 0x5a;100u32 PSD_report_tmp;101u32 ant_a_report = 0x0, ant_b_report = 0x0, ant_0_report = 0x0;102boolean is_result = true;103104PHYDM_DBG(dm, DBG_ANT_DIV, "%s============>\n", __func__);105106if (!(dm->support_ic_type & ODM_RTL8723B))107return is_result;108109/* Retrieve antenna detection registry info, added by Roger, 2012.11.27. */110if (!IS_ANT_DETECT_SUPPORT_SINGLE_TONE(((PADAPTER)adapter)))111return is_result;112113/* @1 Backup Current RF/BB Settings */114115current_channel = odm_get_rf_reg(dm, RF_PATH_A, ODM_CHANNEL, RFREGOFFSETMASK);116rf_loop_reg = odm_get_rf_reg(dm, RF_PATH_A, RF_0x00, RFREGOFFSETMASK);117if (dm->support_ic_type & ODM_RTL8723B) {118reg92c = odm_get_bb_reg(dm, REG_DPDT_CONTROL, MASKDWORD);119reg930 = odm_get_bb_reg(dm, rfe_ctrl_anta_src, MASKDWORD);120reg948 = odm_get_bb_reg(dm, REG_S0_S1_PATH_SWITCH, MASKDWORD);121regb2c = odm_get_bb_reg(dm, REG_AGC_TABLE_SELECT, MASKDWORD);122reg064 = odm_get_mac_reg(dm, REG_SYM_WLBT_PAPE_SEL, BIT(29));123odm_set_bb_reg(dm, REG_DPDT_CONTROL, 0x3, 0x1);124odm_set_bb_reg(dm, rfe_ctrl_anta_src, 0xff, 0x77);125odm_set_mac_reg(dm, REG_SYM_WLBT_PAPE_SEL, BIT(29), 0x1); /* @dbg 7 */126odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, 0x3c0, 0x0); /* @dbg 8 */127odm_set_bb_reg(dm, REG_AGC_TABLE_SELECT, BIT(31), 0x0);128}129130ODM_delay_us(10);131132/* Store A path Register 88c, c08, 874, c50 */133reg88c = odm_get_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, MASKDWORD);134regc08 = odm_get_bb_reg(dm, REG_OFDM_0_TR_MUX_PAR, MASKDWORD);135reg874 = odm_get_bb_reg(dm, REG_FPGA0_XCD_RF_INTERFACE_SW, MASKDWORD);136regc50 = odm_get_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, MASKDWORD);137138/* Store AFE Registers */139if (dm->support_ic_type & ODM_RTL8723B)140afe_rrx_wait_cca = odm_get_bb_reg(dm, REG_RX_WAIT_CCA, MASKDWORD);141142/* Set PSD 128 pts */143odm_set_bb_reg(dm, REG_FPGA0_PSD_FUNCTION, BIT(14) | BIT15, 0x0); /* @128 pts */144145/* To SET CH1 to do */146odm_set_rf_reg(dm, RF_PATH_A, ODM_CHANNEL, RFREGOFFSETMASK, 0x7401); /* @channel 1 */147148/* @AFE all on step */149if (dm->support_ic_type & ODM_RTL8723B)150odm_set_bb_reg(dm, REG_RX_WAIT_CCA, MASKDWORD, 0x01c00016);151152/* @3 wire Disable */153odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, MASKDWORD, 0xCCF000C0);154155/* @BB IQK setting */156odm_set_bb_reg(dm, REG_OFDM_0_TR_MUX_PAR, MASKDWORD, 0x000800E4);157odm_set_bb_reg(dm, REG_FPGA0_XCD_RF_INTERFACE_SW, MASKDWORD, 0x22208000);158159/* @IQK setting tone@ 4.34Mhz */160odm_set_bb_reg(dm, REG_TX_IQK_TONE_A, MASKDWORD, 0x10008C1C);161odm_set_bb_reg(dm, REG_TX_IQK, MASKDWORD, 0x01007c00);162163/* Page B init */164odm_set_bb_reg(dm, REG_CONFIG_ANT_A, MASKDWORD, 0x00080000);165odm_set_bb_reg(dm, REG_CONFIG_ANT_A, MASKDWORD, 0x0f600000);166odm_set_bb_reg(dm, REG_RX_IQK, MASKDWORD, 0x01004800);167odm_set_bb_reg(dm, REG_RX_IQK_TONE_A, MASKDWORD, 0x10008c1f);168if (dm->support_ic_type & ODM_RTL8723B) {169odm_set_bb_reg(dm, REG_TX_IQK_PI_A, MASKDWORD, 0x82150016);170odm_set_bb_reg(dm, REG_RX_IQK_PI_A, MASKDWORD, 0x28150016);171}172odm_set_bb_reg(dm, REG_IQK_AGC_RSP, MASKDWORD, 0x001028d0);173odm_set_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, 0x7f, initial_gain);174175/* @IQK Single tone start */176odm_set_bb_reg(dm, REG_FPGA0_IQK, 0xffffff00, 0x808000);177odm_set_bb_reg(dm, REG_IQK_AGC_PTS, MASKDWORD, 0xf9000000);178odm_set_bb_reg(dm, REG_IQK_AGC_PTS, MASKDWORD, 0xf8000000);179180ODM_delay_us(10000);181182/* PSD report of antenna A */183PSD_report_tmp = 0x0;184for (n = 0; n < 2; n++) {185PSD_report_tmp = phydm_get_psd_data(dm, 14, initial_gain);186if (PSD_report_tmp > ant_a_report)187ant_a_report = PSD_report_tmp;188}189190/* @change to Antenna B */191if (dm->support_ic_type & ODM_RTL8723B) {192#if 0193/* odm_set_bb_reg(dm, REG_DPDT_CONTROL, 0x3, 0x2); */194#endif195odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, 0xfff, 0x280);196odm_set_bb_reg(dm, REG_AGC_TABLE_SELECT, BIT(31), 0x1);197}198199ODM_delay_us(10);200201/* PSD report of antenna B */202PSD_report_tmp = 0x0;203for (n = 0; n < 2; n++) {204PSD_report_tmp = phydm_get_psd_data(dm, 14, initial_gain);205if (PSD_report_tmp > ant_b_report)206ant_b_report = PSD_report_tmp;207}208209/* @Close IQK Single Tone function */210odm_set_bb_reg(dm, REG_FPGA0_IQK, 0xffffff00, 0x000000);211212/* @1 Return to antanna A */213if (dm->support_ic_type & ODM_RTL8723B) {214/* @external DPDT */215odm_set_bb_reg(dm, REG_DPDT_CONTROL, MASKDWORD, reg92c);216217/* @internal S0/S1 */218odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, MASKDWORD, reg948);219odm_set_bb_reg(dm, REG_AGC_TABLE_SELECT, MASKDWORD, regb2c);220odm_set_bb_reg(dm, rfe_ctrl_anta_src, MASKDWORD, reg930);221odm_set_mac_reg(dm, REG_SYM_WLBT_PAPE_SEL, BIT(29), reg064);222}223224odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, MASKDWORD, reg88c);225odm_set_bb_reg(dm, REG_OFDM_0_TR_MUX_PAR, MASKDWORD, regc08);226odm_set_bb_reg(dm, REG_FPGA0_XCD_RF_INTERFACE_SW, MASKDWORD, reg874);227odm_set_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, 0x7F, 0x40);228odm_set_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, MASKDWORD, regc50);229odm_set_rf_reg(dm, RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, current_channel);230odm_set_rf_reg(dm, RF_PATH_A, RF_0x00, RFREGOFFSETMASK, rf_loop_reg);231232/* Reload AFE Registers */233if (dm->support_ic_type & ODM_RTL8723B)234odm_set_bb_reg(dm, REG_RX_WAIT_CCA, MASKDWORD, afe_rrx_wait_cca);235236if (dm->support_ic_type & ODM_RTL8723B) {237PHYDM_DBG(dm, DBG_ANT_DIV, "psd_report_A[%d]= %d\n", 2416,238ant_a_report);239PHYDM_DBG(dm, DBG_ANT_DIV, "psd_report_B[%d]= %d\n", 2416,240ant_b_report);241242/* @2 Test ant B based on ant A is ON */243if (ant_a_report >= 100 && ant_b_report >= 100 && ant_a_report <= 135 && ant_b_report <= 135) {244u8 TH1 = 2, TH2 = 6;245246if ((ant_a_report - ant_b_report < TH1) || (ant_b_report - ant_a_report < TH1)) {247dm_swat_table->ANTA_ON = true;248dm_swat_table->ANTB_ON = true;249PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Dual Antenna\n",250__func__);251} else if (((ant_a_report - ant_b_report >= TH1) && (ant_a_report - ant_b_report <= TH2)) ||252((ant_b_report - ant_a_report >= TH1) && (ant_b_report - ant_a_report <= TH2))) {253dm_swat_table->ANTA_ON = false;254dm_swat_table->ANTB_ON = false;255is_result = false;256PHYDM_DBG(dm, DBG_ANT_DIV,257"%s: Need to check again\n",258__func__);259} else {260dm_swat_table->ANTA_ON = true;261dm_swat_table->ANTB_ON = false;262PHYDM_DBG(dm, DBG_ANT_DIV,263"%s: Single Antenna\n", __func__);264}265dm->ant_detected_info.is_ant_detected = true;266dm->ant_detected_info.db_for_ant_a = ant_a_report;267dm->ant_detected_info.db_for_ant_b = ant_b_report;268dm->ant_detected_info.db_for_ant_o = ant_0_report;269270} else {271PHYDM_DBG(dm, DBG_ANT_DIV, "return false!!\n");272is_result = false;273}274}275return is_result;276}277278/* @1 [2. Scan AP RSSI method] ================================================== */279280boolean281odm_sw_ant_div_check_before_link(282void *dm_void)283{284#if (RT_MEM_SIZE_LEVEL != RT_MEM_SIZE_MINIMUM)285286struct dm_struct *dm = (struct dm_struct *)dm_void;287void *adapter = dm->adapter;288HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));289//PMGNT_INFO mgnt_info = &adapter->MgntInfo;290PMGNT_INFO mgnt_info = &(((PADAPTER)(adapter))->MgntInfo);291struct sw_antenna_switch *dm_swat_table = &dm->dm_swat_table;292struct phydm_fat_struct *fat_tab = &dm->dm_fat_table;293s8 score = 0;294PRT_WLAN_BSS p_tmp_bss_desc, p_test_bss_desc;295u8 power_target_L = 9, power_target_H = 16;296u8 tmp_power_diff = 0, power_diff = 0, avg_power_diff = 0, max_power_diff = 0, min_power_diff = 0xff;297u16 index, counter = 0;298static u8 scan_channel;299u32 tmp_swas_no_link_bk_reg948;300301PHYDM_DBG(dm, DBG_ANT_DIV, "ANTA_ON = (( %d )) , ANTB_ON = (( %d ))\n",302dm->dm_swat_table.ANTA_ON, dm->dm_swat_table.ANTB_ON);303304/* @if(HP id) */305{306if (dm->dm_swat_table.rssi_ant_dect_result == true && dm->support_ic_type == ODM_RTL8723B) {307PHYDM_DBG(dm, DBG_ANT_DIV,308"8723B RSSI-based Antenna Detection is done\n");309return false;310}311312if (dm->support_ic_type == ODM_RTL8723B) {313if (dm_swat_table->swas_no_link_bk_reg948 == 0xff)314dm_swat_table->swas_no_link_bk_reg948 = odm_read_4byte(dm, REG_S0_S1_PATH_SWITCH);315}316}317318if (dm->adapter == NULL) { /* @For BSOD when plug/unplug fast. //By YJ,120413 */319/* The ODM structure is not initialized. */320return false;321}322323/* Retrieve antenna detection registry info, added by Roger, 2012.11.27. */324if (!IS_ANT_DETECT_SUPPORT_RSSI(((PADAPTER)adapter)))325return false;326else327PHYDM_DBG(dm, DBG_ANT_DIV, "Antenna Detection: RSSI method\n");328329/* Since driver is going to set BB register, it shall check if there is another thread controlling BB/RF. */330odm_acquire_spin_lock(dm, RT_RF_STATE_SPINLOCK);331if (hal_data->eRFPowerState != eRfOn || mgnt_info->RFChangeInProgress || mgnt_info->bMediaConnect) {332odm_release_spin_lock(dm, RT_RF_STATE_SPINLOCK);333334PHYDM_DBG(dm, DBG_ANT_DIV,335"%s: rf_change_in_progress(%x), e_rf_power_state(%x)\n",336__func__, mgnt_info->RFChangeInProgress,337hal_data->eRFPowerState);338339dm_swat_table->swas_no_link_state = 0;340341return false;342} else343odm_release_spin_lock(dm, RT_RF_STATE_SPINLOCK);344PHYDM_DBG(dm, DBG_ANT_DIV, "dm_swat_table->swas_no_link_state = %d\n",345dm_swat_table->swas_no_link_state);346/* @1 Run AntDiv mechanism "Before Link" part. */347if (dm_swat_table->swas_no_link_state == 0) {348/* @1 Prepare to do Scan again to check current antenna state. */349350/* Set check state to next step. */351dm_swat_table->swas_no_link_state = 1;352353/* @Copy Current Scan list. */354mgnt_info->tmpNumBssDesc = mgnt_info->NumBssDesc;355PlatformMoveMemory((void *)mgnt_info->tmpbssDesc, (void *)mgnt_info->bssDesc, sizeof(RT_WLAN_BSS) * MAX_BSS_DESC);356357/* @Go back to scan function again. */358PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Scan one more time\n",359__func__);360mgnt_info->ScanStep = 0;361mgnt_info->bScanAntDetect = true;362scan_channel = odm_sw_ant_div_select_scan_chnl(adapter);363364if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8821)) {365if (fat_tab->rx_idle_ant == MAIN_ANT)366odm_update_rx_idle_ant(dm, AUX_ANT);367else368odm_update_rx_idle_ant(dm, MAIN_ANT);369if (scan_channel == 0) {370PHYDM_DBG(dm, DBG_ANT_DIV,371"%s: No AP List Avaiable, Using ant(%s)\n",372__func__,373(fat_tab->rx_idle_ant == MAIN_ANT) ?374"AUX_ANT" : "MAIN_ANT");375376if (IS_5G_WIRELESS_MODE(mgnt_info->dot11CurrentWirelessMode)) {377dm_swat_table->ant_5g = fat_tab->rx_idle_ant;378PHYDM_DBG(dm, DBG_ANT_DIV, "dm_swat_table->ant_5g=%s\n", (fat_tab->rx_idle_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT");379} else {380dm_swat_table->ant_2g = fat_tab->rx_idle_ant;381PHYDM_DBG(dm, DBG_ANT_DIV, "dm_swat_table->ant_2g=%s\n", (fat_tab->rx_idle_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT");382}383return false;384}385386PHYDM_DBG(dm, DBG_ANT_DIV,387"%s: Change to %s for testing.\n", __func__,388((fat_tab->rx_idle_ant == MAIN_ANT) ?389"MAIN_ANT" : "AUX_ANT"));390} else if (dm->support_ic_type & (ODM_RTL8723B)) {391/*Switch Antenna to another one.*/392393tmp_swas_no_link_bk_reg948 = odm_read_4byte(dm, REG_S0_S1_PATH_SWITCH);394395if (dm_swat_table->cur_antenna == MAIN_ANT && tmp_swas_no_link_bk_reg948 == 0x200) {396odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, 0xfff, 0x280);397odm_set_bb_reg(dm, REG_AGC_TABLE_SELECT, BIT(31), 0x1);398dm_swat_table->cur_antenna = AUX_ANT;399} else {400PHYDM_DBG(dm, DBG_ANT_DIV,401"Reg[948]= (( %x )) was in wrong state\n",402tmp_swas_no_link_bk_reg948);403return false;404}405ODM_delay_us(10);406407PHYDM_DBG(dm, DBG_ANT_DIV,408"%s: Change to (( %s-ant)) for testing.\n",409__func__,410(dm_swat_table->cur_antenna == MAIN_ANT) ?411"MAIN" : "AUX");412}413414odm_sw_ant_div_construct_scan_chnl(adapter, scan_channel);415PlatformSetTimer(adapter, &mgnt_info->ScanTimer, 5);416417return true;418} else { /* @dm_swat_table->swas_no_link_state == 1 */419/* @1 ScanComple() is called after antenna swiched. */420/* @1 Check scan result and determine which antenna is going */421/* @1 to be used. */422423PHYDM_DBG(dm, DBG_ANT_DIV, " tmp_num_bss_desc= (( %d ))\n",424mgnt_info->tmpNumBssDesc); /* @debug for Dino */425426for (index = 0; index < mgnt_info->tmpNumBssDesc; index++) {427p_tmp_bss_desc = &mgnt_info->tmpbssDesc[index]; /* @Antenna 1 */428p_test_bss_desc = &mgnt_info->bssDesc[index]; /* @Antenna 2 */429430if (PlatformCompareMemory(p_test_bss_desc->bdBssIdBuf, p_tmp_bss_desc->bdBssIdBuf, 6) != 0) {431PHYDM_DBG(dm, DBG_ANT_DIV,432"%s: ERROR!! This shall not happen.\n",433__func__);434continue;435}436437if (dm->support_ic_type != ODM_RTL8723B) {438if (p_tmp_bss_desc->ChannelNumber == scan_channel) {439if (p_tmp_bss_desc->RecvSignalPower > p_test_bss_desc->RecvSignalPower) {440PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Compare scan entry: score++\n", __func__);441RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", p_tmp_bss_desc->bdSsIdBuf, p_tmp_bss_desc->bdSsIdLen);442PHYDM_DBG(dm, DBG_ANT_DIV, "at ch %d, Original: %d, Test: %d\n\n", p_tmp_bss_desc->ChannelNumber, p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);443444score++;445PlatformMoveMemory(p_test_bss_desc, p_tmp_bss_desc, sizeof(RT_WLAN_BSS));446} else if (p_tmp_bss_desc->RecvSignalPower < p_test_bss_desc->RecvSignalPower) {447PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Compare scan entry: score--\n", __func__);448RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", p_tmp_bss_desc->bdSsIdBuf, p_tmp_bss_desc->bdSsIdLen);449PHYDM_DBG(dm, DBG_ANT_DIV, "at ch %d, Original: %d, Test: %d\n\n", p_tmp_bss_desc->ChannelNumber, p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);450score--;451} else {452if (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp < 5000) {453RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", p_tmp_bss_desc->bdSsIdBuf, p_tmp_bss_desc->bdSsIdLen);454PHYDM_DBG(dm, DBG_ANT_DIV, "at ch %d, Original: %d, Test: %d\n", p_tmp_bss_desc->ChannelNumber, p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);455PHYDM_DBG(dm, DBG_ANT_DIV, "The 2nd Antenna didn't get this AP\n\n");456}457}458}459} else { /* @8723B */460if (p_tmp_bss_desc->ChannelNumber == scan_channel) {461PHYDM_DBG(dm, DBG_ANT_DIV, "channel_number == scan_channel->(( %d ))\n", p_tmp_bss_desc->ChannelNumber);462463if (p_tmp_bss_desc->RecvSignalPower > p_test_bss_desc->RecvSignalPower) { /* Pow(Ant1) > Pow(Ant2) */464counter++;465tmp_power_diff = (u8)(p_tmp_bss_desc->RecvSignalPower - p_test_bss_desc->RecvSignalPower);466power_diff = power_diff + tmp_power_diff;467468PHYDM_DBG(dm, DBG_ANT_DIV, "Original: %d, Test: %d\n", p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);469PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "SSID:", p_tmp_bss_desc->bdSsIdBuf);470PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "BSSID:", p_tmp_bss_desc->bdSsIdBuf);471472#if 0473/* PHYDM_DBG(dm,DBG_ANT_DIV, "tmp_power_diff: (( %d)),max_power_diff: (( %d)),min_power_diff: (( %d))\n", tmp_power_diff,max_power_diff,min_power_diff); */474#endif475if (tmp_power_diff > max_power_diff)476max_power_diff = tmp_power_diff;477if (tmp_power_diff < min_power_diff)478min_power_diff = tmp_power_diff;479#if 0480/* PHYDM_DBG(dm,DBG_ANT_DIV, "max_power_diff: (( %d)),min_power_diff: (( %d))\n",max_power_diff,min_power_diff); */481#endif482483PlatformMoveMemory(p_test_bss_desc, p_tmp_bss_desc, sizeof(RT_WLAN_BSS));484} else if (p_test_bss_desc->RecvSignalPower > p_tmp_bss_desc->RecvSignalPower) { /* Pow(Ant1) < Pow(Ant2) */485counter++;486tmp_power_diff = (u8)(p_test_bss_desc->RecvSignalPower - p_tmp_bss_desc->RecvSignalPower);487power_diff = power_diff + tmp_power_diff;488PHYDM_DBG(dm, DBG_ANT_DIV, "Original: %d, Test: %d\n", p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);489PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "SSID:", p_tmp_bss_desc->bdSsIdBuf);490PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "BSSID:", p_tmp_bss_desc->bdSsIdBuf);491if (tmp_power_diff > max_power_diff)492max_power_diff = tmp_power_diff;493if (tmp_power_diff < min_power_diff)494min_power_diff = tmp_power_diff;495} else { /* Pow(Ant1) = Pow(Ant2) */496if (p_test_bss_desc->bdTstamp > p_tmp_bss_desc->bdTstamp) { /* Stamp(Ant1) < Stamp(Ant2) */497PHYDM_DBG(dm, DBG_ANT_DIV, "time_diff: %lld\n", (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp) / 1000);498if (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp > 5000) {499counter++;500PHYDM_DBG(dm, DBG_ANT_DIV, "Original: %d, Test: %d\n", p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);501PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "SSID:", p_tmp_bss_desc->bdSsIdBuf);502PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "BSSID:", p_tmp_bss_desc->bdSsIdBuf);503min_power_diff = 0;504}505} else506PHYDM_DBG(dm, DBG_ANT_DIV, "[Error !!!]: Time_diff: %lld\n", (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp) / 1000);507}508}509}510}511512if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8821)) {513if (mgnt_info->NumBssDesc != 0 && score < 0) {514PHYDM_DBG(dm, DBG_ANT_DIV,515"%s: Using ant(%s)\n", __func__,516(fat_tab->rx_idle_ant == MAIN_ANT) ?517"MAIN_ANT" : "AUX_ANT");518} else {519PHYDM_DBG(dm, DBG_ANT_DIV,520"%s: Remain ant(%s)\n", __func__,521(fat_tab->rx_idle_ant == MAIN_ANT) ?522"AUX_ANT" : "MAIN_ANT");523524if (fat_tab->rx_idle_ant == MAIN_ANT)525odm_update_rx_idle_ant(dm, AUX_ANT);526else527odm_update_rx_idle_ant(dm, MAIN_ANT);528}529530if (IS_5G_WIRELESS_MODE(mgnt_info->dot11CurrentWirelessMode)) {531dm_swat_table->ant_5g = fat_tab->rx_idle_ant;532PHYDM_DBG(dm, DBG_ANT_DIV,533"dm_swat_table->ant_5g=%s\n",534(fat_tab->rx_idle_ant == MAIN_ANT) ?535"MAIN_ANT" : "AUX_ANT");536} else {537dm_swat_table->ant_2g = fat_tab->rx_idle_ant;538PHYDM_DBG(dm, DBG_ANT_DIV,539"dm_swat_table->ant_2g=%s\n",540(fat_tab->rx_idle_ant == MAIN_ANT) ?541"MAIN_ANT" : "AUX_ANT");542}543} else if (dm->support_ic_type == ODM_RTL8723B) {544if (counter == 0) {545if (dm->dm_swat_table.pre_aux_fail_detec == false) {546dm->dm_swat_table.pre_aux_fail_detec = true;547dm->dm_swat_table.rssi_ant_dect_result = false;548PHYDM_DBG(dm, DBG_ANT_DIV, "counter=(( 0 )) , [[ Cannot find any AP with Aux-ant ]] -> Scan Target-channel again\n");549550/* @3 [ Scan again ] */551odm_sw_ant_div_construct_scan_chnl(adapter, scan_channel);552PlatformSetTimer(adapter, &mgnt_info->ScanTimer, 5);553return true;554} else { /* pre_aux_fail_detec == true */555/* @2 [ Single Antenna ] */556dm->dm_swat_table.pre_aux_fail_detec = false;557dm->dm_swat_table.rssi_ant_dect_result = true;558PHYDM_DBG(dm, DBG_ANT_DIV, "counter=(( 0 )) , [[ Still cannot find any AP ]]\n");559PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Single antenna\n", __func__);560}561dm->dm_swat_table.aux_fail_detec_counter++;562} else {563dm->dm_swat_table.pre_aux_fail_detec = false;564565if (counter == 3) {566avg_power_diff = ((power_diff - max_power_diff - min_power_diff) >> 1) + ((max_power_diff + min_power_diff) >> 2);567PHYDM_DBG(dm, DBG_ANT_DIV, "counter: (( %d )) , power_diff: (( %d ))\n", counter, power_diff);568PHYDM_DBG(dm, DBG_ANT_DIV, "[ counter==3 ] Modified avg_power_diff: (( %d )) , max_power_diff: (( %d )) , min_power_diff: (( %d ))\n", avg_power_diff, max_power_diff, min_power_diff);569} else if (counter >= 4) {570avg_power_diff = (power_diff - max_power_diff - min_power_diff) / (counter - 2);571PHYDM_DBG(dm, DBG_ANT_DIV, "counter: (( %d )) , power_diff: (( %d ))\n", counter, power_diff);572PHYDM_DBG(dm, DBG_ANT_DIV, "[ counter>=4 ] Modified avg_power_diff: (( %d )) , max_power_diff: (( %d )) , min_power_diff: (( %d ))\n", avg_power_diff, max_power_diff, min_power_diff);573574} else { /* @counter==1,2 */575avg_power_diff = power_diff / counter;576PHYDM_DBG(dm, DBG_ANT_DIV, "avg_power_diff: (( %d )) , counter: (( %d )) , power_diff: (( %d ))\n", avg_power_diff, counter, power_diff);577}578579/* @2 [ Retry ] */580if (avg_power_diff >= power_target_L && avg_power_diff <= power_target_H) {581dm->dm_swat_table.retry_counter++;582583if (dm->dm_swat_table.retry_counter <= 3) {584dm->dm_swat_table.rssi_ant_dect_result = false;585PHYDM_DBG(dm, DBG_ANT_DIV, "[[ Low confidence result ]] avg_power_diff= (( %d )) -> Scan Target-channel again ]]\n", avg_power_diff);586587/* @3 [ Scan again ] */588odm_sw_ant_div_construct_scan_chnl(adapter, scan_channel);589PlatformSetTimer(adapter, &mgnt_info->ScanTimer, 5);590return true;591} else {592dm->dm_swat_table.rssi_ant_dect_result = true;593PHYDM_DBG(dm, DBG_ANT_DIV, "[[ Still Low confidence result ]] (( retry_counter > 3 ))\n");594PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Single antenna\n", __func__);595}596}597/* @2 [ Dual Antenna ] */598else if ((mgnt_info->NumBssDesc != 0) && (avg_power_diff < power_target_L)) {599dm->dm_swat_table.rssi_ant_dect_result = true;600if (dm->dm_swat_table.ANTB_ON == false) {601dm->dm_swat_table.ANTA_ON = true;602dm->dm_swat_table.ANTB_ON = true;603}604PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Dual antenna\n", __func__);605dm->dm_swat_table.dual_ant_counter++;606607/* set bt coexDM from 1ant coexDM to 2ant coexDM */608BT_SetBtCoexAntNum(adapter, BT_COEX_ANT_TYPE_DETECTED, 2);609610/* @3 [ Init antenna diversity ] */611dm->support_ability |= ODM_BB_ANT_DIV;612odm_ant_div_init(dm);613}614/* @2 [ Single Antenna ] */615else if (avg_power_diff > power_target_H) {616dm->dm_swat_table.rssi_ant_dect_result = true;617if (dm->dm_swat_table.ANTB_ON == true) {618dm->dm_swat_table.ANTA_ON = true;619dm->dm_swat_table.ANTB_ON = false;620#if 0621/* @bt_set_bt_coex_ant_num(adapter, BT_COEX_ANT_TYPE_DETECTED, 1); */622#endif623}624PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Single antenna\n", __func__);625dm->dm_swat_table.single_ant_counter++;626}627}628#if 0629/* PHYDM_DBG(dm,DBG_ANT_DIV, "is_result=(( %d ))\n",dm->dm_swat_table.rssi_ant_dect_result); */630#endif631PHYDM_DBG(dm, DBG_ANT_DIV,632"dual_ant_counter = (( %d )), single_ant_counter = (( %d )) , retry_counter = (( %d )) , aux_fail_detec_counter = (( %d ))\n\n\n",633dm->dm_swat_table.dual_ant_counter,634dm->dm_swat_table.single_ant_counter,635dm->dm_swat_table.retry_counter,636dm->dm_swat_table.aux_fail_detec_counter);637638/* @2 recover the antenna setting */639640if (dm->dm_swat_table.ANTB_ON == false)641odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, 0xfff, (dm_swat_table->swas_no_link_bk_reg948));642643PHYDM_DBG(dm, DBG_ANT_DIV,644"is_result=(( %d )), Recover Reg[948]= (( %x ))\n\n",645dm->dm_swat_table.rssi_ant_dect_result,646dm_swat_table->swas_no_link_bk_reg948);647}648649/* @Check state reset to default and wait for next time. */650dm_swat_table->swas_no_link_state = 0;651mgnt_info->bScanAntDetect = false;652653return false;654}655656#else657return false;658#endif659660return false;661}662663/* @1 [3. PSD method] ========================================================== */664void odm_single_dual_antenna_detection_psd(665void *dm_void)666{667struct dm_struct *dm = (struct dm_struct *)dm_void;668u32 channel_ori;669u8 initial_gain = 0x36;670u8 tone_idx;671u8 tone_lenth_1 = 7, tone_lenth_2 = 4;672u16 tone_idx_1[7] = {88, 104, 120, 8, 24, 40, 56};673u16 tone_idx_2[4] = {8, 24, 40, 56};674u32 psd_report_main[11] = {0}, psd_report_aux[11] = {0};675/* u8 tone_lenth_1=4, tone_lenth_2=2; */676/* u16 tone_idx_1[4]={88, 120, 24, 56}; */677/* u16 tone_idx_2[2]={ 24, 56}; */678/* u32 psd_report_main[6]={0}, psd_report_aux[6]={0}; */679680u32 PSD_report_temp, max_psd_report_main = 0, max_psd_report_aux = 0;681u32 PSD_power_threshold;682u32 main_psd_result = 0, aux_psd_result = 0;683u32 regc50, reg948, regb2c, regc14, reg908;684u32 i = 0, test_num = 8;685686if (dm->support_ic_type != ODM_RTL8723B)687return;688689PHYDM_DBG(dm, DBG_ANT_DIV, "%s============>\n", __func__);690691/* @2 [ Backup Current RF/BB Settings ] */692693channel_ori = odm_get_rf_reg(dm, RF_PATH_A, ODM_CHANNEL, RFREGOFFSETMASK);694reg948 = odm_get_bb_reg(dm, REG_S0_S1_PATH_SWITCH, MASKDWORD);695regb2c = odm_get_bb_reg(dm, REG_AGC_TABLE_SELECT, MASKDWORD);696regc50 = odm_get_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, MASKDWORD);697regc14 = odm_get_bb_reg(dm, R_0xc14, MASKDWORD);698reg908 = odm_get_bb_reg(dm, R_0x908, MASKDWORD);699700/* @2 [ setting for doing PSD function (CH4)] */701odm_set_bb_reg(dm, REG_FPGA0_RFMOD, BIT(24), 0); /* @disable whole CCK block */702odm_write_1byte(dm, REG_TXPAUSE, 0xFF); /* Turn off TX -> Pause TX Queue */703odm_set_bb_reg(dm, R_0xc14, MASKDWORD, 0x0); /* @[ Set IQK Matrix = 0 ] equivalent to [ Turn off CCA] */704705/* PHYTXON while loop */706odm_set_bb_reg(dm, R_0x908, MASKDWORD, 0x803);707while (odm_get_bb_reg(dm, R_0xdf4, BIT(6))) {708i++;709if (i > 1000000) {710PHYDM_DBG(dm, DBG_ANT_DIV,711"Wait in %s() more than %d times!\n",712__FUNCTION__, i);713break;714}715}716717odm_set_bb_reg(dm, R_0xc50, 0x7f, initial_gain);718odm_set_rf_reg(dm, RF_PATH_A, ODM_CHANNEL, 0x7ff, 0x04); /* Set RF to CH4 & 40M */719odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0xf); /* @3 wire Disable 88c[23:20]=0xf */720odm_set_bb_reg(dm, REG_FPGA0_PSD_FUNCTION, BIT(14) | BIT15, 0x0); /* 128 pt */ /* Set PSD 128 ptss */721ODM_delay_us(3000);722723/* @2 [ Doing PSD Function in (CH4)] */724725/* @Antenna A */726PHYDM_DBG(dm, DBG_ANT_DIV, "Switch to Main-ant (CH4)\n");727odm_set_bb_reg(dm, R_0x948, 0xfff, 0x200);728ODM_delay_us(10);729PHYDM_DBG(dm, DBG_ANT_DIV, "dbg\n");730for (i = 0; i < test_num; i++) {731for (tone_idx = 0; tone_idx < tone_lenth_1; tone_idx++) {732PSD_report_temp = phydm_get_psd_data(dm, tone_idx_1[tone_idx], initial_gain);733/* @if( PSD_report_temp>psd_report_main[tone_idx] ) */734psd_report_main[tone_idx] += PSD_report_temp;735}736}737/* @Antenna B */738PHYDM_DBG(dm, DBG_ANT_DIV, "Switch to Aux-ant (CH4)\n");739odm_set_bb_reg(dm, R_0x948, 0xfff, 0x280);740ODM_delay_us(10);741for (i = 0; i < test_num; i++) {742for (tone_idx = 0; tone_idx < tone_lenth_1; tone_idx++) {743PSD_report_temp = phydm_get_psd_data(dm, tone_idx_1[tone_idx], initial_gain);744/* @if( PSD_report_temp>psd_report_aux[tone_idx] ) */745psd_report_aux[tone_idx] += PSD_report_temp;746}747}748/* @2 [ Doing PSD Function in (CH8)] */749750odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0x0); /* @3 wire enable 88c[23:20]=0x0 */751ODM_delay_us(3000);752753odm_set_bb_reg(dm, R_0xc50, 0x7f, initial_gain);754odm_set_rf_reg(dm, RF_PATH_A, ODM_CHANNEL, 0x7ff, 0x04); /* Set RF to CH8 & 40M */755756odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0xf); /* @3 wire Disable 88c[23:20]=0xf */757ODM_delay_us(3000);758759/* @Antenna A */760PHYDM_DBG(dm, DBG_ANT_DIV, "Switch to Main-ant (CH8)\n");761odm_set_bb_reg(dm, R_0x948, 0xfff, 0x200);762ODM_delay_us(10);763764for (i = 0; i < test_num; i++) {765for (tone_idx = 0; tone_idx < tone_lenth_2; tone_idx++) {766PSD_report_temp = phydm_get_psd_data(dm, tone_idx_2[tone_idx], initial_gain);767/* @if( PSD_report_temp>psd_report_main[tone_idx] ) */768psd_report_main[tone_lenth_1 + tone_idx] += PSD_report_temp;769}770}771772/* @Antenna B */773PHYDM_DBG(dm, DBG_ANT_DIV, "Switch to Aux-ant (CH8)\n");774odm_set_bb_reg(dm, R_0x948, 0xfff, 0x280);775ODM_delay_us(10);776777for (i = 0; i < test_num; i++) {778for (tone_idx = 0; tone_idx < tone_lenth_2; tone_idx++) {779PSD_report_temp = phydm_get_psd_data(dm, tone_idx_2[tone_idx], initial_gain);780/* @if( PSD_report_temp>psd_report_aux[tone_idx] ) */781psd_report_aux[tone_lenth_1 + tone_idx] += PSD_report_temp;782}783}784785/* @2 [ Calculate Result ] */786787PHYDM_DBG(dm, DBG_ANT_DIV, "\nMain PSD Result: (ALL)\n");788for (tone_idx = 0; tone_idx < (tone_lenth_1 + tone_lenth_2); tone_idx++) {789PHYDM_DBG(dm, DBG_ANT_DIV, "[Tone-%d]: %d,\n", (tone_idx + 1),790psd_report_main[tone_idx]);791main_psd_result += psd_report_main[tone_idx];792if (psd_report_main[tone_idx] > max_psd_report_main)793max_psd_report_main = psd_report_main[tone_idx];794}795PHYDM_DBG(dm, DBG_ANT_DIV,796"--------------------------- \nTotal_Main= (( %d ))\n",797main_psd_result);798PHYDM_DBG(dm, DBG_ANT_DIV, "MAX_Main = (( %d ))\n",799max_psd_report_main);800801PHYDM_DBG(dm, DBG_ANT_DIV, "\nAux PSD Result: (ALL)\n");802for (tone_idx = 0; tone_idx < (tone_lenth_1 + tone_lenth_2); tone_idx++) {803PHYDM_DBG(dm, DBG_ANT_DIV, "[Tone-%d]: %d,\n", (tone_idx + 1),804psd_report_aux[tone_idx]);805aux_psd_result += psd_report_aux[tone_idx];806if (psd_report_aux[tone_idx] > max_psd_report_aux)807max_psd_report_aux = psd_report_aux[tone_idx];808}809PHYDM_DBG(dm, DBG_ANT_DIV,810"--------------------------- \nTotal_Aux= (( %d ))\n",811aux_psd_result);812PHYDM_DBG(dm, DBG_ANT_DIV, "MAX_Aux = (( %d ))\n\n",813max_psd_report_aux);814815/* @main_psd_result=main_psd_result-max_psd_report_main; */816/* @aux_psd_result=aux_psd_result-max_psd_report_aux; */817PSD_power_threshold = (main_psd_result * 7) >> 3;818819PHYDM_DBG(dm, DBG_ANT_DIV,820"[ Main_result, Aux_result ] = [ %d , %d ], PSD_power_threshold=(( %d ))\n",821main_psd_result, aux_psd_result, PSD_power_threshold);822823/* @3 [ Dual Antenna ] */824if (aux_psd_result >= PSD_power_threshold) {825if (dm->dm_swat_table.ANTB_ON == false) {826dm->dm_swat_table.ANTA_ON = true;827dm->dm_swat_table.ANTB_ON = true;828}829PHYDM_DBG(dm, DBG_ANT_DIV,830"odm_sw_ant_div_check_before_link(): Dual antenna\n");831832#if 0833/* set bt coexDM from 1ant coexDM to 2ant coexDM */834/* @bt_set_bt_coex_ant_num(adapter, BT_COEX_ANT_TYPE_DETECTED, 2); */835#endif836837/* @Init antenna diversity */838dm->support_ability |= ODM_BB_ANT_DIV;839odm_ant_div_init(dm);840}841/* @3 [ Single Antenna ] */842else {843if (dm->dm_swat_table.ANTB_ON == true) {844dm->dm_swat_table.ANTA_ON = true;845dm->dm_swat_table.ANTB_ON = false;846}847PHYDM_DBG(dm, DBG_ANT_DIV,848"odm_sw_ant_div_check_before_link(): Single antenna\n");849}850851/* @2 [ Recover all parameters ] */852853odm_set_rf_reg(dm, RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, channel_ori);854odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0x0); /* @3 wire enable 88c[23:20]=0x0 */855odm_set_bb_reg(dm, R_0xc50, 0x7f, regc50);856857odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, MASKDWORD, reg948);858odm_set_bb_reg(dm, REG_AGC_TABLE_SELECT, MASKDWORD, regb2c);859860odm_set_bb_reg(dm, REG_FPGA0_RFMOD, BIT(24), 1); /* @enable whole CCK block */861odm_write_1byte(dm, REG_TXPAUSE, 0x0); /* Turn on TX */ /* Resume TX Queue */862odm_set_bb_reg(dm, R_0xc14, MASKDWORD, regc14); /* @[ Set IQK Matrix = 0 ] equivalent to [ Turn on CCA] */863odm_set_bb_reg(dm, R_0x908, MASKDWORD, reg908);864865return;866}867868void odm_sw_ant_detect_init(void *dm_void)869{870#if (RTL8723B_SUPPORT == 1)871872struct dm_struct *dm = (struct dm_struct *)dm_void;873struct sw_antenna_switch *dm_swat_table = &dm->dm_swat_table;874875if (dm->support_ic_type != ODM_RTL8723B)876return;877878/* @dm_swat_table->pre_antenna = MAIN_ANT; */879/* @dm_swat_table->cur_antenna = MAIN_ANT; */880dm_swat_table->swas_no_link_state = 0;881dm_swat_table->pre_aux_fail_detec = false;882dm_swat_table->swas_no_link_bk_reg948 = 0xff;883884#ifdef CONFIG_PSD_TOOL885phydm_psd_init(dm);886#endif887#endif888}889#endif890891892893