M7350/wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/8192cd_dfs.c
2024-09-09 08:59:52 +00:00

1381 lines
48 KiB
C
Executable File

/*
* 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; j<RTL8192CD_NUM_VWLAN; j++) {
if (IS_DRV_OPEN(priv->pvap_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; j<RTL8192CD_NUM_VWLAN; j++) {
if (IS_DRV_OPEN(priv->pvap_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