//============================================================ // // File Name: HalDMOutSrc_AP.c // // Description: // // This file is for common outsource dynamic mechanism for partner. // // //============================================================ #ifndef _HALDM_COMMON_C_ #define _HALDM_COMMON_C_ #ifdef __KERNEL__ #include #include #include #include #include #include #include #endif #include "8192cd_cfg.h" #include "8192cd.h" #include "8192cd_hw.h" #include "8192cd_headers.h" #include "8192cd_debug.h" #ifdef USE_OUT_SRC #include "./OUTSRC/phydm_precomp.h" #else #define TX_POWER_NEAR_FIELD_THRESH_AP HP_LOWER #endif #if defined(CONFIG_RTL_819X) && defined(USE_RLX_BSP) #if defined(CONFIG_OPENWRT_SDK) && !defined(CONFIG_ARCH_CPU_RLX) #include #else #include #endif //CONFIG_OPENWRT_SDK #endif #ifdef HW_ANT_SWITCH #define RXDVY_A_EN ((HW_DIV_ENABLE && !priv->pshare->rf_ft_var.antSw_select) ? 0x80 : 0) #define RXDVY_B_EN ((HW_DIV_ENABLE && priv->pshare->rf_ft_var.antSw_select) ? 0x80 : 0) #endif //3 ============================================================ //3 DIG related functions //3 ============================================================ int getIGIFor1RCCA(int value_IGI) { #define ONERCCA_LOW_TH 0x30 #define ONERCCA_LOW_DIFF 8 if (value_IGI < ONERCCA_LOW_TH) { if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF) return ONERCCA_LOW_TH; else return value_IGI + ONERCCA_LOW_DIFF; } else { return value_IGI; } } #if 1 #if defined(DETECT_STA_EXISTANCE) && defined(CONFIG_WLAN_HAL) // Check for STA existance. If STA disappears, disconnect it. Added by Annie, 2010-08-10. void DetectSTAExistance88XX(struct rtl8192cd_priv *priv, struct tx_rpt *report, struct stat_info *pstat) { //unsigned char tmpbuf[16]; // Parameters const unsigned int maxTxFailCnt = 300; // MAX Tx fail packet count const unsigned int minTxFailCnt = 30; // MIN Tx fail packet count; this value should be less than maxTxFailCnt. const unsigned int txFailSecThr= 3; // threshold of Tx Fail Time (in second) //const unsigned int NoTXOKSecThr= 5; // threshold of NO Tx ok Time (in second) //const unsigned int NoRXOKSecThr= 5; // threshold of NO Tx ok Time (in second) // Temporarily change Retry Limit when TxFail. (tfrl: TxFailRetryLimit) //const unsigned char TFRL = 7; // New Retry Limit value //const unsigned char TFRL_FailCnt = 2; // Tx Fail Count threshold to set Retry Limit //const unsigned char TFRL_SetTime = 2; // Time to set Retry Limit (in second) //const unsigned char TFRL_RcvTime = 3; // Time to recover Retry Limit (in second) //const unsigned short Back_retty_value = 0x10; #ifdef MCR_WIRELESS_EXTEND if (pstat->IOTPeer==HT_IOT_PEER_CMW) return; #endif if( report->txok != 0 ) { // Reset Counter pstat->tx_conti_fail_cnt = 0; pstat->tx_last_good_time = priv->up_time; if (pstat->leave) { #if defined(CONFIG_PCI_HCI) GET_HAL_INTERFACE(priv)->UpdateHalMSRRPTHandler(priv, pstat, INCREASE); #elif defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) notify_update_sta_msr(priv, pstat, INCREASE); #endif pstat->leave = 0; } } else if( report->txfail != 0 ) { if (pstat->leave) return; pstat->tx_conti_fail_cnt += report->txfail; DEBUG_WARN( "detect: txfail=%d, tx_conti_fail_cnt=%d\n", report->txfail, pstat->tx_conti_fail_cnt ); //RTL_W16(RL, (TFRL&SRL_Mask)<up_time >= (pstat->tx_last_good_time+TFRL_SetTime) && pstat->tx_conti_fail_cnt >= TFRL_FailCnt && #if defined(CONFIG_RTL8672) || defined (NOT_RTK_BSP) !pstat->ht_cap_len && // legacy rate only #endif !priv->pshare->bRLShortened ) { // Shorten retry limit, because AP spending too much time to send out g mode STA pending packets in HW queue. priv->pshare->bRLShortened = TRUE; printk( "== Shorten RetryLimit to 0x%04X ==\n", RTL_R16(RL) ); } #endif if( (pstat->tx_conti_fail_cnt >= maxTxFailCnt) || (pstat->tx_conti_fail_cnt >= minTxFailCnt && priv->up_time >= (pstat->tx_last_good_time+txFailSecThr) ) ) { // This STA is considered as disappeared, so delete it. DEBUG_WARN( "** tx_conti_fail_cnt=%d (min=%d,max=%d)\n", pstat->tx_conti_fail_cnt, minTxFailCnt, maxTxFailCnt); DEBUG_WARN( "** tx_last_good_time=%d, up_time=%d (Thr:%d)\n", (int)pstat->tx_last_good_time, (int)priv->up_time, txFailSecThr ); DEBUG_WARN( "AP is going to del_sta %02X:%02X:%02X:%02X:%02X:%02X\n", pstat->hwaddr[0],pstat->hwaddr[1],pstat->hwaddr[2],pstat->hwaddr[3],pstat->hwaddr[4],pstat->hwaddr[5] ); // del_sta(priv, tmpbuf); ++(pstat->leave); #if defined(CONFIG_PCI_HCI) GET_HAL_INTERFACE(priv)->UpdateHalMSRRPTHandler(priv, pstat, DECREASE); pstat->bDrop = 1; #elif defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) notify_update_sta_msr(priv, pstat, DECREASE); #endif //printk("Drop client packet, AID = %x TxFailCnt= %x \n",pstat->aid,pstat->tx_conti_fail_cnt); //RTL_W16(RL, (Back_retty_value&SRL_Mask)<tx_conti_fail_cnt = 0; pstat->tx_last_good_time = priv->up_time; } } else { #if 0 //printk("AID[%x](pstat->leave)=%x priv->up_time=%x (pstat->tx_last_good_time+NoTXOKSecThr)=%x \n",pstat->aid,(pstat->leave),priv->up_time,(pstat->tx_last_good_time+NoTXOKSecThr)); if (!(pstat->leave) && (priv->up_time > (pstat->tx_last_good_time+NoTXOKSecThr)) && (priv->up_time > (pstat->rx_last_good_time+NoRXOKSecThr)) ) { DEBUG_WARN("%s %d expire timeout, set MACID 0 AID = %x \n",__FUNCTION__,__LINE__,REMAP_AID(pstat)); GET_HAL_INTERFACE(priv)->UpdateHalMSRRPTHandler(priv, pstat, DECREASE); pstat->bDrop = 1; printk("Client no TRX over 10 Secs , Drop client packet, AID = %x \n",pstat->aid); ++(pstat->leave); } #endif } } #endif #if defined(DETECT_STA_EXISTANCE) && (defined(CONFIG_RTL_92C_SUPPORT) || defined(CONFIG_RTL_92D_SUPPORT) || defined(CONFIG_RTL_8812_SUPPORT)) void DetectSTAExistance(struct rtl8192cd_priv *priv, struct tx_rpt *report, struct stat_info *pstat) { const unsigned int maxTxFailCnt = 300; // MAX Tx fail packet count const unsigned int minTxFailCnt = 30; // MIN Tx fail packet count; this value should be less than maxTxFailCnt. const unsigned int txFailSecThr= 3; // threshold of Tx Fail Time (in second) const unsigned char TFRL = 7; // New Retry Limit value const unsigned char TFRL_FailCnt = 2; // Tx Fail Count threshold to set Retry Limit 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; pstat->tx_last_good_time = priv->up_time; pstat->leave = 0; } else if( report->txfail != 0 ) { pstat->tx_conti_fail_cnt += report->txfail; DEBUG_WARN( "detect: txfail=%d, tx_conti_fail_cnt=%d\n", report->txfail, pstat->tx_conti_fail_cnt ); if (pstat->leave) return; if( CHIP_VER_92X_SERIES(priv) && (priv->up_time >= (pstat->tx_last_good_time+TFRL_SetTime)) && pstat->tx_conti_fail_cnt >= TFRL_FailCnt && #if defined(CONFIG_RTL8672) || defined (NOT_RTK_BSP) !pstat->ht_cap_len && // legacy rate only #endif !priv->pshare->bRLShortened ) { // Shorten retry limit, because AP spending too much time to send out g mode STA pending packets in HW queue. RTL_W16(RL, (TFRL&SRL_Mask)<pshare->bRLShortened = TRUE; DEBUG_WARN( "== Shorten RetryLimit to 0x%04X ==\n", RTL_R16(RL) ); } if( (pstat->tx_conti_fail_cnt >= maxTxFailCnt) || (pstat->tx_conti_fail_cnt >= minTxFailCnt && priv->up_time >= (pstat->tx_last_good_time+txFailSecThr) ) ) { // This STA is considered as disappeared, so delete it. DEBUG_WARN( "** tx_conti_fail_cnt=%d (min=%d,max=%d)\n", pstat->tx_conti_fail_cnt, minTxFailCnt, maxTxFailCnt); DEBUG_WARN( "** tx_last_good_time=%d, up_time=%d (Thr:%d)\n", (int)pstat->tx_last_good_time, (int)priv->up_time, txFailSecThr ); DEBUG_WARN( "AP is going to del_sta %02X:%02X:%02X:%02X:%02X:%02X\n", pstat->hwaddr[0],pstat->hwaddr[1],pstat->hwaddr[2],pstat->hwaddr[3],pstat->hwaddr[4],pstat->hwaddr[5] ); ++(pstat->leave); pstat->tx_conti_fail_cnt = 0; pstat->tx_last_good_time = priv->up_time; } } } #if defined(CONFIG_RTL_92C_SUPPORT) || defined(CONFIG_RTL_92D_SUPPORT) // Timer callback function to recover hardware retry limit register. Added by Annie, 2010-08-10. void RetryLimitRecovery(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if( priv->pshare->bRLShortened ) { // RTL_W16(RL, (priv->pshare->RLShort&SRL_Mask)<pshare->RLLong&LRL_Mask)<pshare->RL_setting); priv->pshare->bRLShortened = FALSE; DEBUG_WARN( "== Recover RetryLimit to 0x%04X ==\n", RTL_R16(RL) ); } } // Chack STA leaving status; per interface. Added by Annie, 2010-08-10. unsigned char NoLeavingSTA(struct rtl8192cd_priv *priv) { unsigned char bStaAllOK = TRUE; struct list_head *phead, *plist; struct stat_info *pstat; #ifdef SMP_SYNC unsigned long flags = 0; #endif phead = &priv->asoc_list; if (!netif_running(priv->dev) || list_empty(phead)) return bStaAllOK; SMP_LOCK_ASOC_LIST(flags); plist = phead->next; while (plist != phead) { pstat = list_entry(plist, struct stat_info, asoc_list); plist = plist->next; if( pstat->tx_conti_fail_cnt != 0 ) { if (pstat->leave) pstat->tx_conti_fail_cnt = 0; bStaAllOK = FALSE; break; } } SMP_UNLOCK_ASOC_LIST(flags); return bStaAllOK; } // Chack STA leaving status for all active interface and recover retry limit register value. Added by Annie, 2010-08-10. void LeavingSTA_RLCheck(struct rtl8192cd_priv *priv) { unsigned char bIfAllOK = TRUE; static int AllOKTimes = 0; #ifdef MBSSID int i; #endif // Parameter const unsigned char TFRL_RcvTime = 10; // Time to recover Retry Limit (in second) if (FALSE == priv->pshare->bRLShortened) return; if( !NoLeavingSTA(priv) ) bIfAllOK = FALSE; #ifdef UNIVERSAL_REPEATER else if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && !NoLeavingSTA(GET_VXD_PRIV(priv))) { bIfAllOK = FALSE; } #endif #ifdef MBSSID else if (priv->pmib->miscEntry.vap_enable) { for (i=0; ipvap_priv[i])) { if( !NoLeavingSTA(priv->pvap_priv[i]) ) { bIfAllOK = FALSE; break; } } } } #endif if( bIfAllOK ) { AllOKTimes ++; if( AllOKTimes >= TFRL_RcvTime ) #ifdef __KERNEL__ RetryLimitRecovery((unsigned long)priv); #elif defined(__ECOS) RetryLimitRecovery((void *)priv); #endif } else { AllOKTimes = 0; } } #endif #endif //#if defined(DETECT_STA_EXISTANCE) #endif void set_DIG_state(struct rtl8192cd_priv *priv, int state) { int value_IGI; if (state) { priv->pshare->DIG_on = 1; #if defined(USE_OUT_SRC) if(IS_OUTSRC_CHIP(priv) && priv->pshare->restore) { ODM_Write_DIG(ODMPTR, priv->pshare->restore); // panic_printk("%s, 1-> %x, %x\n", __FUNCTION__, RTL_R8(0xc50), priv->pshare->restore); } #endif priv->pshare->restore = 0; } else { priv->pshare->DIG_on = 0; if (priv->pshare->restore == 0) { #if defined(CONFIG_RTL_92C_SUPPORT) && defined(HIGH_POWER_EXT_LNA) if ((GET_CHIP_VER(priv)==VERSION_8192C) && priv->pshare->rf_ft_var.use_ext_lna == 1) value_IGI = 0x30; else #endif value_IGI = 0x20; priv->pshare->restore = PHY_QueryBBReg(priv, 0xc50, 0x7f); #if defined(USE_OUT_SRC) if(IS_OUTSRC_CHIP(priv) ) { ODM_Write_DIG(ODMPTR, value_IGI); //panic_printk("%s, 0-> %x, %x\n", __FUNCTION__, RTL_R8(0xc50), priv->pshare->restore); } #endif #if defined(CONFIG_RTL_92C_SUPPORT) || defined(CONFIG_RTL_92D_SUPPORT) if(CHIP_VER_92X_SERIES(priv)) { if (priv->pshare->rf_ft_var.one_path_cca == 0) { PHY_SetBBReg(priv, 0xc50, 0x7f, value_IGI); PHY_SetBBReg(priv, 0xc58, 0x7f, value_IGI); } else if (priv->pshare->rf_ft_var.one_path_cca == 1) { PHY_SetBBReg(priv, 0xc50, 0x7f, value_IGI); PHY_SetBBReg(priv, 0xc58, 0x7f, getIGIFor1RCCA(value_IGI)); } else if (priv->pshare->rf_ft_var.one_path_cca == 2) { PHY_SetBBReg(priv, 0xc50, 0x7f, getIGIFor1RCCA(value_IGI)); PHY_SetBBReg(priv, 0xc58, 0x7f, value_IGI); } } #endif } #ifdef INTERFERENCE_CONTROL priv->pshare->phw->signal_strength = 0; #endif } } void check_DIG_by_rssi(struct rtl8192cd_priv *priv, unsigned char rssi_strength) { unsigned int dig_on = 0; if (OPMODE & WIFI_SITE_MONITOR) return; #if defined(CONFIG_RTL_8812_SUPPORT)||defined(CONFIG_WLAN_HAL_8881A)||defined(CONFIG_WLAN_HAL_8814AE) if((GET_CHIP_VER(priv)== VERSION_8812E)||(GET_CHIP_VER(priv)== VERSION_8881A)||(GET_CHIP_VER(priv)== VERSION_8814A)) return; #endif if ((rssi_strength > priv->pshare->rf_ft_var.digGoUpperLevel) && (rssi_strength < TX_POWER_NEAR_FIELD_THRESH_AP+1) && (priv->pshare->phw->signal_strength != 2)) { #ifndef CONFIG_RTL_92D_SUPPORT if (priv->pshare->is_40m_bw) // RTL_W8(0xc87, (RTL_R8(0xc87) & 0xf) | 0x30); 92D RTL_W8(0xc87, 0x30); else RTL_W8(0xc30, 0x44); #endif if (priv->pshare->phw->signal_strength != 3) dig_on++; priv->pshare->phw->signal_strength = 2; } else if ((rssi_strength > TX_POWER_NEAR_FIELD_THRESH_AP+5) && (priv->pshare->phw->signal_strength != 3)) { #ifndef CONFIG_RTL_92D_SUPPORT if (priv->pshare->is_40m_bw) // RTL_W8(0xc87, (RTL_R8(0xc87) & 0xf) | 0x30); 92D RTL_W8(0xc87, 0x30); else RTL_W8(0xc30, 0x44); #endif if (priv->pshare->phw->signal_strength != 2) dig_on++; priv->pshare->phw->signal_strength = 3; } else if (((rssi_strength < priv->pshare->rf_ft_var.digGoLowerLevel) && (priv->pshare->phw->signal_strength != 1)) || !priv->pshare->phw->signal_strength) { // DIG off #if 0 set_DIG_state(priv, 0); #endif #ifndef CONFIG_RTL_92D_SUPPORT if (priv->pshare->is_40m_bw) //RTL_W8(0xc87, (RTL_R8(0xc87) & 0xf) | 0x30); 92D RTL_W8(0xc87, 0x30); else RTL_W8(0xc30, 0x44); #endif priv->pshare->phw->signal_strength = 1; } if (dig_on) { // DIG on set_DIG_state(priv, 1); } //check_DC_TH_by_rssi(priv, rssi_strength); } void DIG_for_site_survey(struct rtl8192cd_priv *priv, int do_ss) { if (do_ss) { // DIG off set_DIG_state(priv, 0); } else { // DIG on #ifndef INTERFERENCE_CONTROL // if (priv->pshare->phw->signal_strength > 1) #endif { set_DIG_state(priv, 1); } } } extern unsigned char CCKSwingTable_Ch14 [][8]; extern unsigned char CCKSwingTable_Ch1_Ch13[][8]; #ifndef CCK_TABLE_SIZE #define CCK_TABLE_SIZE 33 #endif int get_CCK_swing_index(struct rtl8192cd_priv *priv) { int TempCCk, index=12, i; short channel; #ifdef MP_TEST if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) channel=priv->pshare->working_channel; else #endif channel = (priv->pmib->dot11RFEntry.dot11channel); //Query CCK default setting From 0xa24 TempCCk = PHY_QueryBBReg(priv, rCCK0_TxFilter2, bMaskDWord)&bMaskCCK; TempCCk = cpu_to_le32(TempCCk); for(i=0 ; ipshare->rf_ft_var.mp_specific) channel=priv->pshare->working_channel; else #endif channel = (priv->pmib->dot11RFEntry.dot11channel); #ifdef USE_OUT_SRC #ifdef CONFIG_RTL_88E_SUPPORT if (GET_CHIP_VER(priv) == VERSION_8188E) { CCK_index = ((CCK_index > (CCK_TABLE_SIZE - 1)) ? (CCK_TABLE_SIZE - 1) : CCK_index); if (channel !=14) { RTL_W8( 0xa22, CCKSwingTable_Ch1_Ch13_New[CCK_index][0]); RTL_W8( 0xa23, CCKSwingTable_Ch1_Ch13_New[CCK_index][1]); RTL_W8( 0xa24, CCKSwingTable_Ch1_Ch13_New[CCK_index][2]); RTL_W8( 0xa25, CCKSwingTable_Ch1_Ch13_New[CCK_index][3]); RTL_W8( 0xa26, CCKSwingTable_Ch1_Ch13_New[CCK_index][4]); RTL_W8( 0xa27, CCKSwingTable_Ch1_Ch13_New[CCK_index][5]); RTL_W8( 0xa28, CCKSwingTable_Ch1_Ch13_New[CCK_index][6]); RTL_W8( 0xa29, CCKSwingTable_Ch1_Ch13_New[CCK_index][7]); } else{ RTL_W8( 0xa22, CCKSwingTable_Ch14_New[CCK_index][0]); RTL_W8( 0xa23, CCKSwingTable_Ch14_New[CCK_index][1]); RTL_W8( 0xa24, CCKSwingTable_Ch14_New[CCK_index][2]); RTL_W8( 0xa25, CCKSwingTable_Ch14_New[CCK_index][3]); RTL_W8( 0xa26, CCKSwingTable_Ch14_New[CCK_index][4]); RTL_W8( 0xa27, CCKSwingTable_Ch14_New[CCK_index][5]); RTL_W8( 0xa28, CCKSwingTable_Ch14_New[CCK_index][6]); RTL_W8( 0xa29, CCKSwingTable_Ch14_New[CCK_index][7]); } } else #endif #ifdef CONFIG_WLAN_HAL_8192EE if (GET_CHIP_VER(priv) == VERSION_8192E) { CCK_index = ((CCK_index > (CCK_TABLE_SIZE_92E - 1)) ? (CCK_TABLE_SIZE_92E - 1) : CCK_index); if (channel !=14) { RTL_W8( 0xa22, CCKSwingTable_Ch1_Ch13_92E[CCK_index][0]); RTL_W8( 0xa23, CCKSwingTable_Ch1_Ch13_92E[CCK_index][1]); RTL_W8( 0xa24, CCKSwingTable_Ch1_Ch13_92E[CCK_index][2]); RTL_W8( 0xa25, CCKSwingTable_Ch1_Ch13_92E[CCK_index][3]); RTL_W8( 0xa26, CCKSwingTable_Ch1_Ch13_92E[CCK_index][4]); RTL_W8( 0xa27, CCKSwingTable_Ch1_Ch13_92E[CCK_index][5]); RTL_W8( 0xa28, CCKSwingTable_Ch1_Ch13_92E[CCK_index][6]); RTL_W8( 0xa29, CCKSwingTable_Ch1_Ch13_92E[CCK_index][7]); } else{ RTL_W8( 0xa22, CCKSwingTable_Ch14_92E[CCK_index][0]); RTL_W8( 0xa23, CCKSwingTable_Ch14_92E[CCK_index][1]); RTL_W8( 0xa24, CCKSwingTable_Ch14_92E[CCK_index][2]); RTL_W8( 0xa25, CCKSwingTable_Ch14_92E[CCK_index][3]); RTL_W8( 0xa26, CCKSwingTable_Ch14_92E[CCK_index][4]); RTL_W8( 0xa27, CCKSwingTable_Ch14_92E[CCK_index][5]); RTL_W8( 0xa28, CCKSwingTable_Ch14_92E[CCK_index][6]); RTL_W8( 0xa29, CCKSwingTable_Ch14_92E[CCK_index][7]); } } else #endif #endif { CCK_index = ((CCK_index > (CCK_TABLE_SIZE - 1)) ? (CCK_TABLE_SIZE - 1) : CCK_index); if(channel !=14) { RTL_W8( 0xa22, CCKSwingTable_Ch1_Ch13[CCK_index][0]); RTL_W8( 0xa23, CCKSwingTable_Ch1_Ch13[CCK_index][1]); RTL_W8( 0xa24, CCKSwingTable_Ch1_Ch13[CCK_index][2]); RTL_W8( 0xa25, CCKSwingTable_Ch1_Ch13[CCK_index][3]); RTL_W8( 0xa26, CCKSwingTable_Ch1_Ch13[CCK_index][4]); RTL_W8( 0xa27, CCKSwingTable_Ch1_Ch13[CCK_index][5]); RTL_W8( 0xa28, CCKSwingTable_Ch1_Ch13[CCK_index][6]); RTL_W8( 0xa29, CCKSwingTable_Ch1_Ch13[CCK_index][7]); } else{ RTL_W8( 0xa22, CCKSwingTable_Ch14[CCK_index][0]); RTL_W8( 0xa23, CCKSwingTable_Ch14[CCK_index][1]); RTL_W8( 0xa24, CCKSwingTable_Ch14[CCK_index][2]); RTL_W8( 0xa25, CCKSwingTable_Ch14[CCK_index][3]); RTL_W8( 0xa26, CCKSwingTable_Ch14[CCK_index][4]); RTL_W8( 0xa27, CCKSwingTable_Ch14[CCK_index][5]); RTL_W8( 0xa28, CCKSwingTable_Ch14[CCK_index][6]); RTL_W8( 0xa29, CCKSwingTable_Ch14[CCK_index][7]); } } } #ifdef WIFI_WMM void check_NAV_prot_len(struct rtl8192cd_priv *priv, struct stat_info *pstat, unsigned int disassoc) { #if defined(CONFIG_RTL_8812_SUPPORT)||defined(CONFIG_WLAN_HAL_8881A) ||defined(CONFIG_WLAN_HAL_8814AE) if((GET_CHIP_VER(priv)== VERSION_8812E)||(GET_CHIP_VER(priv)== VERSION_8881A)||(GET_CHIP_VER(priv)== VERSION_8814A)) return; #endif if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat && pstat->ht_cap_len && (pstat->IOTPeer==HT_IOT_PEER_INTEL)) { if (!disassoc && (pstat->MIMO_ps & _HT_MIMO_PS_DYNAMIC_)) { setSTABitMap(&priv->pshare->mimo_ps_dynamic_sta, pstat->aid); } else { clearSTABitMap(&priv->pshare->mimo_ps_dynamic_sta, pstat->aid); } #ifdef CONFIG_RTL_88E_SUPPORT if (GET_CHIP_VER(priv) != VERSION_8188E) #endif { #if defined(CONFIG_PCI_HCI) if (orSTABitMap(&priv->pshare->mimo_ps_dynamic_sta)) { RTL_W8(NAV_PROT_LEN, 0x40); } else { RTL_W8(NAV_PROT_LEN, 0x20); } #elif defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) notify_NAV_prot_len_change(priv); #endif } } } #endif //3 ============================================================ //3 FA statistic functions //3 ============================================================ #if !defined(CONFIG_RTL_NEW_AUTOCH) static #endif void reset_FA_reg(struct rtl8192cd_priv *priv) { #if defined(CONFIG_RTL_8812_SUPPORT)||defined(CONFIG_WLAN_HAL_8881A) ||defined(CONFIG_WLAN_HAL_8814AE) if((GET_CHIP_VER(priv)== VERSION_8812E)||(GET_CHIP_VER(priv)== VERSION_8881A)||(GET_CHIP_VER(priv)== VERSION_8814A)) { // reset OFDM FA coutner PHY_SetBBReg(priv, 0x9a4, BIT(17), 1); PHY_SetBBReg(priv, 0x9a4, BIT(17), 0); // reset CCK FA counter PHY_SetBBReg(priv, 0xa2c, BIT(17), 0); PHY_SetBBReg(priv, 0xa2c, BIT(17), 1); // reset CCA counter PHY_SetBBReg(priv, 0xb58, BIT(17), 1); PHY_SetBBReg(priv, 0xb58, BIT(17), 0); return; } #endif #if !defined(CONFIG_RTL_NEW_AUTOCH) unsigned char value8; value8 = RTL_R8(0xd03); RTL_W8(0xd03, value8 | 0x08); // regD00[27]=1 to reset these OFDM FA counters value8 = RTL_R8(0xd03); RTL_W8(0xd03, value8 & 0xF7); // regD00[27]=0 to start counting value8 = RTL_R8(0xa2d); RTL_W8(0xa2d, value8 & 0x3F); // regA2D[7:6]=00 to disable counting value8 = RTL_R8(0xa2d); RTL_W8(0xa2d, value8 | 0x80); // regA2D[7:6]=10 to enable counting #else /* cck CCA */ PHY_SetBBReg(priv, 0xa2c, BIT(13) | BIT(12), 0); PHY_SetBBReg(priv, 0xa2c, BIT(13) | BIT(12), 2); /* cck FA*/ PHY_SetBBReg(priv, 0xa2c, BIT(15) | BIT(14), 0); PHY_SetBBReg(priv, 0xa2c, BIT(15) | BIT(14), 2); /* ofdm */ PHY_SetBBReg(priv, 0xd00, BIT(27), 1); PHY_SetBBReg(priv, 0xd00, BIT(27), 0); #endif #if defined(CONFIG_RTL_92D_SUPPORT) && defined(CONFIG_RTL_NOISE_CONTROL) if (GET_CHIP_VER(priv) == VERSION_8192D){ PHY_SetBBReg(priv, 0xf14, BIT(16),1); PHY_SetBBReg(priv, 0xf14, BIT(16),0); RTL_W32(RXERR_RPT, RTL_R32(RXERR_RPT)|BIT(27)); RTL_W32(RXERR_RPT, RTL_R32(RXERR_RPT)&(~BIT(27))); } #endif #if defined(CONFIG_RTL_88E_SUPPORT) || defined(CONFIG_WLAN_HAL_8192EE) if (GET_CHIP_VER(priv)==VERSION_8188E || GET_CHIP_VER(priv)==VERSION_8192E) { PHY_SetBBReg(priv, 0xc0c, BIT(31), 1); PHY_SetBBReg(priv, 0xc0c, BIT(31), 0); } #endif } #if defined(CONFIG_RTL_NEW_AUTOCH) void hold_CCA_FA_counter(struct rtl8192cd_priv *priv) { #if defined(CONFIG_RTL_8812_SUPPORT)||defined(CONFIG_WLAN_HAL_8881A) if((GET_CHIP_VER(priv)== VERSION_8812E)||(GET_CHIP_VER(priv)== VERSION_8881A)) return; #endif /* hold cck CCA & FA counter */ PHY_SetBBReg(priv, 0xa2c, BIT(12), 1); PHY_SetBBReg(priv, 0xa2c, BIT(14), 1); /* hold ofdm CCA & FA counter */ PHY_SetBBReg(priv, 0xc00, BIT(31), 1); PHY_SetBBReg(priv, 0xd00, BIT(31), 1); } void release_CCA_FA_counter(struct rtl8192cd_priv *priv) { #if defined(CONFIG_RTL_8812_SUPPORT)||defined(CONFIG_WLAN_HAL_8881A) || defined(CONFIG_WLAN_HAL_8814AE) if((GET_CHIP_VER(priv)== VERSION_8812E)||(GET_CHIP_VER(priv)== VERSION_8881A) ||(GET_CHIP_VER(priv)== VERSION_8814A)) return; #endif /* release cck CCA & FA counter */ PHY_SetBBReg(priv, 0xa2c, BIT(12), 0); PHY_SetBBReg(priv, 0xa2c, BIT(14), 0); /* release ofdm CCA & FA counter */ PHY_SetBBReg(priv, 0xc00, BIT(31), 0); PHY_SetBBReg(priv, 0xd00, BIT(31), 0); #ifdef CONFIG_RTL_88E_SUPPORT if (GET_CHIP_VER(priv)==VERSION_8188E) { PHY_SetBBReg(priv, 0xc0c, BIT(31), 1); PHY_SetBBReg(priv, 0xc0c, BIT(31), 0); } #endif } void _FA_statistic(struct rtl8192cd_priv *priv) { #if defined(CONFIG_RTL_8812_SUPPORT)||defined(CONFIG_WLAN_HAL_8881A)||defined(CONFIG_WLAN_HAL_8814AE) if((GET_CHIP_VER(priv)== VERSION_8812E)||(GET_CHIP_VER(priv)== VERSION_8881A)||(GET_CHIP_VER(priv)== VERSION_8814A)) return; #endif // read OFDM FA counters priv->pshare->ofdm_FA_cnt1 = RTL_R16(0xda2); priv->pshare->ofdm_FA_cnt2 = RTL_R16(0xda4); priv->pshare->ofdm_FA_cnt3 = RTL_R16(0xda6); priv->pshare->ofdm_FA_cnt4 = RTL_R16(0xda8); priv->pshare->cck_FA_cnt = (RTL_R8(0xa5b) << 8) + 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 } #endif void FA_statistic(struct rtl8192cd_priv *priv) { #if defined(CONFIG_RTL_8812_SUPPORT)||defined(CONFIG_WLAN_HAL_8881A) if((GET_CHIP_VER(priv)== VERSION_8812E)||(GET_CHIP_VER(priv)== VERSION_8881A)) return; #endif #if defined(CONFIG_RTL_92D_SUPPORT) && defined(CONFIG_RTL_NOISE_CONTROL) if (GET_CHIP_VER(priv) == VERSION_8192D){ // priv->pshare->F90_cnt = PHY_QueryBBReg(priv, 0xf90, bMaskHWord); priv->pshare->F94_cnt = PHY_QueryBBReg(priv, 0xf94, bMaskHWord); priv->pshare->F94_cntOK = PHY_QueryBBReg(priv, 0xf94, bMaskLWord); RTL_W32(RXERR_RPT,(RTL_R32(RXERR_RPT)&0x0fffffff)|0x70000000); priv->pshare->Reg664_cnt = RTL_R32(RXERR_RPT) & 0xfffff; RTL_W32(RXERR_RPT,(RTL_R32(RXERR_RPT)&0x0fffffff)|0x60000000); priv->pshare->Reg664_cntOK = RTL_R32(RXERR_RPT) & 0xfffff; } #endif #if !defined(CONFIG_RTL_NEW_AUTOCH) signed char value8; // read OFDM FA counters priv->pshare->ofdm_FA_cnt1 = RTL_R16(0xda2); priv->pshare->ofdm_FA_cnt2 = RTL_R16(0xda4); priv->pshare->ofdm_FA_cnt3 = RTL_R16(0xda6); priv->pshare->ofdm_FA_cnt4 = RTL_R16(0xda8); // read the CCK FA counters value8 = RTL_R8(0xa2d); RTL_W8(0xa2d, value8 | 0x40); // regA2D[6]=1 to hold and read the CCK FA counters 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); 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); if (priv->pshare->rf_ft_var.rssi_dump) priv->pshare->CCA_total_cnt = ((RTL_R8(0xa60)<<8)|RTL_R8(0xa61)) + RTL_R16(0xda0); #else hold_CCA_FA_counter(priv); _FA_statistic(priv); if (priv->pshare->rf_ft_var.rssi_dump) priv->pshare->CCA_total_cnt = ((RTL_R8(0xa60)<<8)|RTL_R8(0xa61)) + RTL_R16(0xda0); release_CCA_FA_counter(priv); #endif reset_FA_reg(priv); #if defined(CONFIG_RTL_92D_SUPPORT) && defined(CONFIG_RTL_NOISE_CONTROL) if (GET_CHIP_VER(priv) == VERSION_8192D){ if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G && !(OPMODE & WIFI_SITE_MONITOR)) { if (priv->pshare->DNC_on == 0){ //if ((priv->pshare->F94_cnt + priv->pshare->F90_cnt)> 3000){ /* Reg 664: x > y && x > 1000 Reg F94: x > 0.75*y && x > 1000 */ if (((priv->pshare->Reg664_cnt>priv->pshare->Reg664_cntOK) && (priv->pshare->Reg664_cnt > 1000))|| ((priv->pshare->F94_cnt > ((priv->pshare->Reg664_cntOK*3)>>2)) && (priv->pshare->F94_cnt > 1000))) { priv->ext_stats.tp_average_pre = (priv->ext_stats.tx_avarage+priv->ext_stats.rx_avarage)>>17; priv->pshare->DNC_on = 1; priv->pshare->DNC_chk_cnt = 1; priv->pshare->DNC_chk = 2; // 0: don't check, 1; check, 2: just entering DNC //PHY_SetBBReg(priv, 0xb30, bMaskDWord, 0x00a00000); PHY_SetBBReg(priv, 0x870, bMaskDWord, 0x07600760); PHY_SetBBReg(priv, 0xc50, bMaskByte0, 0x20); PHY_SetBBReg(priv, 0xc58, bMaskByte0, 0x20); //printk("Dynamic Noise Control ON\n"); } } else { if ((priv->pshare->DNC_chk_cnt % 5)==0){ // check every 5*2=10 seconds unsigned long tp_now = (priv->ext_stats.tx_avarage+priv->ext_stats.rx_avarage)>>17; priv->pshare->DNC_chk_cnt = 0; if ((priv->pshare->DNC_chk == 2) && (tp_now < priv->ext_stats.tp_average_pre+5)){ //no advantage, leave DNC state priv->pshare->DNC_on = 0; priv->pshare->DNC_chk = 0; //PHY_SetBBReg(priv, 0xb30, bMaskDWord, 0); PHY_SetBBReg(priv, 0x870, bMaskDWord, 0x07000700); } else { priv->pshare->DNC_chk = 0; /* If TP < 20M or TP varies more than 5M. Start Checking...*/ if ((tp_now < 20) || ((tp_now < (priv->ext_stats.tp_average_pre-5))|| (tp_now > (priv->ext_stats.tp_average_pre+5)))){ priv->pshare->DNC_chk = 1; //PHY_SetBBReg(priv, 0xb30, bMaskDWord, 0); PHY_SetBBReg(priv, 0x870, bMaskDWord, 0x07000700); if (!timer_pending(&priv->dnc_timer)) { //printk("... Start Check Noise ...\n"); mod_timer(&priv->dnc_timer, jiffies + RTL_MILISECONDS_TO_JIFFIES(100)); // 100 ms } } } priv->ext_stats.tp_average_pre = tp_now; } else if ((priv->pshare->DNC_chk_cnt % 5)==1 && priv->pshare->DNC_chk == 1) { priv->pshare->DNC_chk = 0; //if ((priv->pshare->F94_cnt + priv->pshare->F90_cnt) < 120) { if ((priv->pshare->F94_cnt + priv->pshare->Reg664_cnt) < 120) { priv->pshare->DNC_on = 0; //PHY_SetBBReg(priv, 0xb30, bMaskDWord, 0); PHY_SetBBReg(priv, 0x870, bMaskDWord, 0x07000700); //printk("Dynamic Noise Control OFF\n"); } } priv->pshare->DNC_chk_cnt++; } } } #endif } //3 ============================================================ //3 Rate Adaptive //3 ============================================================ void check_RA_by_rssi(struct rtl8192cd_priv *priv, struct stat_info *pstat) { int level = 0; switch (pstat->rssi_level) { case 1: if (pstat->rssi >= priv->pshare->rf_ft_var.raGoDownUpper) level = 1; else if ((pstat->rssi >= priv->pshare->rf_ft_var.raGoDown20MLower) || ((priv->pshare->is_40m_bw) && (pstat->ht_cap_len) && (pstat->rssi >= priv->pshare->rf_ft_var.raGoDown40MLower) && (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SUPPORT_CH_WDTH_)))) level = 2; else level = 3; break; case 2: if (pstat->rssi > priv->pshare->rf_ft_var.raGoUpUpper) level = 1; else if ((pstat->rssi < priv->pshare->rf_ft_var.raGoDown40MLower) || ((!pstat->ht_cap_len || !priv->pshare->is_40m_bw || !(pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SUPPORT_CH_WDTH_))) && (pstat->rssi < priv->pshare->rf_ft_var.raGoDown20MLower))) level = 3; else level = 2; break; case 3: if (pstat->rssi > priv->pshare->rf_ft_var.raGoUpUpper) level = 1; else if ((pstat->rssi > priv->pshare->rf_ft_var.raGoUp20MLower) || ((priv->pshare->is_40m_bw) && (pstat->ht_cap_len) && (pstat->rssi > priv->pshare->rf_ft_var.raGoUp40MLower) && (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SUPPORT_CH_WDTH_)))) level = 2; else level = 3; break; default: if (isErpSta(pstat)) DEBUG_ERR("wrong rssi level setting\n"); break; } if (level != pstat->rssi_level && CHIP_VER_92X_SERIES(priv)) { pstat->rssi_level = level; #ifdef CONFIG_RTL_88E_SUPPORT if (GET_CHIP_VER(priv)==VERSION_8188E) { #ifdef TXREPORT add_RATid(priv, pstat); #endif } else #endif { #if defined(CONFIG_RTL_92D_SUPPORT) || defined(CONFIG_RTL_92C_SUPPORT) add_update_RATid(priv, pstat); #endif } } } void add_RATid(struct rtl8192cd_priv *priv, struct stat_info *pstat) { unsigned char limit=16; int i; #ifndef SMP_SYNC unsigned long flags; #endif #if defined(CONFIG_RTL_92D_SUPPORT) || defined(CONFIG_RTL_92C_SUPPORT) unsigned int update_reg=0; #endif SAVE_INT_AND_CLI(flags); pstat->tx_ra_bitmap = 0; for (i=0; i<32; i++) { if (pstat->bssrateset[i]) pstat->tx_ra_bitmap |= get_bit_value_from_ieee_value(pstat->bssrateset[i]&0x7f); } if (pstat->ht_cap_len) { if ((pstat->MIMO_ps & _HT_MIMO_PS_STATIC_) || (get_rf_mimo_mode(priv)== MIMO_1T2R) || (get_rf_mimo_mode(priv)== MIMO_1T1R)) limit=8; for (i=0; iht_cap_buf.support_mcs[i/8] & BIT(i%8)) pstat->tx_ra_bitmap |= BIT(i+12); } } if (pstat->ht_cap_len) { unsigned int set_sgi = 0; if (priv->pshare->is_40m_bw && (pstat->tx_bw == HT_CHANNEL_WIDTH_20_40) #ifdef WIFI_11N_2040_COEXIST && !((OPMODE & WIFI_AP_STATE) && priv->pmib->dot11nConfigEntry.dot11nCoexist && (priv->bg_ap_timeout || orForce20_Switch20Map(priv) )) #endif ) { if (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SHORTGI_40M_) && priv->pmib->dot11nConfigEntry.dot11nShortGIfor40M) set_sgi++; } else if (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SHORTGI_20M_) && priv->pmib->dot11nConfigEntry.dot11nShortGIfor20M) { set_sgi++; } if (set_sgi) { #if defined(CONFIG_RTL_88E_SUPPORT) && defined(TXREPORT) if (GET_CHIP_VER(priv)==VERSION_8188E) #ifdef RATEADAPTIVE_BY_ODM ODMPTR->RAInfo[pstat->aid].SGIEnable = 1; #else priv->pshare->RaInfo[pstat->aid].SGIEnable = 1; #endif else #endif pstat->tx_ra_bitmap |= BIT(28); } #if defined(CONFIG_RTL_88E_SUPPORT) && defined(TXREPORT) else { if (GET_CHIP_VER(priv)==VERSION_8188E) #ifdef RATEADAPTIVE_BY_ODM ODMPTR->RAInfo[pstat->aid].SGIEnable = 0; #else priv->pshare->RaInfo[pstat->aid].SGIEnable = 0; #endif } #endif } #if defined(CONFIG_RTL_88E_SUPPORT) && defined(TXREPORT) else { if (GET_CHIP_VER(priv)==VERSION_8188E) #ifdef RATEADAPTIVE_BY_ODM ODMPTR->RAInfo[pstat->aid].SGIEnable = 0; #else priv->pshare->RaInfo[pstat->aid].SGIEnable = 0; #endif } #endif #ifdef USE_OUT_SRC if(IS_OUTSRC_CHIP(priv)) { if ((pstat->rssi_level < 1) || (pstat->rssi_level > 4)) ODM_RAStateCheck(ODMPTR, (s4Byte)pstat->rssi, FALSE, &pstat->rssi_level) ; } else #endif { if ((pstat->rssi_level < 1) || (pstat->rssi_level > 3)) { if (pstat->rssi >= priv->pshare->rf_ft_var.raGoDownUpper) pstat->rssi_level = 1; else if ((pstat->rssi >= priv->pshare->rf_ft_var.raGoDown20MLower) || ((priv->pshare->is_40m_bw) && (pstat->ht_cap_len) && (pstat->rssi >= priv->pshare->rf_ft_var.raGoDown40MLower) && (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SUPPORT_CH_WDTH_)))) pstat->rssi_level = 2; else pstat->rssi_level = 3; } } if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) && ((OPMODE & WIFI_AP_STATE) || (priv->pmib->dot11RFEntry.phyBandSelect & PHY_BAND_5G))) pstat->tx_ra_bitmap &= 0xfffffff0; //disable cck rate #ifdef P2P_SUPPORT if(pstat->is_p2p_client){ pstat->tx_ra_bitmap &= 0xfffffff0; //disable cck rate } #endif // rate adaptive by rssi if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len && (!should_restrict_Nrate(priv, pstat))) { if ((get_rf_mimo_mode(priv) == MIMO_1T2R) || (get_rf_mimo_mode(priv) == MIMO_1T1R)) { switch (pstat->rssi_level) { case 1: pstat->tx_ra_bitmap &= 0x100f0000; break; case 2: pstat->tx_ra_bitmap &= 0x100ff000; break; case 3: if (priv->pshare->is_40m_bw) pstat->tx_ra_bitmap &= 0x100fe00f; else pstat->tx_ra_bitmap &= 0x100fe00f; break; } } else { switch (pstat->rssi_level) { case 1: pstat->tx_ra_bitmap &= 0x1f8f0000; break; case 2: pstat->tx_ra_bitmap &= 0x1f8ff00D; break; case 3: if (priv->pshare->is_40m_bw) pstat->tx_ra_bitmap &= 0x010fe00f; else pstat->tx_ra_bitmap &= 0x010ff00f; break; } // Don't need to mask high rates due to new rate adaptive parameters //if (pstat->is_broadcom_sta) // use MCS12 as the highest rate vs. Broadcom sta // pstat->tx_ra_bitmap &= 0x81ffffff; // NIC driver will report not supporting MCS15 and MCS14 in asoc req //if (pstat->is_rtl8190_sta && !pstat->is_2t_mimo_sta) // pstat->tx_ra_bitmap &= 0x83ffffff; // if Realtek 1x2 sta, don't use MCS15 and MCS14 } } else if (((priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) && isErpSta(pstat)) || ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) && ((OPMODE & WIFI_AP_STATE) || (priv->pmib->dot11RFEntry.phyBandSelect & PHY_BAND_5G)))) { switch (pstat->rssi_level) { case 1: pstat->tx_ra_bitmap &= 0x00000f00; break; case 2: pstat->tx_ra_bitmap &= 0x00000ff0; break; case 3: pstat->tx_ra_bitmap &= 0x00000fef; break; } } else { pstat->tx_ra_bitmap &= 0x0000000d; } // Client mode IOT issue, Button 2009.07.17 #ifdef CLIENT_MODE if(OPMODE & WIFI_STATION_STATE) { if((pstat->IOTPeer!=HT_IOT_PEER_REALTEK_92SE) && pstat->is_realtek_sta && pstat->is_legacy_encrpt) pstat->tx_ra_bitmap &= 0x0001ffff; // up to MCS4 } #endif #if defined(CONFIG_RTL_92D_SUPPORT) && defined (USB_POWER_SUPPORT) if ((GET_CHIP_VER(priv)==VERSION_8192D) && (priv->pmib->dot11RFEntry.phyBandSelect & PHY_BAND_5G)) pstat->tx_ra_bitmap &= USB_RA_MASK; #endif update_remapAid(priv,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; else priv->pshare->RaInfo[pstat->aid].RateID = ARFR_1T_20M; } else if (pstat->tx_ra_bitmap & 0xff0) { priv->pshare->RaInfo[pstat->aid].RateID = ARFR_BG_MIX; } else { priv->pshare->RaInfo[pstat->aid].RateID = ARFR_B_ONLY; } 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->SGIEnable); #endif } else #endif #if defined(CONFIG_RTL_92D_SUPPORT) || defined(CONFIG_RTL_92C_SUPPORT) if(CHIP_VER_92X_SERIES(priv)) { if (pstat->sta_in_firmware == 1) { #ifdef CONFIG_RTL_92D_SUPPORT if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G) { pstat->tx_ra_bitmap &= 0xfffffff0; if (pstat->tx_ra_bitmap & 0xff00000) { if (priv->pshare->is_40m_bw) set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_2T_Band_A_40M, pstat->tx_ra_bitmap); else set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_2T_Band_A_20M, pstat->tx_ra_bitmap); update_reg++; } else if (pstat->tx_ra_bitmap & 0xff000) { if (priv->pshare->is_40m_bw) set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_2T_Band_A_40M, pstat->tx_ra_bitmap); else set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_2T_Band_A_20M, pstat->tx_ra_bitmap); } else if (pstat->tx_ra_bitmap & 0xff0) { set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_Band_A_BMC, pstat->tx_ra_bitmap); } else { set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_Band_A_BMC, pstat->tx_ra_bitmap); } } else #endif { if (pstat->tx_ra_bitmap & 0xff00000) { if (priv->pshare->is_40m_bw) set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_2T_40M, pstat->tx_ra_bitmap); else set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_2T_20M, pstat->tx_ra_bitmap); update_reg++; } else if (pstat->tx_ra_bitmap & 0xff000) { if (priv->pshare->is_40m_bw) set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_1T_40M, pstat->tx_ra_bitmap); else set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_1T_20M, pstat->tx_ra_bitmap); } else if (pstat->tx_ra_bitmap & 0xff0) { set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_BG_MIX, pstat->tx_ra_bitmap); } else { set_RATid_cmd(priv, REMAP_AID(pstat), ARFR_B_ONLY, pstat->tx_ra_bitmap); } } /* * Rate adaptive algorithm. * If the STA is 2R, we set the inti rate to MCS 15 */ if (update_reg) { if (!pstat->check_init_tx_rate && (pstat->rssi > 55)) { RTL_W8(INIDATA_RATE_SEL + REMAP_AID(pstat), 0x1b); pstat->check_init_tx_rate = 1; } } DEBUG_INFO("Add id %d val %08x to ratr\n", pstat->aid, pstat->tx_ra_bitmap); } else { #ifdef CONFIG_RTL_92D_SUPPORT if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G) { if (priv->pshare->is_40m_bw) set_RATid_cmd(priv, priv->pshare->fw_support_sta_num, ARFR_2T_Band_A_40M, 0x1ffffff0); else set_RATid_cmd(priv, priv->pshare->fw_support_sta_num, ARFR_2T_Band_A_20M, 0x1ffffff0); } else #endif { if (priv->pshare->is_40m_bw) set_RATid_cmd(priv, priv->pshare->fw_support_sta_num, ARFR_2T_40M, 0x1fffffff); else set_RATid_cmd(priv, priv->pshare->fw_support_sta_num, ARFR_2T_20M, 0x1fffffff); } } } #endif RESTORE_INT(flags); } void rtl8192cd_NHMBBInit(struct rtl8192cd_priv *priv) { RTL_W16(0x894+2, 0xc350); //0x894[31:16]=0xffff Time duration for NHM unit: 4us, 0x2710=40ms RTL_W16(0x890+2, 0xffff); //0x890[31:16]=0xffff th_9, th_10 RTL_W32(0x898, 0xffffff50); //0x898=0xffffff50 th_3, th_2, th_1, th_0 RTL_W32(0x89c, 0xffffffff); //0x89c=0xffffffff th_7, th_6, th_5, th_4 PHY_SetBBReg(priv, 0xe28, bMaskByte0, 0xff); //0xe28[7:0]=0xff th_8 PHY_SetBBReg(priv, 0x890, BIT10|BIT9|BIT8, 0x1); //0x890[9:8]=3 enable CCX PHY_SetBBReg(priv, 0xc0c, BIT7, 0x1); //0xc0c[7]=1 } void rtl8192cd_GetNHMCounterStatistics(struct rtl8192cd_priv *priv) { u4Byte value32 = 0; value32 = PHY_QueryBBReg(priv, 0x8d8, bMaskDWord); priv->pshare->rf_ft_var.NHM_cnt_0 = (u1Byte)(value32 & bMaskByte0); priv->pshare->rf_ft_var.NHM_cnt_1 = (u1Byte)((value32 & bMaskByte1)>>8); } void rtl8192cd_NHMCounterStatisticsReset(struct rtl8192cd_priv *priv) { PHY_SetBBReg(priv, 0x890, BIT1, 0); PHY_SetBBReg(priv, 0x890, BIT1, 1); } void rtl8192cd_NHMCounterStatistics(struct rtl8192cd_priv *priv) { // Get NHM report rtl8192cd_GetNHMCounterStatistics(priv); // Reset NHM counter rtl8192cd_NHMCounterStatisticsReset(priv); } void rtl8192cd_SetTRxMux(struct rtl8192cd_priv *priv, u1Byte txMode, u1Byte rxMode) { PHY_SetBBReg(priv, 0x824, BIT3|BIT2|BIT1, txMode); // set TXmode to standby mode to remove outside noise affect PHY_SetBBReg(priv, 0x824, BIT22|BIT21|BIT20, rxMode); // set RXmode to standby mode to remove outside noise affect if(get_rf_mimo_mode(priv) != MIMO_1T1R) { PHY_SetBBReg(priv, 0x82c, BIT3|BIT2|BIT1, txMode); // set TXmode to standby mode to remove outside noise affect PHY_SetBBReg(priv, 0x82c, BIT22|BIT21|BIT20, rxMode); // set RXmode to standby mode to remove outside noise affect } } void rtl8192cd_SetEDCCAThreshold(struct rtl8192cd_priv *priv, s1Byte H2L, s1Byte L2H) { PHY_SetBBReg(priv,rOFDM0_ECCAThreshold, bMaskByte0, (u1Byte)L2H); PHY_SetBBReg(priv,rOFDM0_ECCAThreshold, bMaskByte2, (u1Byte)H2L); } void rtl8192cd_SearchPwdBLowerBound(struct rtl8192cd_priv *priv) { u4Byte value32; u1Byte cnt, IGI_Pause = 0x7f, IGI_Resume = 0x20, IGI = 0x50; //IGI = 0x50 for cal EDCCA lower bound BOOLEAN bAdjust = TRUE, bAdjust2 = TRUE;; s1Byte TH_L2H_dmc, TH_H2L_dmc, Diff, IGI_target = 0x32; u1Byte txEdcca1 = 0, txEdcca0 = 0; rtl8192cd_SetTRxMux(priv, 1, 1); // Set both Tx mode and Rx mode to standby mode RTL_W8(0xc50,IGI_Pause); RTL_W8(0xc58,IGI_Pause); Diff = IGI_target -(s1Byte)IGI; TH_L2H_dmc = priv->pshare->rf_ft_var.TH_L2H_ini + Diff; if(TH_L2H_dmc > 10) TH_L2H_dmc = 10; TH_H2L_dmc = TH_L2H_dmc - priv->pshare->rf_ft_var.TH_EDCCA_HL_diff; rtl8192cd_SetEDCCAThreshold(priv,TH_H2L_dmc,TH_L2H_dmc); delay_ms(5); while(bAdjust) { for(cnt=0; cnt<250; cnt ++) { value32 = PHY_QueryBBReg(priv,0xDF4, bMaskDWord); if ( (GET_CHIP_VER(priv) == VERSION_8188E) && (value32 & BIT30) ) txEdcca1 = txEdcca1 + 1; else if(value32 & BIT29) txEdcca1 = txEdcca1 + 1; else txEdcca0 = txEdcca0 + 1; } if(txEdcca1 > 1) { IGI = IGI -1; TH_L2H_dmc = TH_L2H_dmc + 1; if(TH_L2H_dmc > 10) TH_L2H_dmc = 10; TH_H2L_dmc = TH_L2H_dmc - priv->pshare->rf_ft_var.TH_EDCCA_HL_diff; rtl8192cd_SetEDCCAThreshold(priv,TH_H2L_dmc,TH_L2H_dmc); txEdcca1 = 0; txEdcca0 = 0; if(TH_L2H_dmc == 10) { bAdjust = FALSE; priv->pshare->rf_ft_var.H2L_lb = TH_H2L_dmc; priv->pshare->rf_ft_var.L2H_lb = TH_L2H_dmc; priv->pshare->rf_ft_var.Adaptivity_IGI_upper = IGI; } } else { bAdjust = FALSE; txEdcca1 = 0; txEdcca0 = 0; priv->pshare->rf_ft_var.H2L_lb = TH_H2L_dmc; priv->pshare->rf_ft_var.L2H_lb = TH_L2H_dmc; priv->pshare->rf_ft_var.Adaptivity_IGI_upper = IGI; } } while (bAdjust2) { rtl8192cd_SetEDCCAThreshold(priv, priv->pshare->rf_ft_var.H2L_lb, priv->pshare->rf_ft_var.L2H_lb); for (cnt = 0; cnt < 250; cnt++) { value32 = PHY_QueryBBReg(priv,0xDF4, bMaskDWord); if ( (GET_CHIP_VER(priv) == VERSION_8188E) && (value32 & BIT30) ) txEdcca1 = txEdcca1 + 1; else if (value32 & BIT29) txEdcca1 = txEdcca1 + 1; else txEdcca0 = txEdcca0 + 1; } if (txEdcca1 > 1) { priv->pshare->rf_ft_var.Adaptivity_IGI_upper -= 1; priv->pshare->rf_ft_var.H2L_lb += 1; priv->pshare->rf_ft_var.L2H_lb += 1; } else bAdjust2 = FALSE; } priv->pshare->rf_ft_var.Adaptivity_IGI_upper -= priv->pshare->rf_ft_var.dcbackoff; priv->pshare->rf_ft_var.H2L_lb += priv->pshare->rf_ft_var.dcbackoff; priv->pshare->rf_ft_var.L2H_lb += priv->pshare->rf_ft_var.dcbackoff; rtl8192cd_SetTRxMux(priv, 2, 3); // Set 2:Tx mode and 3:Rx mode RTL_W8(0xc50,IGI_Resume); RTL_W8(0xc58,IGI_Resume); rtl8192cd_SetEDCCAThreshold(priv,0x7f,0x7f); } void rtl8192cd_MACEDCCAState(struct rtl8192cd_priv *priv, u1Byte State) { if(State == 0)//ignore edcca { PHY_SetBBReg(priv, REG_TX_PTCL_CTRL, BIT15, 1); //ignore EDCCA reg520[15]=1 PHY_SetBBReg(priv, REG_RD_CTRL, BIT11, 0); //reg524[11]=0 } else // don't set MAC ignore EDCCA signal { PHY_SetBBReg(priv, REG_TX_PTCL_CTRL, BIT15, 0); //don't ignore EDCCA reg520[15]=0 PHY_SetBBReg(priv, REG_RD_CTRL, BIT11, 1); //reg524[11]=1 } } void rtl8192cd_AdaptivityInit(struct rtl8192cd_priv *priv) { rtl8192cd_NHMBBInit(priv); priv->pshare->rf_ft_var.TH_L2H_ini = priv->pshare->rf_ft_var.TH_L2H_ini_backup; priv->pshare->rf_ft_var.TH_EDCCA_HL_diff = 7; priv->pshare->rf_ft_var.TH_L2H_ini_mode2 = 20; priv->pshare->rf_ft_var.TH_EDCCA_HL_diff_mode2 = 8; priv->pshare->rf_ft_var.TH_EDCCA_HL_diff_backup = priv->pshare->rf_ft_var.TH_EDCCA_HL_diff ; priv->pshare->rf_ft_var.IGI_Base = 0x32; priv->pshare->rf_ft_var.IGI_target = 0x1c; priv->pshare->rf_ft_var.H2L_lb = 0; priv->pshare->rf_ft_var.L2H_lb = 0; priv->pshare->rf_ft_var.Adaptivity_IGI_upper = 0; priv->pshare->rf_ft_var.NHMWait = 0; priv->pshare->rf_ft_var.bCheck = FALSE; priv->pshare->rf_ft_var.bFirstLink = TRUE; priv->pshare->rf_ft_var.Adaptivity_enable = FALSE; // use this flag to judge enable or disable if(priv->pshare->rf_ft_var.adaptivity_enable == 2) priv->pshare->rf_ft_var.DynamicLinkAdaptivity = TRUE; else priv->pshare->rf_ft_var.DynamicLinkAdaptivity = FALSE; rtl8192cd_MACEDCCAState(priv, 1); PHY_SetBBReg(priv,0x908, bMaskDWord, 0x208); PHY_SetBBReg(priv, 0xc4c, BIT9 | BIT8, 0x0);// set forgetting factor = 0 for all n series IC rtl8192cd_SearchPwdBLowerBound(priv); } BOOLEAN rtl8192cd_CalNHMcnt(struct rtl8192cd_priv *priv) { u2Byte Base = 0; Base = priv->pshare->rf_ft_var.NHM_cnt_0 + priv->pshare->rf_ft_var.NHM_cnt_1; if(Base != 0) { priv->pshare->rf_ft_var.NHM_cnt_0 = ((priv->pshare->rf_ft_var.NHM_cnt_0) << 8) / Base; priv->pshare->rf_ft_var.NHM_cnt_1 = ((priv->pshare->rf_ft_var.NHM_cnt_1) << 8) / Base; } if((priv->pshare->rf_ft_var.NHM_cnt_0 - priv->pshare->rf_ft_var.NHM_cnt_1) >= 100) return TRUE; // clean environment else return FALSE; //noisy environment } void rtl8192cd_CheckEnvironment(struct rtl8192cd_priv *priv) { BOOLEAN isCleanEnvironment = FALSE; if(priv->pshare->rf_ft_var.bFirstLink == TRUE) { priv->pshare->rf_ft_var.adaptivity_flag = TRUE; priv->pshare->rf_ft_var.bFirstLink = FALSE; return; } else { if(priv->pshare->rf_ft_var.NHMWait < 3) // Start enter NHM after 4 NHMWait { priv->pshare->rf_ft_var.NHMWait ++; rtl8192cd_NHMCounterStatistics(priv); return; } else { rtl8192cd_NHMCounterStatistics(priv); isCleanEnvironment = rtl8192cd_CalNHMcnt(priv); if(isCleanEnvironment == TRUE) { priv->pshare->rf_ft_var.TH_L2H_ini = priv->pshare->rf_ft_var.TH_L2H_ini_backup; //mode 1 priv->pshare->rf_ft_var.TH_EDCCA_HL_diff= priv->pshare->rf_ft_var.TH_EDCCA_HL_diff_backup; priv->pshare->rf_ft_var.Adaptivity_enable = TRUE; priv->pshare->rf_ft_var.adaptivity_flag = TRUE; } else { priv->pshare->rf_ft_var.TH_L2H_ini = priv->pshare->rf_ft_var.TH_L2H_ini_mode2; // for AP mode 2 priv->pshare->rf_ft_var.TH_EDCCA_HL_diff= priv->pshare->rf_ft_var.TH_EDCCA_HL_diff_mode2; priv->pshare->rf_ft_var.Adaptivity_enable = FALSE; priv->pshare->rf_ft_var.adaptivity_flag = FALSE; } priv->pshare->rf_ft_var.bFirstLink = TRUE; priv->pshare->rf_ft_var.bCheck = TRUE; } } } void rtl8192cd_CheckAdaptivity(struct rtl8192cd_priv *priv) { if(priv->pshare->rf_ft_var.adaptivity_enable) { if(priv->pshare->rf_ft_var.DynamicLinkAdaptivity == TRUE) { if( priv->pshare->rf_ft_var.bLinked && !priv->pshare->rf_ft_var.bCheck ) { rtl8192cd_NHMCounterStatistics(priv); rtl8192cd_CheckEnvironment(priv); } else if( !priv->pshare->rf_ft_var.bLinked ) { priv->pshare->rf_ft_var.bCheck = FALSE; } } else { priv->pshare->rf_ft_var.Adaptivity_enable = TRUE; priv->pshare->rf_ft_var.adaptivity_flag = TRUE; } } else { priv->pshare->rf_ft_var.Adaptivity_enable = FALSE; priv->pshare->rf_ft_var.adaptivity_flag = FALSE; } } void rtl8192cd_Adaptivity(struct rtl8192cd_priv *priv, u1Byte IGI) { s1Byte Diff, IGI_target, TH_L2H_dmc, TH_H2L_dmc; if(priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_20) IGI_target = priv->pshare->rf_ft_var.IGI_Base; else if(priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) IGI_target = priv->pshare->rf_ft_var.IGI_Base + 2; else IGI_target = priv->pshare->rf_ft_var.IGI_Base; priv->pshare->rf_ft_var.IGI_target = IGI_target; if ( priv->pshare->rf_ft_var.adap_debug ) { printk("DynamicLinkAdaptivity=%d, adaptivity_flag=%d, Adaptivity_enable=%d, bLinked=%d\n", priv->pshare->rf_ft_var.DynamicLinkAdaptivity, priv->pshare->rf_ft_var.adaptivity_flag, priv->pshare->rf_ft_var.Adaptivity_enable, priv->pshare->rf_ft_var.bLinked); } if ( priv->pshare->rf_ft_var.DynamicLinkAdaptivity && !priv->pshare->rf_ft_var.bLinked && !priv->pshare->rf_ft_var.Adaptivity_enable ) { rtl8192cd_SetEDCCAThreshold(priv, 0x7f, 0x7f); return; } Diff = IGI_target -IGI; TH_L2H_dmc = priv->pshare->rf_ft_var.TH_L2H_ini + Diff; TH_H2L_dmc = TH_L2H_dmc - priv->pshare->rf_ft_var.TH_EDCCA_HL_diff; if(TH_L2H_dmc >10) TH_L2H_dmc = 10; TH_H2L_dmc = TH_L2H_dmc - priv->pshare->rf_ft_var.TH_EDCCA_HL_diff; //replace lower bound to prevent EDCCA always equal 1 if(TH_H2L_dmc < priv->pshare->rf_ft_var.H2L_lb) TH_H2L_dmc = priv->pshare->rf_ft_var.H2L_lb; if(TH_L2H_dmc < priv->pshare->rf_ft_var.L2H_lb) TH_L2H_dmc = priv->pshare->rf_ft_var.L2H_lb; if(priv->pshare->rf_ft_var.adap_debug) { printk("TH_L2H_ini=%d, TH_EDCCA_HL_diff=%d\n", priv->pshare->rf_ft_var.TH_L2H_ini, priv->pshare->rf_ft_var.TH_EDCCA_HL_diff); printk("IGI=0x%02x, TH_H2L_dmc=%d, TH_L2H_dmc=%d\n", IGI, TH_H2L_dmc, TH_L2H_dmc); printk("Adaptivity_IGI_upper=0x%02x, H2L_lb=%d, L2H_lb=%d\n", priv->pshare->rf_ft_var.Adaptivity_IGI_upper, priv->pshare->rf_ft_var.H2L_lb, priv->pshare->rf_ft_var.L2H_lb); } rtl8192cd_SetEDCCAThreshold(priv,TH_H2L_dmc,TH_L2H_dmc); } void check_NBI_by_rssi(struct rtl8192cd_priv *priv, unsigned char rssi_strength) { if (OPMODE & WIFI_SITE_MONITOR) return; if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G) return; if (priv->pshare->phw->nbi_filter_on) { if (rssi_strength < 20) NBI_filter_off(priv); } else { // NBI OFF previous if (rssi_strength > 25) NBI_filter_on(priv); } } void NBI_filter_on(struct rtl8192cd_priv *priv) { priv->pshare->phw->nbi_filter_on = 1; #ifdef MP_TEST if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) return; #endif #ifdef RTK_AC_SUPPORT if((GET_CHIP_VER(priv) == VERSION_8812E) || (GET_CHIP_VER(priv) == VERSION_8881A)) RTL_W16(rFPGA0_XCD_RFParam, RTL_R16(rFPGA0_XCD_RFParam) | BIT(13)); // NBI on else #endif RTL_W16(rOFDM0_RxDSP, RTL_R16(rOFDM0_RxDSP) | BIT(9)); // NBI on } void NBI_filter_off(struct rtl8192cd_priv *priv) { priv->pshare->phw->nbi_filter_on = 0; #ifdef MP_TEST if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) return; #endif #ifdef RTK_AC_SUPPORT if((GET_CHIP_VER(priv) == VERSION_8812E) || (GET_CHIP_VER(priv) == VERSION_8881A)) RTL_W16(rFPGA0_XCD_RFParam, RTL_R16(rFPGA0_XCD_RFParam) & ~ BIT(13)); // NBI off else #endif RTL_W16(rOFDM0_RxDSP, RTL_R16(rOFDM0_RxDSP) & ~ BIT(9)); // NBI off } #if defined(CONFIG_WLAN_HAL_8192EE) #ifdef CONFIG_PCI_HCI void RRSR_power_control_11n(struct rtl8192cd_priv *priv, int lower) { #ifndef SMP_SYNC unsigned long x; #endif unsigned long pwrdiff= 0x0c; #ifdef HIGH_POWER_EXT_PA u4Byte pwr_value = 0x16161616; #endif u1Byte pwrlevelHT40_1S_A = priv->pmib->dot11RFEntry.pwrlevelHT40_1S_A[priv->pshare->working_channel-1]; if ((pwrlevelHT40_1S_A == 0) ) return; if (priv->pmib->dot11RFEntry.tx2path) pwrdiff= 0x16; pwrdiff = (priv->pshare->rf_ft_var.min_pwr_idex > pwrdiff) ? pwrdiff: priv->pshare->rf_ft_var.min_pwr_idex; pwrdiff |= (pwrdiff<<24) | (pwrdiff<<16) | (pwrdiff<<8); if( lower && priv->pshare->phw->lower_tx_power== 0) { SAVE_INT_AND_CLI(x); #ifdef HIGH_POWER_EXT_PA if (priv->pshare->rf_ft_var.use_ext_pa) { priv->pshare->phw->power_backup[0x00] = RTL_R32(rTxAGC_A_Rate18_06); priv->pshare->phw->power_backup[0x01] = RTL_R32(rTxAGC_A_Rate54_24); priv->pshare->phw->power_backup[0x02] = RTL_R32(rTxAGC_B_Rate18_06); priv->pshare->phw->power_backup[0x03] = RTL_R32(rTxAGC_B_Rate54_24); priv->pshare->phw->power_backup[0x04] = RTL_R32(rTxAGC_A_Mcs03_Mcs00); priv->pshare->phw->power_backup[0x05] = RTL_R32(rTxAGC_A_Mcs07_Mcs04); priv->pshare->phw->power_backup[0x06] = RTL_R32(rTxAGC_A_Mcs11_Mcs08); priv->pshare->phw->power_backup[0x07] = RTL_R32(rTxAGC_A_Mcs15_Mcs12); priv->pshare->phw->power_backup[0x08] = RTL_R32(rTxAGC_B_Mcs03_Mcs00); priv->pshare->phw->power_backup[0x09] = RTL_R32(rTxAGC_B_Mcs07_Mcs04); priv->pshare->phw->power_backup[0x0a] = RTL_R32(rTxAGC_B_Mcs11_Mcs08); priv->pshare->phw->power_backup[0x0b] = RTL_R32(rTxAGC_B_Mcs15_Mcs12); priv->pshare->phw->power_backup[0x0c] = RTL_R32(rTxAGC_A_CCK11_2_B_CCK11); priv->pshare->phw->power_backup[0x0d] = RTL_R32(rTxAGC_A_CCK1_Mcs32); priv->pshare->phw->power_backup[0x0e] = RTL_R32(rTxAGC_B_CCK5_1_Mcs32); RTL_W32(rTxAGC_A_Mcs03_Mcs00, pwr_value); RTL_W32(rTxAGC_A_Mcs07_Mcs04, pwr_value); RTL_W32(rTxAGC_A_Mcs11_Mcs08, pwr_value); RTL_W32(rTxAGC_A_Mcs15_Mcs12, pwr_value); RTL_W32(rTxAGC_B_Mcs03_Mcs00, pwr_value); RTL_W32(rTxAGC_B_Mcs07_Mcs04, pwr_value); RTL_W32(rTxAGC_B_Mcs11_Mcs08, pwr_value); RTL_W32(rTxAGC_B_Mcs15_Mcs12, pwr_value); RTL_W32(rTxAGC_A_CCK1_Mcs32, (pwr_value & 0x0000ff00) | (priv->pshare->phw->power_backup[0x0d] &0xffff00ff)); // A 1M RTL_W32(rTxAGC_B_CCK5_1_Mcs32, (pwr_value & 0x0000ff00) | (priv->pshare->phw->power_backup[0x0e] &0xffff00ff)); // B 1M } else #endif { priv->pshare->phw->power_backup[0x00] = RTL_R32(rTxAGC_A_Rate18_06); priv->pshare->phw->power_backup[0x01] = RTL_R32(rTxAGC_A_Rate54_24); priv->pshare->phw->power_backup[0x02] = RTL_R32(rTxAGC_B_Rate18_06); priv->pshare->phw->power_backup[0x03] = RTL_R32(rTxAGC_B_Rate54_24); priv->pshare->phw->power_backup[0x0c] = RTL_R32(rTxAGC_A_CCK11_2_B_CCK11); priv->pshare->phw->power_backup[0x0e] = RTL_R32(rTxAGC_B_CCK5_1_Mcs32); } RTL_W32(rTxAGC_A_Rate18_06, priv->pshare->phw->power_backup[0x00]-pwrdiff); RTL_W32(rTxAGC_A_Rate54_24, priv->pshare->phw->power_backup[0x01]-(pwrdiff & 0xff)); RTL_W32(rTxAGC_B_Rate18_06, priv->pshare->phw->power_backup[0x02]-pwrdiff); RTL_W32(rTxAGC_B_Rate54_24, priv->pshare->phw->power_backup[0x03]-(pwrdiff & 0xff)); RTL_W32(rTxAGC_A_CCK11_2_B_CCK11, priv->pshare->phw->power_backup[0x0c]-pwrdiff); RTL_W32(rTxAGC_B_CCK5_1_Mcs32, priv->pshare->phw->power_backup[0x0e]-(pwrdiff & 0xffff0000) ); priv->pshare->phw->lower_tx_power = 1; RESTORE_INT(x); } else if( !lower && priv->pshare->phw->lower_tx_power) { SAVE_INT_AND_CLI(x); #ifdef HIGH_POWER_EXT_PA if (priv->pshare->rf_ft_var.use_ext_pa) { RTL_W32(rTxAGC_A_Mcs03_Mcs00, priv->pshare->phw->power_backup[0x04]); RTL_W32(rTxAGC_A_Mcs07_Mcs04, priv->pshare->phw->power_backup[0x05]); RTL_W32(rTxAGC_A_Mcs11_Mcs08, priv->pshare->phw->power_backup[0x06]); RTL_W32(rTxAGC_A_Mcs15_Mcs12, priv->pshare->phw->power_backup[0x07]); RTL_W32(rTxAGC_B_Mcs03_Mcs00, priv->pshare->phw->power_backup[0x08]); RTL_W32(rTxAGC_B_Mcs07_Mcs04, priv->pshare->phw->power_backup[0x09]); RTL_W32(rTxAGC_B_Mcs11_Mcs08, priv->pshare->phw->power_backup[0x0a]); RTL_W32(rTxAGC_B_Mcs15_Mcs12, priv->pshare->phw->power_backup[0x0b]); RTL_W32(rTxAGC_A_CCK1_Mcs32, priv->pshare->phw->power_backup[0x0d]); } #endif { RTL_W32(rTxAGC_A_Rate18_06, priv->pshare->phw->power_backup[0x00]); RTL_W32(rTxAGC_A_Rate54_24, priv->pshare->phw->power_backup[0x01]); RTL_W32(rTxAGC_B_Rate18_06, priv->pshare->phw->power_backup[0x02]); RTL_W32(rTxAGC_B_Rate54_24, priv->pshare->phw->power_backup[0x03]); RTL_W32(rTxAGC_A_CCK11_2_B_CCK11, priv->pshare->phw->power_backup[0x0c]); RTL_W32(rTxAGC_B_CCK5_1_Mcs32, priv->pshare->phw->power_backup[0x0e]); } priv->pshare->phw->lower_tx_power = 0; RESTORE_INT(x); } } #endif // CONFIG_PCI_HCI #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) void RRSR_power_control_11n(struct rtl8192cd_priv *priv, int lower) { u4Byte val32; if (lower && priv->pshare->phw->lower_tx_power == 0) { priv->pshare->phw->lower_tx_power = 1; val32 = RTL_R32(0x6d8); val32 = (val32 & ~0x001C0000) | 0x00080000; // [ 20:18] = 2 ( -7dB) RTL_W32(0x6d8, val32); } else if (!lower && priv->pshare->phw->lower_tx_power) { priv->pshare->phw->lower_tx_power = 0; val32 = RTL_R32(0x6d8); val32 &= ~0x001C0000; // [ 20:18] = 0 RTL_W32(0x6d8, val32); } } #endif #endif // CONFIG_WLAN_HAL_8192EE #ifdef CONFIG_WLAN_HAL_8814AE void RRSR_power_control_14(struct rtl8192cd_priv *priv, int lower) { u4Byte val32; if (lower && priv->pshare->phw->lower_tx_power == 0) { priv->pshare->phw->lower_tx_power = 1; val32 = RTL_R32(0x6d8); val32 = (val32 & ~0x001C0000) | 0x00080000; // [ 20:18] = 2 ( -7dB) RTL_W32(0x6d8, val32); } else if (!lower && priv->pshare->phw->lower_tx_power) { priv->pshare->phw->lower_tx_power = 0; val32 = RTL_R32(0x6d8); val32 &= ~0x001C0000; // [ 20:18] = 0 RTL_W32(0x6d8, val32); } } #endif //3 ============================================================ //3 PHY calibration //3 ============================================================ #ifndef CALIBRATE_BY_ODM void _PHY_SaveADDARegisters(struct rtl8192cd_priv *priv, unsigned int* ADDAReg, unsigned int* ADDABackup, unsigned int RegisterNum) { unsigned int i; for( i = 0 ; i < RegisterNum ; i++){ ADDABackup[i] = PHY_QueryBBReg(priv, ADDAReg[i], bMaskDWord); } } void _PHY_SetADDARegisters(struct rtl8192cd_priv *priv, unsigned int* ADDAReg, unsigned int* ADDASettings, unsigned int RegisterNum) { unsigned int i; for( i = 0 ; i < RegisterNum ; i++){ PHY_SetBBReg(priv, ADDAReg[i], bMaskDWord, ADDASettings[i]); } } void _PHY_SaveMACRegisters(struct rtl8192cd_priv *priv, unsigned int* MACReg, unsigned int* MACBackup) { unsigned int i; for( i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++){ MACBackup[i] = RTL_R8(MACReg[i]); } MACBackup[i] = RTL_R32( MACReg[i]); } void _PHY_ReloadADDARegisters(struct rtl8192cd_priv *priv, unsigned int* ADDAReg, unsigned int* ADDABackup, unsigned int RegiesterNum) { unsigned int i; for(i = 0 ; i < RegiesterNum; i++){ PHY_SetBBReg(priv, ADDAReg[i], bMaskDWord, ADDABackup[i]); } } void _PHY_ReloadMACRegisters(struct rtl8192cd_priv *priv,unsigned int* MACReg, unsigned int* MACBackup) { unsigned int i; for(i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++){ RTL_W8( MACReg[i], (unsigned char)MACBackup[i]); } RTL_W32( MACReg[i], MACBackup[i]); } void _PHY_MACSettingCalibration(struct rtl8192cd_priv *priv, unsigned int* MACReg, unsigned int* MACBackup) { unsigned int i = 0; RTL_W8(MACReg[i], 0x3F); for(i = 1 ; i < (IQK_MAC_REG_NUM - 1); i++){ RTL_W8( MACReg[i], (unsigned char)(MACBackup[i]&(~ BIT(3)))); } RTL_W8( MACReg[i], (unsigned char)(MACBackup[i]&(~ BIT(5)))); } void _PHY_PathADDAOn(struct rtl8192cd_priv *priv, unsigned int* ADDAReg, char isPathAOn, char is2T) { unsigned int pathOn; unsigned int i; pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4; if(FALSE == is2T){ pathOn = 0x0bdb25a0; PHY_SetBBReg(priv, ADDAReg[0], bMaskDWord, 0x0b1b25a0); } else{ PHY_SetBBReg(priv, ADDAReg[0], bMaskDWord, pathOn); } for( i = 1 ; i < IQK_ADDA_REG_NUM ; i++){ PHY_SetBBReg(priv, ADDAReg[i], bMaskDWord, pathOn); } } #endif void PHY_LCCalibrate(struct rtl8192cd_priv *priv) { unsigned char tmpReg, value_IGI; unsigned int LC_Cal; int isNormal; #if defined(TESTCHIP_SUPPORT) && defined(CONFIG_RTL_92C_SUPPORT) isNormal = (IS_TEST_CHIP(priv)? 0 : 1); #else isNormal = 1; #endif /* 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(0x522, 0xFF); /* block all queues */ /* 2. Set RF mode = standby mode */ if ((tmpReg & 0x70) != 0) { /* Path-A */ PHY_SetRFReg(priv, RF92CD_PATH_A, 0x00, bMask20Bits, 0x10000); /* Path-B */ if (get_rf_mimo_mode(priv) != MIMO_1T1R) PHY_SetRFReg(priv, RF92CD_PATH_B, 0x00, bMask20Bits, 0x10000); } /* 3. Read RF reg18 */ LC_Cal = PHY_QueryRFReg(priv, RF92CD_PATH_A, 0x18, bMask12Bits, 1); /* 4. Set LC calibration begin */ PHY_SetRFReg(priv, RF92CD_PATH_A, 0x18, bMask12Bits, LC_Cal|0x08000); if (GET_CHIP_VER(priv)==VERSION_8192D) watchdog_kick(); if (isNormal) delay_ms(100); else delay_ms(3); /* Restore original situation */ if ((tmpReg & 0x70) != 0) { /* Deal with contisuous TX case */ /* Path-A */ RTL_W8(0xd03, tmpReg); /* Restore RF mdoe & RF gain by change IGI to trigger HW tristate */ value_IGI = (RTL_R8(0xc50) & 0x7F); RTL_W8(0xc50, ((value_IGI!=0x30)?0x30:0x31)); RTL_W8(0xc50, value_IGI); /* Path-B */ if (get_rf_mimo_mode(priv) != MIMO_1T1R) { /* Restore RF mdoe & RF gain by change IGI to trigger HW tristate */ value_IGI = (RTL_R8(0xc58) & 0x7F); RTL_W8(0xc58, ((value_IGI!=0x30)?0x30:0x31)); RTL_W8(0xc58, value_IGI); } } else { /* Deal with Packet TX case */ RTL_W8(0x522, 0x00); } } #endif