📄 dfs.c
字号:
/* ************************************************************************* * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, Taiwan, R.O.C. * * (c) Copyright 2002-2007, Ralink Technology, Inc. * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * ************************************************************************* Module Name: ap_dfs.c Abstract: Support DFS function. Revision History: Who When What -------- ---------- ---------------------------------------------- Fonchi 03-12-2007 created*/#include "rt_config.h"typedef struct _RADAR_DURATION_TABLE{ ULONG RDDurRegion; ULONG RadarSignalDuration; ULONG Tolerance;} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;static BOOLEAN RadarSignalDetermination( IN PRTMP_ADAPTER pAd, IN BOOLEAN RadarType, IN UINT32 RadarSignalDuration);static RADAR_DURATION_TABLE RadarSignalDurationTable[]={//Pattern num, Session interval, Theorical duration, Tolerance // CE. {CE, 0x682A, 0x10}, {CE, 0x186A0, 0x100}, {CE, 0x1046A, 0x100}, {CE, 0x9C40, 0x10}, {CE, 0x61A8, 0x10}, {CE, 0x4E20, 0x10}, {CE, 0x411A, 0x10}, {CE, 0x3415, 0x10}, {CE, 0x30D4, 0x10}, {CE, 0x21F7, 0x10}, {CE, 0x1A0A, 0x10}, {CE, 0x1652, 0x10}, {CE, 0x1388, 0x10}, {CE, 0x2710, 0x10}, //FCC {FCC, 0x6F90, 0x100}, {FCC, ((0x11F8+0xBB8)/2), ((0x11F8-0xBB8)/2)}, {FCC, ((0x2710+0xFA0)/2), ((0x2710-0xFA0)/2)}, {FCC, 0x1a04, 0x100}, //Japan {JAP, 0x6F9B, 0x10}, {JAP, 0x12C7B, 0x100}, {JAP, 0x6C81, 0x10}, {JAP, 0x6F9B, 0x100}, {JAP, 0x13880, 0x100}, {JAP, ((0x11F8+0xBB7)/2), ((0x11F8-0xBB7)/2)}, {JAP, ((0x2710+0xFA0)/2), ((0x2710-0xFA0)/2)}, {JAP, 0x12C7B, 0x100}, //Japan w53 {JAP_W53, 0x6F9B, 0x10}, {JAP_W53, 0x12C7B, 0x100}, //Japan w56 {JAP_W56, 0x6C81, 0x10}, {JAP_W56, 0x6F9B, 0x100}, {JAP_W56, 0x13880, 0x100}, {JAP_W56, ((0x11F8+0xBB7)/2), ((0x11F8-0xBB7)/2)}, {JAP_W56, ((0x2710+0xFA0)/2), ((0x2710-0xFA0)/2)}, {JAP_W56, 0x12C7B, 0x100},};#define RD_TAB_SIZE (sizeof(RadarSignalDurationTable) / sizeof(RADAR_DURATION_TABLE))static RADAR_DURATION_TABLE RadarWidthSignalDurationTable[]={ //Pattern num, Session interval, Theorical duration, Tolerance //FCC {FCC, ((0x7D0+0x3E8)/2), ((0x7D0-0x3E8)/2)}, {JAP, ((0x7D0+0x3E8)/2), ((0x7D0-0x3E8)/2)}, {JAP_W56, ((0x7D0+0x3E8)/2), ((0x7D0-0x3E8)/2)},};#define RD_WIDTH_TAB_SIZE (sizeof(RadarWidthSignalDurationTable) / sizeof(RADAR_DURATION_TABLE))/* ======================================================================== Routine Description: Bbp Radar detection routine Arguments: pAd Pointer to our adapter Return Value: ========================================================================*/VOID BbpRadarDetectionStart( IN PRTMP_ADAPTER pAd){ BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02); BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20); BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00); BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x80); BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28); BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff); BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R65, 0x0d); BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x50); BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R113, 0x21); return;}/* ======================================================================== Routine Description: Bbp Radar detection routine Arguments: pAd Pointer to our adapter Return Value: ========================================================================*/VOID BbpRadarDetectionStop( IN PRTMP_ADAPTER pAd){ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R65, 0x2c); BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x38); BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R113, 0x01); return;}/* ======================================================================== Routine Description: Radar detection routine Arguments: pAd Pointer to our adapter Return Value: ========================================================================*/VOID RadarDetectionStart( IN PRTMP_ADAPTER pAd, IN BOOLEAN CTSProtect, IN UINT8 CTSPeriod){ UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f); UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect. if (CTSProtect != 0) { switch(pAd->CommonCfg.RadarDetect.RDDurRegion) { case FCC: case JAP_W56: CtsProtect = 0x03; break; case CE: case JAP_W53: default: CtsProtect = 0x02; break; } } else CtsProtect = 0x01; DBGPRINT(RT_DEBUG_INFO,("RadarDetectionStart %s CTS protection, duration %dms, period=%dms\n", (CTSProtect == 1 ? "with" : "without"), DfsActiveTime, CTSPeriod)); // send start-RD with CTS protection command to MCU // highbyte [7] reserve // highbyte [6:5] 0x: stop Carrier/Radar detection // highbyte [10]: Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection // highbyte [4:0] Radar/carrier detection duration. In 1ms. // lowbyte [7:0] Radar/carrier detection period, in 1ms. AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5)); //AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0); return;}/* ======================================================================== Routine Description: Radar detection routine Arguments: pAd Pointer to our adapter Return Value: TRUE Found radar signal FALSE Not found radar signal ========================================================================*/VOID RadarDetectionStop( IN PRTMP_ADAPTER pAd){ DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n")); AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00); // send start-RD with CTS protection command to MCU return;}/* ======================================================================== 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; UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}; for (i=0; i<15; i++) { if (Ch == Channel[i]) { break; } } if (i != 15) return TRUE; else return FALSE;}ULONG RTMPBbpReadRadarDuration( IN PRTMP_ADAPTER pAd){ UINT8 byteValue = 0; ULONG result; BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue); result = 0; switch (byteValue) { case 1: // radar signal detected by pulse mode. case 2: // radar signal detected by width mode. result = RTMPReadRadarDuration(pAd); break; case 0: // No radar signal. default: result = 0; break; } return result;}ULONG RTMPReadRadarDuration( IN PRTMP_ADAPTER pAd){ ULONG result = 0;#ifdef DFS_SUPPORT UINT8 duration1 = 0, duration2 = 0, duration3 = 0; BBP_IO_READ8_BY_REG_ID(pAd, BBP_R116, &duration1); BBP_IO_READ8_BY_REG_ID(pAd, BBP_R117, &duration2); BBP_IO_READ8_BY_REG_ID(pAd, BBP_R118, &duration3); result = (duration1 << 16) + (duration2 << 8) + duration3;#endif // DFS_SUPPORT // return result;}VOID RTMPCleanRadarDuration( IN PRTMP_ADAPTER pAd){ return;}/* ======================================================================== Routine Description: Radar wave detection. The API should be invoke each second. Arguments: pAd - Adapter pointer Return Value: None ========================================================================*/VOID ApRadarDetectPeriodic( IN PRTMP_ADAPTER pAd){ INT i; pAd->CommonCfg.RadarDetect.InServiceMonitorCount++; for (i=0; i<pAd->ChannelListNum; i++) { if (pAd->ChannelList[i].RemainingTimeForUse > 0) { pAd->ChannelList[i].RemainingTimeForUse --; if ((pAd->Mlme.PeriodicRound%5) == 0) { DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse)); } } } //radar detect if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) { RadarDetectPeriodic(pAd); } return;}// Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()// Before switch channel, driver needs doing channel switch announcement.VOID RadarDetectPeriodic( IN PRTMP_ADAPTER pAd){ UINT32 RadarSignalDuration; // need to check channel availability, after switch channel // channel availability check time is 60sec, use 65 for assurance if ((pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE) && (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)) { do { UINT8 byteValue = 0;#ifdef DFS_SUPPORT BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue); BbpRadarDetectionStop(pAd);#endif // DFS_SUPPORT // if (!byteValue) break; RadarSignalDuration = RTMPReadRadarDuration(pAd); if (RadarSignalDetermination(pAd, (byteValue == 1 ? 1 : 2), RadarSignalDuration)) {#ifdef CONFIG_STA_SUPPORT pAd->ExtraInfo = DETECT_RADAR_SIGNAL; pAd->CommonCfg.RadarDetect.RDCount = 0; // stat at silence mode and detect radar signal#endif // CONFIG_STA_SUPPORT // DBGPRINT(RT_DEBUG_TRACE, ("Found radar signal(duration =%x), will switch to ch%d !!!\n\n\n", RadarSignalDuration, pAd->CommonCfg.Channel)); } else { DBGPRINT(RT_DEBUG_INFO, ("Mis-trigger radar detection(duration =%x) !!!\n", RadarSignalDuration)); break; } return; } while(FALSE); DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n")); AsicEnableBssSync(pAd); pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE; } return;}/* ========================================================================== 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 PUCHAR arg){ UINT8 Value; Value = simple_strtol(arg, 0, 10); pAd->CommonCfg.RadarDetect.ChMovingTime = Value; DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__, pAd->CommonCfg.RadarDetect.ChMovingTime)); return TRUE;}#define RADAR_ELECT_NUMBER 3static BOOLEAN RadarSignalDetermination( IN PRTMP_ADAPTER pAd, IN BOOLEAN RadarType, IN UINT32 RadarSignalDuration){ INT index; ULONG RadarTabSize = RD_TAB_SIZE; PRADAR_DURATION_TABLE pRadarSignalTab = RadarSignalDurationTable; BOOLEAN result = FALSE; static ULONG WidthRadarSamples[RADAR_ELECT_NUMBER] = {0}; static ULONG WidthRadarSamplesIdx = 0; if (!RadarSignalDuration) return FALSE; if (RadarType == RADAR_WIDTH) { RadarTabSize = RD_WIDTH_TAB_SIZE; pRadarSignalTab = RadarWidthSignalDurationTable; } else { RadarTabSize = RD_TAB_SIZE; pRadarSignalTab = RadarSignalDurationTable; } for (index=0; index < RadarTabSize; index++) { PRADAR_DURATION_TABLE pRadarEntry = pRadarSignalTab + index; if ((pRadarEntry->RDDurRegion == pAd->CommonCfg.RadarDetect.RDDurRegion) && (RadarSignalDuration > (pRadarEntry->RadarSignalDuration - pRadarEntry->Tolerance)) && (RadarSignalDuration < (pRadarEntry->RadarSignalDuration + pRadarEntry->Tolerance)) ) break; } if (index < RadarTabSize) result = TRUE; else result = FALSE; if ((RadarType == RADAR_WIDTH) && (result == TRUE)) { ULONG CurRecodTime; ULONG PreRecodTime = WidthRadarSamples[(WidthRadarSamplesIdx + 1) % RADAR_ELECT_NUMBER]; NdisGetSystemUpTime(&CurRecodTime); WidthRadarSamples[WidthRadarSamplesIdx % RADAR_ELECT_NUMBER] = CurRecodTime; if ((PreRecodTime != 0) && ((CurRecodTime - PreRecodTime) < (6 * OS_HZ)) ) result = TRUE; else result = FALSE; WidthRadarSamplesIdx ++; } return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -