Files
Linux_Drivers/osdrv/extdrv/wireless/mediatek/mt7603/common/cmm_radar.c
forum_service 213c880673 add driver of tp、wiegand-gpio and wireless
Change-Id: Ie3c11d9d85cf1a05042f5690ac711856fe8b1ad7
2023-12-22 09:56:05 +08:00

534 lines
14 KiB
C

/*
***************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
*
* (c) Copyright 2002, Ralink Technology, Inc.
*
* All rights reserved. Ralink's source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of Ralink Tech. Any attemp
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of Ralink Technology, Inc. is obtained.
***************************************************************************
Module Name:
cmm_radar.c
Abstract:
CS/DFS common functions.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#include "rt_config.h"
/*----- 802.11H -----*/
/* Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()*/
/* Before switch channel, driver needs doing channel switch announcement.*/
VOID RadarDetectPeriodic(
IN PRTMP_ADAPTER pAd)
{
INT i, ChIdx = 0, bAnyUnavailableChannel = FALSE;
/*
1. APStart(), CalBufTime = 0;
2. if bAnyUnavailableChannel, CalBufTime = DEFAULT_CAL_BUF_TIME;
3. if Calibrated, CalBufTime = DEFAULT_CAL_BUF_TIME_MAX;
*/
#if 0
/* need to check channel availability, after switch channel*/
if (pAd->Dot11_H.RDMode != RD_SILENCE_MODE)
return;
#endif
for (i=0; i<pAd->ChannelListNum; i++)
{
if (pAd->ChannelList[i].RemainingTimeForUse != 0)
{
bAnyUnavailableChannel = TRUE;
}
if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
{
ChIdx = i;
}
}
if (bAnyUnavailableChannel)
pAd->Dot11_H.CalBufTime = DEFAULT_CAL_BUF_TIME;
if (pAd->Dot11_H.RDMode == RD_SILENCE_MODE)
{
/* In Silent Mode, RDCount is use to check with the CAC Time */
if (pAd->Dot11_H.RDCount++ > pAd->Dot11_H.ChMovingTime &&
pAd->ChannelList[ChIdx].RemainingTimeForUse == 0)
{
DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
pAd->Dot11_H.RDMode = RD_NORMAL_MODE;
AsicEnableBssSync(pAd, pAd->CommonCfg.BeaconPeriod);
pAd->Dot11_H.RDCount = 0;
}
}
else if (pAd->Dot11_H.RDMode == RD_NORMAL_MODE)
{
if (!bAnyUnavailableChannel)
{
pAd->Dot11_H.RDCount++;
/* In Normal Mode, RDCount is use to check with the CalBufTime */
if ((pAd->Dot11_H.RDCount >= pAd->Dot11_H.CalBufTime))
{
#ifdef MT76x0
mt76x0_calibration(pAd, pAd->hw_cfg.cent_ch, FALSE, TRUE, TRUE);
#endif /* MT76x0 */
pAd->Dot11_H.CalBufTime = DEFAULT_CAL_BUF_TIME_MAX;
}
}
}
}
/*
========================================================================
Routine Description:
Radar channel check routine
Arguments:
pAd Pointer to our adapter
Return Value:
TRUE need to do radar detect
FALSE need not to do radar detect
========================================================================
*/
BOOLEAN RadarChannelCheck(
IN PRTMP_ADAPTER pAd,
IN UCHAR Ch)
{
INT i;
BOOLEAN result = FALSE;
for (i=0; i<pAd->ChannelListNum; i++)
{
if (Ch == pAd->ChannelList[i].Channel)
{
result = pAd->ChannelList[i].DfsReq;
break;
}
}
return result;
}
/*
========================================================================
Routine Description:
Determine the current radar state
Arguments:
pAd Pointer to our adapter
Return Value:
========================================================================
*/
VOID RadarStateCheck(
IN PRTMP_ADAPTER pAd)
{
pAd->Dot11_H.CalBufTime = 0;
if ((pAd->CommonCfg.Channel > 14) &&
(pAd->CommonCfg.bIEEE80211H == 1) &&
RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
{
pAd->Dot11_H.RDMode = RD_SILENCE_MODE;
pAd->Dot11_H.RDCount = 0;
pAd->Dot11_H.InServiceMonitorCount = 0;
}
else
pAd->Dot11_H.RDMode = RD_NORMAL_MODE;
#ifdef CARRIER_DETECTION_SUPPORT
if ((pAd->CommonCfg.RDDurRegion == JAP)
|| (pAd->CommonCfg.RDDurRegion == JAP_W53)
|| (pAd->CommonCfg.RDDurRegion == JAP_W56))
{
if ((pAd->CommonCfg.Channel > 14) ||
(pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40))
{
pAd->CommonCfg.CarrierDetect.Enable = TRUE;
}
}
#endif /* CARRIER_DETECTION_SUPPORT */
}
ULONG JapRadarType(
IN PRTMP_ADAPTER pAd)
{
ULONG i;
const UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
if (pAd->CommonCfg.RDDurRegion != JAP)
{
return pAd->CommonCfg.RDDurRegion;
}
for (i=0; i<15; i++)
{
if (pAd->CommonCfg.Channel == Channel[i])
{
break;
}
}
if (i < 4)
return JAP_W53;
else if (i < 15)
return JAP_W56;
else
return JAP; /* W52*/
}
UCHAR get_channel_by_reference(
IN PRTMP_ADAPTER pAd,
IN UINT8 mode)
{
UCHAR ch = 0;
INT ch_idx;
switch (mode)
{
case 1:
{
USHORT min_time = 0xFFFF;
/* select channel with least RemainingTimeForUse */
for ( ch_idx = 0; ch_idx < pAd->ChannelListNum; ch_idx++)
{
if (pAd->ChannelList[ch_idx].RemainingTimeForUse < min_time)
{
min_time = pAd->ChannelList[ch_idx].RemainingTimeForUse;
ch = pAd->ChannelList[ch_idx].Channel;
}
}
break;
}
default:
{
ch = FirstChannel(pAd);
break;
}
}
DBGPRINT(RT_DEBUG_TRACE,("%s(): mode = %u, ch = %u\n",
__FUNCTION__, mode, ch));
return ch;
}
#ifdef CONFIG_AP_SUPPORT
/*
========================================================================
Routine Description:
Channel switching count down process upon radar detection
Arguments:
pAd Pointer to our adapter
========================================================================
*/
VOID ChannelSwitchingCountDownProc(
IN PRTMP_ADAPTER pAd)
{
DBGPRINT(RT_DEBUG_TRACE, ("%s():Channel Switching...(%d/%d)\n",
__FUNCTION__, pAd->Dot11_H.CSCount, pAd->Dot11_H.CSPeriod));
pAd->Dot11_H.CSCount++;
if (pAd->Dot11_H.CSCount >= pAd->Dot11_H.CSPeriod)
{
#ifdef DFS_SUPPORT
pAd->CommonCfg.RadarDetect.DFSAPRestart = 1;
schedule_dfs_task(pAd);
#else
APStop(pAd);
APStartUp(pAd);
#endif /* !DFS_SUPPORT */
}
}
#endif /* CONFIG_AP_SUPPORT */
/*
==========================================================================
Description:
Set channel switch Period
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_CSPeriod_Proc(
IN PRTMP_ADAPTER pAd,
IN RTMP_STRING *arg)
{
pAd->Dot11_H.CSPeriod = (USHORT) simple_strtol(arg, 0, 10);
DBGPRINT(RT_DEBUG_TRACE, ("Set_CSPeriod_Proc::(CSPeriod=%d)\n", pAd->Dot11_H.CSPeriod));
return TRUE;
}
/*
==========================================================================
Description:
change channel moving time for DFS testing.
Arguments:
pAdapter Pointer to our adapter
wrq Pointer to the ioctl argument
Return Value:
None
Note:
Usage:
1.) iwpriv ra0 set ChMovTime=[value]
==========================================================================
*/
INT Set_ChMovingTime_Proc(
IN PRTMP_ADAPTER pAd,
IN RTMP_STRING *arg)
{
USHORT Value;
Value = (USHORT) simple_strtol(arg, 0, 10);
pAd->Dot11_H.ChMovingTime = Value;
DBGPRINT(RT_DEBUG_TRACE, ("%s: %d\n", __FUNCTION__,
pAd->Dot11_H.ChMovingTime));
return TRUE;
}
/*
==========================================================================
Description:
Reset channel block status.
Arguments:
pAd Pointer to our adapter
arg Not used
Return Value:
None
Note:
Usage:
1.) iwpriv ra0 set ChMovTime=[value]
==========================================================================
*/
INT Set_BlockChReset_Proc(
IN PRTMP_ADAPTER pAd,
IN RTMP_STRING *arg)
{
INT i;
DBGPRINT(RT_DEBUG_TRACE, ("%s: Reset channel block status.\n", __FUNCTION__));
for (i=0; i<pAd->ChannelListNum; i++)
pAd->ChannelList[i].RemainingTimeForUse = 0;
return TRUE;
}
#if defined(DFS_SUPPORT) || defined(CARRIER_DETECTION_SUPPORT)
INT Set_RadarShow_Proc(
IN PRTMP_ADAPTER pAd,
IN RTMP_STRING *arg)
{
#ifdef DFS_SUPPORT
UINT8 idx;
PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
PDFS_PROGRAM_PARAM pDfsProgramParam = &pRadarDetect->DfsProgramParam;
PDFS_SW_DETECT_PARAM pDfsSwParam = &pRadarDetect->DfsSwParam;
PCHAR RDMode[]= {"Normal State", "Switching State", "Silent State"};
printk("DFSUseTasklet = %d\n", pRadarDetect->use_tasklet);
printk("McuRadarDebug = %x\n", (unsigned int)pRadarDetect->McuRadarDebug);
printk("PollTime = %d\n", pRadarDetect->PollTime);
printk("ChEnable = %d (0x%x)\n", pDfsProgramParam->ChEnable, pDfsProgramParam->ChEnable);
printk("DeltaDelay = %d\n", pDfsProgramParam->DeltaDelay);
printk("PeriodErr = %d\n", pDfsSwParam->dfs_period_err);
printk("MaxPeriod = %d\n", (unsigned int)pDfsSwParam->dfs_max_period);
printk("Ch0LErr = %d\n", pDfsSwParam->dfs_width_ch0_err_L);
printk("Ch0HErr = %d\n", pDfsSwParam->dfs_width_ch0_err_H);
printk("Ch1Shift = %d\n", pDfsSwParam->dfs_width_diff_ch1_Shift);
printk("Ch2Shift = %d\n", pDfsSwParam->dfs_width_diff_ch2_Shift);
printk("DfsRssiHigh = %d\n", pRadarDetect->DfsRssiHigh);
printk("DfsRssiLow = %d\n", pRadarDetect->DfsRssiLow);
printk("DfsSwDisable = %u\n", pRadarDetect->bDfsSwDisable);
printk("CheckLoop = %d\n", pDfsSwParam->dfs_check_loop);
printk("DeclareThres = %d\n", pDfsSwParam->dfs_declare_thres);
for (idx=0; idx < pAd->chipCap.DfsEngineNum; idx++)
printk("sw_idx[%u] = %u\n", idx, pDfsSwParam->sw_idx[idx]);
for (idx=0; idx < pAd->chipCap.DfsEngineNum; idx++)
printk("hw_idx[%u] = %u\n", idx, pDfsSwParam->hw_idx[idx]);
printk("pAd->Dot11_H.ChMovingTime = %d\n", pAd->Dot11_H.ChMovingTime);
printk("pAd->Dot11_H.RDMode = %s\n", RDMode[pAd->Dot11_H.RDMode]);
printk("pAd->Dot11_H.RDCount = %d\n", pAd->Dot11_H.RDCount);
printk("pAd->Dot11_H.CalBufTime = %d\n", pAd->Dot11_H.CalBufTime);
#endif /* DFS_SUPPORT */
#ifdef CARRIER_DETECTION_SUPPORT
printk("pAd->CommonCfg.CarrierDetect.CD_State = %d\n", pAd->CommonCfg.CarrierDetect.CD_State);
printk("pAd->CommonCfg.CarrierDetect.criteria = %d\n", pAd->CommonCfg.CarrierDetect.criteria);
printk("pAd->CommonCfg.CarrierDetect.Delta = %d\n", pAd->CommonCfg.CarrierDetect.delta);
printk("pAd->CommonCfg.CarrierDetect.DivFlag = %d\n", pAd->CommonCfg.CarrierDetect.div_flag);
printk("pAd->CommonCfg.CarrierDetect.Threshold = %d(0x%x)\n", pAd->CommonCfg.CarrierDetect.threshold, pAd->CommonCfg.CarrierDetect.threshold);
#endif /* CARRIER_DETECTION_SUPPORT */
return TRUE;
}
/*
========================================================================
Routine Description:
Control CCK_MRC Status
Arguments:
pAd Pointer to our adapter
Return Value:
========================================================================
*/
VOID CckMrcStatusCtrl(IN PRTMP_ADAPTER pAd)
{
#ifdef RT5592
UCHAR bbp = 0, bCckMrc = 0;
#ifdef RELEASE_EXCLUDE
/*
This function control CCK_MRC status according to the following table:
Due to the H/W issue, when CS/DFS is turned ON, the
CCK_MRC should be keep OFF except in 2.4G with 40BW.
This function can be removed after the H/W issue fixed.
| | G band | A band |
| BW |20 |40 | 20 |40 |
|CS enabled | X O X X |
|CS disabled | O O X X |
*/
#endif /* RELEASE_EXCLUDE */
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R95, &bbp);
bCckMrc = (bbp >> 7);
if (bCckMrc)
{
if (pAd->CommonCfg.Channel>14
#ifdef CARRIER_DETECTION_SUPPORT
|| (pAd->CommonCfg.CarrierDetect.Enable == TRUE &&
pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_20)
#endif /* CARRIER_DETECTION_SUPPORT */
)
{
/* Disable CCK_MRC*/
bbp &= ~(1 << 7);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R95, bbp);
}
}
else
{
if (pAd->CommonCfg.Channel<=14)
{
#ifdef CARRIER_DETECTION_SUPPORT
if (pAd->CommonCfg.CarrierDetect.Enable == FALSE ||
pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)
#endif /* CARRIER_DETECTION_SUPPORT */
{
/* Enable CCK_MRC */
bbp |= (1 << 7);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R95, bbp);
}
}
}
#endif /* RT5592 */
}
/*
========================================================================
Routine Description:
Enhance DFS/CS when using GLRT.
Arguments:
pAd Pointer to our adapter
Return Value:
========================================================================
*/
VOID RadarGLRTCompensate(IN PRTMP_ADAPTER pAd)
{
#ifdef RT5592
#ifdef RELEASE_EXCLUDE
/*
Moderate GLRT effect on CS/DFS.
This is a H/W issue, CS/DFS radar will cause large false CCA at some frequency points when using GLRT.
This will block DFS/CS signels.
If CS/DFS is enabled, GLRT should be programmed as bellow.
*/
#endif /* RELEASE_EXCLUDE */
if (pAd->CommonCfg.bIEEE80211H == 1
#ifdef CARRIER_DETECTION_SUPPORT
|| pAd->CommonCfg.CarrierDetect.Enable == TRUE
#endif /* CARRIER_DETECTION_SUPPORT */
)
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R195, 0x91);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R196, 0x24);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R195, 0x95);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R196, 0x2D);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R195, 0x99);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R196, 0x40);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R195, 0x9A);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R196, 0x3E);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R195, 0x9B);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R196, 0x42);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R195, 0x9C);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R196, 0x3D);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R195, 0x9D);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R196, 0x40);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R195, 0xA1);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R196, 0x2F);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R195, 0xA5);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R196, 0x2A);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R195, 0xB5);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R196, 0x40);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R195, 0xCE);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R196, 0x43);
}
#endif /* RT5592 */
}
#endif /*defined(DFS_SUPPORT) || defined(CARRIER_DETECTION_SUPPORT) */