/* * Handling routines for DFS (Dynamic Frequency Selection) functions * * $Id: 8192cd_dfs.c,v 1.1 2012/05/04 12:49:07 jimmylin Exp $ * * Copyright (c) 2012 Realtek Semiconductor Corp. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #define _8192CD_DFS_C_ #include "./8192cd_cfg.h" #include "./8192cd.h" #include "./8192cd_headers.h" #include "./8192cd_debug.h" #ifdef RTK_NL80211 #include "8192cd_cfg80211.h" #endif #ifdef DFS #define DFS_VERSION "2.0.5" void rtl8192cd_dfs_chk_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (timer_pending(&priv->dfs_chk_timer)){ del_timer_sync(&priv->dfs_chk_timer); } if (GET_CHIP_VER(priv) == VERSION_8192D) PHY_SetBBReg(priv, 0xcdc, BIT(8)|BIT(9), 1); PRINT_INFO("DFS CP END.\n"); } void set_CHXX_timer(struct rtl8192cd_priv *priv, unsigned int channel) { switch(channel) { case 52: mod_timer(&priv->ch52_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 56: mod_timer(&priv->ch56_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 60: mod_timer(&priv->ch60_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 64: mod_timer(&priv->ch64_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 100: mod_timer(&priv->ch100_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 104: mod_timer(&priv->ch104_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 108: mod_timer(&priv->ch108_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 112: mod_timer(&priv->ch112_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 116: mod_timer(&priv->ch116_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 120: mod_timer(&priv->ch120_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 124: mod_timer(&priv->ch124_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 128: mod_timer(&priv->ch128_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 132: mod_timer(&priv->ch132_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 136: mod_timer(&priv->ch136_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 140: mod_timer(&priv->ch140_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; case 144: mod_timer(&priv->ch144_timer, jiffies + NONE_OCCUPANCY_PERIOD); break; default: DEBUG_ERR("DFS_timer: Channel match none!\n"); break; } } void rtl8192cd_DFS_TXPAUSE_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; unsigned int which_channel; printk("rtl8192cd_DFS_TXPAUSE_timer\n"); if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (priv->available_chnl_num != 0) { if (timer_pending(&priv->DFS_TXPAUSE_timer)) del_timer_sync(&priv->DFS_TXPAUSE_timer); printk("rtl8192cd_DFS_TXPAUSE_timer PATH2\n"); #if defined(UNIVERSAL_REPEATER) if (!under_apmode_repeater(priv)) #endif { /* select a channel */ which_channel = DFS_SelectChannel(priv); priv->pshare->dfsSwitchChannel = which_channel; if (priv->pshare->dfsSwitchChannel == 0) { panic_printk("It should not run to here\n"); return; } else priv->pmib->dot11DFSEntry.DFS_detected = 1; panic_printk("rtl8192cd_DFS_TXPAUSE_timer,dfsSwitchChannel=%d\n",priv->pshare->dfsSwitchChannel); #ifdef MBSSID if (priv->pmib->miscEntry.vap_enable) priv->pshare->dfsSwitchChCountDown = 6; else #endif priv->pshare->dfsSwitchChCountDown = 5; } if (priv->pmib->dot11StationConfigEntry.dot11DTIMPeriod >= priv->pshare->dfsSwitchChCountDown) priv->pshare->dfsSwitchChCountDown = priv->pmib->dot11StationConfigEntry.dot11DTIMPeriod+1; } else { printk("rtl8192cd_DFS_TXPAUSE_timer PATH3\n"); mod_timer(&priv->DFS_TXPAUSE_timer, jiffies + DFS_TXPAUSE_TO); } } void rtl8192cd_DFS_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; unsigned int radar_type = 0; /* 0 for short, 1 for long */ unsigned int dfs_chk = 0; unsigned long throughput = 0; int j; int tp_th = ((priv->pshare->is_40m_bw)?45:20); #ifdef SMP_SYNC unsigned long flags; #endif SMP_LOCK(flags); if (!(priv->drv_state & DRV_STATE_OPEN)) { SMP_UNLOCK(flags); return; } #ifdef PCIE_POWER_SAVING if ((priv->pwr_state == L2) || (priv->pwr_state == L1)) goto exit_timer; #endif throughput = priv->ext_stats.tx_avarage+priv->ext_stats.rx_avarage; #ifdef MBSSID if (priv->pmib->miscEntry.vap_enable) { for (j=0; jpvap_priv[j])) { throughput += priv->pvap_priv[j]->ext_stats.tx_avarage+priv->pvap_priv[j]->ext_stats.rx_avarage; } } } #endif if (throughput>>17>tp_th) { if (GET_CHIP_VER(priv) == VERSION_8192D){ dfs_chk = 1; PHY_SetBBReg(priv, 0xcdc, BIT(8)|BIT(9), 0); } } else { dfs_chk = 0; if (GET_CHIP_VER(priv) == VERSION_8192D) PHY_SetBBReg(priv, 0xcdc, BIT(8)|BIT(9), 1); } if (!(priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_ETSI)) { if (GET_CHIP_VER(priv) == VERSION_8192D) { if (PHY_QueryBBReg(priv, 0xcf8, BIT(31))) { radar_type++; priv->pmib->dot11DFSEntry.DFS_detected = 1; } } else if ((GET_CHIP_VER(priv) == VERSION_8812E) || (GET_CHIP_VER(priv) == VERSION_8881A) || (GET_CHIP_VER(priv) == VERSION_8814A)) { if (priv->pshare->rf_ft_var.dfs_det_off == 1) { if (PHY_QueryBBReg(priv, 0xf98, BIT(19))) { radar_type++; priv->pmib->dot11DFSEntry.DFS_detected = 1; } } } } if (GET_CHIP_VER(priv) == VERSION_8192D) { if (PHY_QueryBBReg(priv, 0xcf8, BIT(23))) priv->pmib->dot11DFSEntry.DFS_detected = 1; } else if ((GET_CHIP_VER(priv) == VERSION_8812E) || (GET_CHIP_VER(priv) == VERSION_8881A) || (GET_CHIP_VER(priv) == VERSION_8814A)) { if (priv->pshare->rf_ft_var.dfs_det_off == 1) { if (PHY_QueryBBReg(priv, 0xf98, BIT(17))) priv->pmib->dot11DFSEntry.DFS_detected = 1; } } /* * DFS debug mode for logo test */ if (!priv->pmib->dot11DFSEntry.disable_DFS && priv->pshare->rf_ft_var.dfsdbgmode && priv->pmib->dot11DFSEntry.DFS_detected) { if ((jiffies - priv->pshare->rf_ft_var.dfsrctime)>RTL_SECONDS_TO_JIFFIES(10)) priv->pshare->rf_ft_var.dfsdbgcnt = 1; else priv->pshare->rf_ft_var.dfsdbgcnt++; if (GET_CHIP_VER(priv) == VERSION_8192D) { if (priv->pshare->rf_ft_var.dfs_det_print1) panic_printk("[%d] DFS dbg mode, Radar is detected as %x %08x (%d)!\n", priv->pshare->rf_ft_var.dfsdbgcnt, radar_type, PHY_QueryBBReg(priv, 0xcf4, bMaskDWord), (unsigned int)RTL_JIFFIES_TO_MILISECONDS(jiffies)); } else if ((GET_CHIP_VER(priv) == VERSION_8812E) || (GET_CHIP_VER(priv) == VERSION_8881A) || (GET_CHIP_VER(priv) == VERSION_8814A)) { if (priv->pshare->rf_ft_var.dfs_det_print1) panic_printk("[%d] DFS dbg mode, Radar is detected as %x %08x (%d)!\n", priv->pshare->rf_ft_var.dfsdbgcnt, radar_type, PHY_QueryBBReg(priv, 0xf98, 0xffffffff), (unsigned int)RTL_JIFFIES_TO_MILISECONDS(jiffies)); RTL_W32(0x920, RTL_R32(0x920) | (BIT(24) | BIT(25) | BIT(28))); RTL_W32(0x920, RTL_R32(0x920) & ~(BIT(24) | BIT(25) | BIT(28))); } priv->pshare->rf_ft_var.dfsrctime = jiffies; priv->pmib->dot11DFSEntry.DFS_detected = 0; if (GET_CHIP_VER(priv) == VERSION_8192D) { PHY_SetBBReg(priv, 0xc84, BIT(25), 0); PHY_SetBBReg(priv, 0xc84, BIT(25), 1); } goto exit_timer; } if (!priv->pmib->dot11DFSEntry.disable_DFS && priv->pmib->dot11DFSEntry.DFS_detected) { if (GET_CHIP_VER(priv) == VERSION_8192D) { PRINT_INFO("Radar is detected as %x %08x (%d)!\n", radar_type, PHY_QueryBBReg(priv, 0xcf4, bMaskDWord), (unsigned int)RTL_JIFFIES_TO_MILISECONDS(jiffies)); } else if ((GET_CHIP_VER(priv) == VERSION_8812E) || (GET_CHIP_VER(priv) == VERSION_8881A) || (GET_CHIP_VER(priv) == VERSION_8814A)) { PRINT_INFO("Radar is detected as %x %08x (%d)!\n", radar_type, PHY_QueryBBReg(priv, 0xf98, 0xffffffff), (unsigned int)RTL_JIFFIES_TO_MILISECONDS(jiffies)); } if (timer_pending(&priv->dfs_chk_timer)) { del_timer(&priv->dfs_chk_timer); if (GET_CHIP_VER(priv) == VERSION_8192D) PHY_SetBBReg(priv, 0xcdc, BIT(8)|BIT(9), 1); PRINT_INFO("DFS CP2. Switch channel!\n"); } else { if (dfs_chk){ // reset dfs flag and counter priv->pmib->dot11DFSEntry.DFS_detected = 0; if (GET_CHIP_VER(priv) == VERSION_8192D) { PHY_SetBBReg(priv, 0xc84, BIT(25), 0); PHY_SetBBReg(priv, 0xc84, BIT(25), 1); } PRINT_INFO("DFS CP1.\n"); init_timer(&priv->dfs_chk_timer); priv->dfs_chk_timer.data = (unsigned long) priv; priv->dfs_chk_timer.function = rtl8192cd_dfs_chk_timer; mod_timer(&priv->dfs_chk_timer, jiffies + RTL_SECONDS_TO_JIFFIES(300)); goto exit_timer; } } priv->pmib->dot11DFSEntry.disable_tx = 1; if (timer_pending(&priv->ch_avail_chk_timer)) { del_timer(&priv->ch_avail_chk_timer); RTL_W8(TXPAUSE, 0xff); } else RTL_W8(TXPAUSE, 0xf); /* disable transmitter */ #if !defined(RTK_NL80211) //For OpwenWRT SDK, do not consider block channel list if(priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_80 && priv->pmib->dot11RFEntry.band5GSelected == PHY_BAND_5G_3) { int i, channel; channel = priv->pmib->dot11RFEntry.dot11channel; if ((channel >= 104) && (channel <= 112)) channel = 100; else if ((channel >= 120) && (channel <= 128)) channel = 116; else if ((channel >= 136) && (channel <= 144)) channel = 132; for(i=0;i<4;i++) { set_CHXX_timer(priv, channel+i*4); } } else { set_CHXX_timer(priv,priv->pmib->dot11RFEntry.dot11channel); } /* add the channel in the blocked-channel list */ if(priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_80 && priv->pmib->dot11RFEntry.band5GSelected == PHY_BAND_5G_3) { int i, channel; channel = priv->pmib->dot11RFEntry.dot11channel; if ((channel >= 104) && (channel <= 112)) channel = 100; else if ((channel >= 120) && (channel <= 128)) channel = 116; else if ((channel >= 136) && (channel <= 144)) channel = 132; for (i=0;i<4;i++) { if (RemoveChannel(priv, priv->available_chnl, &priv->available_chnl_num, channel+i*4)) InsertChannel(priv->NOP_chnl, &priv->NOP_chnl_num, channel+i*4); #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && (RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, channel+i*4)) ) InsertChannel(priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, channel+i*4); #endif } } else { int j; InsertChannel(priv->NOP_chnl, &priv->NOP_chnl_num, priv->pmib->dot11RFEntry.dot11channel); RemoveChannel(priv, priv->available_chnl, &priv->available_chnl_num, priv->pmib->dot11RFEntry.dot11channel); #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv))){ RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, priv->pmib->dot11RFEntry.dot11channel); InsertChannel(priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, priv->pmib->dot11RFEntry.dot11channel); } #endif } #endif if (timer_pending(&priv->DFS_timer)) del_timer(&priv->DFS_timer); #if !defined(RTK_NL80211) //For OpenWRT, do not select another channel automatically /* select a channel */ priv->pshare->dfsSwitchChannel = DFS_SelectChannel(priv); if(priv->pshare->dfsSwitchChannel == 0) { priv->pmib->dot11DFSEntry.DFS_detected = 0; if (priv->pmib->dot11RFEntry.band5GSelected == PHY_BAND_5G_3) { // when band 2 is selected, AP does not come back to band2 // even when NOP (NONE_OCCUPANCY_PERIOD) timer is expired. RTL_W8(TXPAUSE, 0xff);// after cac, still has to pause if channel is run out mod_timer(&priv->DFS_TXPAUSE_timer, jiffies + DFS_TXPAUSE_TO); } } #else //Clear disable_tx here becoz turnkey do it at DFS_SelectChannel() priv->pmib->dot11DFSEntry.disable_tx = 0; #endif #ifdef MBSSID if (priv->pmib->miscEntry.vap_enable) priv->pshare->dfsSwitchChCountDown = 6; else #endif priv->pshare->dfsSwitchChCountDown = 5; if (priv->pmib->dot11StationConfigEntry.dot11DTIMPeriod >= priv->pshare->dfsSwitchChCountDown) priv->pshare->dfsSwitchChCountDown = priv->pmib->dot11StationConfigEntry.dot11DTIMPeriod+1; #if defined(RTK_NL80211) event_indicate_cfg80211(priv, NULL, CFG80211_RADAR_DETECTED, NULL); #endif SMP_UNLOCK(flags); return; } exit_timer: mod_timer(&priv->DFS_timer, jiffies + DFS_TO); SMP_UNLOCK(flags); } #ifdef CLIENT_MODE void rtl8192cd_dfs_cntdwn_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; #ifdef SMP_SYNC unsigned long flags; #endif SMP_LOCK(flags); if (!(priv->drv_state & DRV_STATE_OPEN)) { SMP_UNLOCK(flags); return; } DEBUG_INFO("rtl8192cd_dfs_cntdwn_timer timeout!\n"); priv->pshare->dfsSwCh_ongoing = 0; SMP_UNLOCK(flags); } #endif void rtl8192cd_ch_avail_chk_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; #ifdef SMP_SYNC unsigned long flags; #endif SMP_LOCK(flags); if (!(priv->drv_state & DRV_STATE_OPEN)) { SMP_UNLOCK(flags); return; } priv->pmib->dot11DFSEntry.disable_tx = 0; if (GET_CHIP_VER(priv) == VERSION_8192D || GET_CHIP_VER(priv) == VERSION_8881A || GET_CHIP_VER(priv) == VERSION_8812E || (GET_CHIP_VER(priv) == VERSION_8814A)) { if (GET_CHIP_VER(priv) == VERSION_8881A){ PHY_SetBBReg(priv, 0xcb0, 0x000000f0, 4); } if (priv->pshare->rf_ft_var.dfsdelayiqk) PHY_IQCalibrate(priv); if (GET_CHIP_VER(priv) == VERSION_8881A){ PHY_SetBBReg(priv, 0xcb0, 0x000000f0, 5); } } #ifdef DPK_92D if (GET_CHIP_VER(priv) == VERSION_8192D){ if (priv->pshare->rf_ft_var.dfsdelayiqk && priv->pshare->rf_ft_var.dpk_on) PHY_DPCalibrate(priv); } #endif if (GET_CHIP_VER(priv) == VERSION_8192D) RTL_W16(PCIE_CTRL_REG, RTL_R16(PCIE_CTRL_REG) & (~BCNQSTOP)); else RTL_W8(TXPAUSE, 0); SMP_UNLOCK(flags); if(priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_ETSI){ if((priv->pmib->dot11RFEntry.dot11channel >= 120) && (priv->pmib->dot11RFEntry.dot11channel <= 132)){ if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c17acdf); PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c17ecdf); PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x0152a480); } PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x0fa21a20); PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0f69204); priv->ch_120_132_CAC_end = 1; } } priv->pmib->dot11DFSEntry.CAC_ss_counter = 3; panic_printk("Transmitter is enabled!\n"); #if defined(RTK_NL80211) event_indicate_cfg80211(priv, NULL, CFG80211_RADAR_CAC_FINISHED, NULL); #endif } void rtl8192cd_ch52_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; //still block channel 52 if in adhoc mode in Japan if (((priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK) || (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK3)) && (OPMODE & WIFI_ADHOC_STATE)) return; //remove the channel from NOP_chnl[4] and place it in available_chnl[32] if (RemoveChannel(priv,priv->NOP_chnl, &priv->NOP_chnl_num, 52)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 52); DEBUG_INFO("Channel 52 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 52)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 52); } #endif } void rtl8192cd_ch56_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (((priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK) || (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK3)) && (OPMODE & WIFI_ADHOC_STATE)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 56)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 56); DEBUG_INFO("Channel 56 is released!\n"); #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 56)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 56); } #endif } } void rtl8192cd_ch60_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (((priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK) || (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK3)) && (OPMODE & WIFI_ADHOC_STATE)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 60)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 60); DEBUG_INFO("Channel 60 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 60)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 60); } #endif } void rtl8192cd_ch64_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (((priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK) || (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK3)) && (OPMODE & WIFI_ADHOC_STATE)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 64)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 64); DEBUG_INFO("Channel 64 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 64)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 64); } #endif } void rtl8192cd_ch100_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 100)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 100); DEBUG_INFO("Channel 100 is released!\n"); #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 100)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 100); } #endif } } void rtl8192cd_ch104_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 104)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 104); DEBUG_INFO("Channel 104 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 104)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 104); } #endif } void rtl8192cd_ch108_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 108)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 108); DEBUG_INFO("Channel 108 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 108)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 108); } #endif } void rtl8192cd_ch112_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 112)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 112); DEBUG_INFO("Channel 112 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 112)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 112); } #endif } void rtl8192cd_ch116_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 116)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 116); DEBUG_INFO("Channel 116 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 116)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 116); } #endif } void rtl8192cd_ch120_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 120)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 120); DEBUG_INFO("Channel 120 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 120)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 120); } #endif } void rtl8192cd_ch124_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 124)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 124); DEBUG_INFO("Channel 124 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 124)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 124); } #endif } void rtl8192cd_ch128_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 128)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 128); DEBUG_INFO("Channel 128 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 128)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 128); } #endif } void rtl8192cd_ch132_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 132)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 132); DEBUG_INFO("Channel 132 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 132)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 132); } #endif } void rtl8192cd_ch136_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 136)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 136); DEBUG_INFO("Channel 136 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 136)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 136); } #endif } void rtl8192cd_ch140_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 140)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 140); DEBUG_INFO("Channel 140 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 140)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 140); } #endif } void rtl8192cd_ch144_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (RemoveChannel(priv, priv->NOP_chnl, &priv->NOP_chnl_num, 144)) { if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->available_chnl, &priv->available_chnl_num, 144); DEBUG_INFO("Channel 144 is released!\n"); } #ifdef UNIVERSAL_REPEATER if (IS_DRV_OPEN(GET_VXD_PRIV(priv)) && RemoveChannel(priv->pvxd_priv, priv->pvxd_priv->NOP_chnl, &priv->pvxd_priv->NOP_chnl_num, 144)) { if (priv->pvxd_priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) InsertChannel(priv->pvxd_priv->available_chnl, &priv->pvxd_priv->available_chnl_num, 144); } #endif } unsigned int DFS_SelectChannel(struct rtl8192cd_priv *priv) { unsigned int random; unsigned int num, random_base, which_channel = -1; int reg = priv->pmib->dot11StationConfigEntry.dot11RegDomain; if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80){ // When user select band 3 with 80M channel bandwidth which_channel = find80MChannel(priv->available_chnl,priv->available_chnl_num); if(which_channel == -1) // select non-DFS band 80M (ch 36 or 149) or down to 40/20M { #ifdef __ECOS // generate random number { unsigned int random_buf[4]; get_random_bytes(random_buf, 4); random = random_buf[3]; } #else get_random_bytes(&random, 4); #endif if(random % 2 == 0){ // try ch155 if not available choose ch36 if(is80MChannel(priv->available_chnl, priv->available_chnl_num, 149)){ which_channel = 149; } else{ if(is80MChannel(priv->available_chnl, priv->available_chnl_num, 36)){ which_channel = 36; } } } else{ if(is80MChannel(priv->available_chnl, priv->available_chnl_num, 36)){ which_channel = 36; } else{ if(is80MChannel(priv->available_chnl, priv->available_chnl_num, 149)){ which_channel = 149; } } } } } if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80 || priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40) { if(which_channel == -1){ // down to 40M priv->pmib->dot11nConfigEntry.dot11nUse40M = HT_CHANNEL_WIDTH_20_40; which_channel = find40MChannel(priv->available_chnl,priv->available_chnl_num); } } if(which_channel == -1){ // down to 20M priv->pmib->dot11nConfigEntry.dot11nUse40M = HT_CHANNEL_WIDTH_20; #ifdef __ECOS unsigned int random_buf[4]; get_random_bytes(random_buf, 4); random = random_buf[3]; #else get_random_bytes(&random, 4); #endif if(priv->available_chnl_num){ num = random % priv->available_chnl_num; which_channel = priv->available_chnl[num]; }else{ which_channel = 0; } } return which_channel; } //insert the channel into the channel list //if successful, return 1, else return 0 int InsertChannel(unsigned int chnl_list[], unsigned int *chnl_num, unsigned int channel) { unsigned int i, j; if (*chnl_num==0) { chnl_list[0] = channel; (*chnl_num)++; return SUCCESS; } for (i=0; i < *chnl_num; i++) { if (chnl_list[i] == channel) { _DEBUG_INFO("Inserting channel failed: channel %d already exists!\n", channel); return FAIL; } else if (chnl_list[i] > channel) { break; } } if (i == *chnl_num) { chnl_list[(*chnl_num)++] = channel; } else { for (j=*chnl_num; j > i; j--) chnl_list[j] = chnl_list[j-1]; chnl_list[j] = channel; (*chnl_num)++; } return SUCCESS; } /* * remove the channel from the channel list * if successful, return 1, else return 0 */ int RemoveChannel(struct rtl8192cd_priv *priv, unsigned int chnl_list[], unsigned int *chnl_num, unsigned int channel) { unsigned int i, j; if (*chnl_num) { for (i=0; i < *chnl_num; i++) if (channel == chnl_list[i]) break; if (i == *chnl_num) { _DEBUG_INFO("Can not remove channel %d!\n", channel); return FAIL; } else { for (j=i; j < (*chnl_num-1); j++) chnl_list[j] = chnl_list[j+1]; (*chnl_num)--; return SUCCESS; } } else { _DEBUG_INFO("Can not remove channel %d!\n", channel); return FAIL; } } void DFS_SwChnl_clnt(struct rtl8192cd_priv *priv) { /* signin non-DFS channel */ priv->pmib->dot11RFEntry.dot11channel = priv->pshare->dfsSwitchChannel; priv->pshare->dfsSwitchChannel = 0; RTL_W8(TXPAUSE, 0xff); panic_printk("1. Swiching channel to %d!\n", priv->pmib->dot11RFEntry.dot11channel); reload_txpwr_pg(priv); SwChnl(priv, priv->pmib->dot11RFEntry.dot11channel, priv->pshare->offset_2nd_chan); RTL_W8(TXPAUSE, 0x00); if (is_DFS_channel(priv->pmib->dot11RFEntry.dot11channel)) { panic_printk("Switched to DFS band (ch %d) again!!\n", priv->pmib->dot11RFEntry.dot11channel); } #ifdef CONFIG_RTL_92D_SUPPORT if ((GET_CHIP_VER(priv) == VERSION_8192D) && (priv->pmib->dot11Bss.channel > 14)) { priv->pshare->iqk_5g_done = 0; PHY_IQCalibrate(priv); } #endif } void DFS_SwitchChannel(struct rtl8192cd_priv *priv) { int ch = priv->pshare->dfsSwitchChannel; if (!(priv->drv_state & DRV_STATE_OPEN)) return; priv->pmib->dot11RFEntry.dot11channel = ch; priv->pshare->dfsSwitchChannel = 0; RTL_W8(TXPAUSE, 0xff); DEBUG_INFO("2. Swiching channel to %d!\n", priv->pmib->dot11RFEntry.dot11channel); priv->pshare->CurrentChannelBW = priv->pshare->is_40m_bw = priv->pmib->dot11nConfigEntry.dot11nUse40M; if( (ch>144) ? ((ch-1)%8) : (ch%8)) { GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE; priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE; } else { GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW; priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW; } //priv->pshare->No_RF_Write = 0; SwBWMode(priv, priv->pshare->CurrentChannelBW, priv->pshare->offset_2nd_chan); SwChnl(priv, priv->pmib->dot11RFEntry.dot11channel, priv->pshare->offset_2nd_chan); PHY_IQCalibrate(priv); //FOR_8812_IQK //priv->pshare->No_RF_Write = 1; GET_ROOT(priv)->pmib->dot11DFSEntry.DFS_detected = priv->pshare->dfsSwitchChannel = 0; GET_ROOT(priv)->pmib->dot11DFSEntry.disable_tx = priv->pmib->dot11DFSEntry.disable_tx = 0; priv->ht_cap_len = 0; update_beacon(priv); RTL_W8(TXPAUSE, 0x00); } void rtl8192cd_dfs_det_chk_timer(unsigned long task_priv) { struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv; unsigned long throughput = 0; int j; if (!(priv->drv_state & DRV_STATE_OPEN)) return; priv->ini_gain_cur = RTL_R8(0xc50); priv->st_L2H_cur = PHY_QueryBBReg(priv, 0x91c, 0x000000ff); throughput = priv->ext_stats.tx_avarage+priv->ext_stats.rx_avarage; #ifdef MBSSID if (priv->pmib->miscEntry.vap_enable) { for (j=0; jpvap_priv[j])) { throughput += priv->pvap_priv[j]->ext_stats.tx_avarage+priv->pvap_priv[j]->ext_stats.rx_avarage; } } } #endif if ((throughput >> 17) <= priv->pshare->rf_ft_var.dfs_psd_tp_th) { priv->idle_flag = 1; if(priv->pshare->rf_ft_var.dfs_force_TP_mode) priv->idle_flag = 0; } else{ priv->idle_flag = 0; } #if !defined(CONFIG_RTL_92D_SUPPORT) // dfs_det.c if((GET_CHIP_VER(priv) == VERSION_8812E) || (GET_CHIP_VER(priv) == VERSION_8881A) || (GET_CHIP_VER(priv) == VERSION_8814A)) { if (priv->pshare->rf_ft_var.dfs_det_off == 0) { #if defined(CONFIG_WLAN_HAL_8814AE) if(GET_CHIP_VER(priv) == VERSION_8814A){ if(priv->pshare->rf_ft_var.dfs_radar_diff_on){ rtl8192cd_radar_type_differentiation(priv); } } #endif rtl8192cd_dfs_det_chk(priv); rtl8192cd_dfs_dynamic_setting(priv); } } #endif // dynamic pwdb calibration if (priv->ini_gain_pre != priv->ini_gain_cur) { priv->pwdb_th = ((int)priv->st_L2H_cur - (int)priv->ini_gain_cur)/2 + priv->pshare->rf_ft_var.dfs_pwdb_scalar_factor; priv->pwdb_th = MAX_NUM(priv->pwdb_th, (int)priv->pshare->rf_ft_var.dfs_pwdb_th); // limit the pwdb value to absoulte lower bound 0xa priv->pwdb_th = MIN_NUM(priv->pwdb_th, 0x1f); // limit the pwdb value to absoulte upper bound 0x1f PHY_SetBBReg(priv, 0x918, 0x00001f00, priv->pwdb_th); } priv->ini_gain_pre = priv->ini_gain_cur; if(((priv->pmib->dot11RFEntry.dot11channel >= 52) && (priv->pmib->dot11RFEntry.dot11channel <= 64)) && (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK)){ mod_timer(&priv->dfs_det_chk_timer, jiffies + RTL_MILISECONDS_TO_JIFFIES(priv->pshare->rf_ft_var.dfs_det_period_jp_w53*10)); } else{ mod_timer(&priv->dfs_det_chk_timer, jiffies + RTL_MILISECONDS_TO_JIFFIES(priv->pshare->rf_ft_var.dfs_det_period*10)); } } void DFS_SetReg(struct rtl8192cd_priv *priv) { if (!(priv->drv_state & DRV_STATE_OPEN)) return; if (GET_CHIP_VER(priv) == VERSION_8192D) { PHY_SetBBReg(priv, 0xc38, BIT(23) | BIT(22), 2); PHY_SetBBReg(priv, 0x814, bMaskDWord, 0x04cc4d10); } else if ((GET_CHIP_VER(priv) == VERSION_8812E) || (GET_CHIP_VER(priv) == VERSION_8881A) || (GET_CHIP_VER(priv) == VERSION_8814A)) { PHY_SetBBReg(priv, 0x814, 0x3fffffff, 0x04cc4d10); PHY_SetBBReg(priv, 0x834, bMaskByte0, 0x06); if (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_FCC) { if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20){ PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x64741a20); } else{ PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x68741a20); } if(priv->pshare->rf_ft_var.dfs_det_off == 1){ if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c166cdf); PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c16acdf); PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x0152a480); } PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0d67231); } else{ if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c176cdf); PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c17acdf); PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x0152a480); } PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0d6d231); } } else if (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_ETSI) { if(priv->pshare->rf_ft_var.dfs_det_off == 1){ if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c16acdf); PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c16ecdf); PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x0152a400); } PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x0fa21a20); PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0f57204); } else{ if((priv->pmib->dot11RFEntry.dot11channel >= 120) && (priv->pmib->dot11RFEntry.dot11channel <= 132)){ if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80 || priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20){ if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c16acdf); PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c16ecdf); PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x0152a400); } PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x0fa21a20); PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0f87204); } else{ if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c16acdf); PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c16ecdf); PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x01528480); } PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x0fa21a20); PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0f77204); } priv->ch_120_132_CAC_end = 0; } else{ if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c17acdf); PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c17ecdf); PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x0152a480); } PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x0fa21a20); PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0f79204); } } } else if(priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK){ if(priv->pshare->rf_ft_var.dfs_det_off == 1){ if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x0152a480); } PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0d67234); if((priv->pmib->dot11RFEntry.dot11channel >= 52) && (priv->pmib->dot11RFEntry.dot11channel <= 64)){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c16ecdf); PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x0f141a20); } else{ if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20){ PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x64721a20); } else{ PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x68721a20); } if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c166cdf); } else{ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c16acdf); } } } else{ if((priv->pmib->dot11RFEntry.dot11channel >= 52) && (priv->pmib->dot11RFEntry.dot11channel <= 64)){ PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0fe7234); PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x0f141a20); PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c17ecdf); if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x0152a480); } } else{ PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0d67234); if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c176cdf); PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c17acdf); PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x01528480); } if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20){ PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x64721a20); } else{ PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x68721a20); } } } } else{ // default: FCC if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20){ PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x64741a20); } else{ PHY_SetBBReg(priv, 0x91c, bMaskDWord, 0x68741a20); } if(priv->pshare->rf_ft_var.dfs_det_off == 1){ if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c166cdf); PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c16acdf); PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x0152a480); } PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0d67231); } else{ if (GET_CHIP_VER(priv) == VERSION_8814A){ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c176cdf); PHY_SetBBReg(priv, 0x924, 0xfffffff, 0x095aa480); } else{ PHY_SetBBReg(priv, 0x918, bMaskDWord, 0x1c17acdf); PHY_SetBBReg(priv, 0x924, bMaskDWord, 0x0152a480); } PHY_SetBBReg(priv, 0x920, bMaskDWord, 0xe0d6d231); } } priv->st_L2H_cur = PHY_QueryBBReg(priv, 0x91c, 0x000000ff); priv->pwdb_th = (int)PHY_QueryBBReg(priv, 0x918, 0x00001f00); priv->peak_th = PHY_QueryBBReg(priv, 0x918, 0x00030000); priv->short_pulse_cnt_th = PHY_QueryBBReg(priv, 0x920, 0x000f0000); priv->long_pulse_cnt_th = PHY_QueryBBReg(priv, 0x920, 0x00f00000); priv->peak_window = PHY_QueryBBReg(priv, 0x920, 0x00000300); priv->nb2wb_th = PHY_QueryBBReg(priv, 0x920, 0x0000e000); //panic_printk("peak_th: %d\n", priv->peak_th); if (GET_CHIP_VER(priv) == VERSION_8881A) PHY_SetBBReg(priv, 0xb00, 0xc0000000, 3); if (GET_CHIP_VER(priv) == VERSION_8814A){ // for 8814 new dfs mechanism setting PHY_SetBBReg(priv, 0x19e4, 0x1fff, 0x1600); // DFS backoff factor=0.375 PHY_SetBBReg(priv, 0x19e4, 0x30000, 1); //NonDC peak_th = 2times DC peak_th PHY_SetBBReg(priv, 0x9f8, 0xc0000000, 3); // power for debug and auto test flow latch after ST PHY_SetBBReg(priv, 0x9f4, 0x80000000, 1); // enable peak index should the same during the same short pulse (new mechanism) PHY_SetBBReg(priv, 0x924, 0x20000000, 0); // disable peak index should the same during the same short pulse (old mechanism) PHY_SetBBReg(priv, 0x19e4, 0xe000, 2); // if peak index diff >=2, then drop the result if (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK) { if((priv->pmib->dot11RFEntry.dot11channel >= 52) && (priv->pmib->dot11RFEntry.dot11channel <= 64)){ // pulse width hist th setting PHY_SetBBReg(priv, 0x19e4, 0xff000000, 2); // th1=2*04us PHY_SetBBReg(priv, 0x19e8, bMaskDWord, 0xff080604); // set th2 = 4*0.4us, th3 = 6*0.4us, th4 = 8*0.4, th5 to max // pulse repetition interval hist th setting PHY_SetBBReg(priv, 0x19b8, 0x00007f80, 86); // th1=86*32us PHY_SetBBReg(priv, 0x19ec, bMaskDWord, 0xffffffff); // set th2, th3, th4, th5 to max } else{ // pulse width hist th setting PHY_SetBBReg(priv, 0x19e4, 0xff000000, 2); // th1=2*04us PHY_SetBBReg(priv, 0x19e8, bMaskDWord, 0x1a0e0604); // set th2 = 4*0.4us, th3 = 6*0.4us, th4 = 14*0.4us, th5 = 26*0.4us // pulse repetition interval hist th setting PHY_SetBBReg(priv, 0x19b8, 0x00007f80, 27); // th1=27*32us PHY_SetBBReg(priv, 0x19ec, bMaskDWord, 0xffffffff); // set th2, th3, th4, th5 to max } } else if(priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_ETSI){ // pulse width hist th setting PHY_SetBBReg(priv, 0x19e4, 0xff000000, 9); // th1=9*04us PHY_SetBBReg(priv, 0x19e8, bMaskDWord, 0xffff2c19); // // set th2 = 25*0.4us, th3 = 44*0.4us, th4, th5 = max // pulse repetition interval hist th setting //PHY_SetBBReg(priv, 0x19b8, 0x00007f80, 86); // th1=86*32us //PHY_SetBBReg(priv, 0x19ec, bMaskDWord, 0xffffffff); // set th2, th3, th4, th5 to max } else if(priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_FCC){ // pulse width hist th setting PHY_SetBBReg(priv, 0x19e4, 0xff000000, 2); // th1=2*04us PHY_SetBBReg(priv, 0x19e8, bMaskDWord, 0x331a0e03); // // set th2 = 3*0.4us, th3 = 14*0.4us, th4 = 26*0.4us, th5 = 51*0.4us // pulse repetition interval hist th setting //PHY_SetBBReg(priv, 0x19b8, 0x00007f80, 86); // th1=86*32us //PHY_SetBBReg(priv, 0x19ec, bMaskDWord, 0xffffffff); // set th2, th3, th4, th5 to max } else{ } } RTL_W8(TXPAUSE, 0xff); } if (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_ETSI) { if (GET_CHIP_VER(priv) == VERSION_8192D) { PHY_SetBBReg(priv, 0xc8c, BIT(23) | BIT(22), 3); PHY_SetBBReg(priv, 0xc30, 0xf, 0xa); PHY_SetBBReg(priv, 0xcdc, 0xf0000, 4); } } else { if (GET_CHIP_VER(priv) == VERSION_8192D) { PHY_SetBBReg(priv, 0xc8c, BIT(23) | BIT(22), 0); PHY_SetBBReg(priv, 0xcd8, 0xffff, 0x1a1f); } } /* * Enable h/w DFS detect */ if (GET_CHIP_VER(priv) == VERSION_8192D) { PHY_SetBBReg(priv, 0xc84, BIT(25), 1); if (!priv->pshare->rf_ft_var.dfsdbgmode){ PHY_SetBBReg(priv, 0xc7c, BIT(28), 1); // ynlin dbg } } } unsigned char *get_DFS_version(void) { return DFS_VERSION; } #endif