454 lines
10 KiB
C
454 lines
10 KiB
C
/*
|
|
*************************************************************************
|
|
* Ralink Tech Inc.
|
|
* 5F., No.36, Taiyuan St., Jhubei City,
|
|
* Hsinchu County 302,
|
|
* 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 UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
|
|
{
|
|
{9, 250, 250, 250}, // CE
|
|
{4, 250, 250, 250}, // FCC
|
|
{4, 250, 250, 250}, // JAP
|
|
{15, 250, 250, 250}, // JAP_W53
|
|
{4, 250, 250, 250} // JAP_W56
|
|
};
|
|
|
|
/*
|
|
========================================================================
|
|
|
|
Routine Description:
|
|
Bbp Radar detection routine
|
|
|
|
Arguments:
|
|
pAd Pointer to our adapter
|
|
|
|
Return Value:
|
|
|
|
========================================================================
|
|
*/
|
|
VOID BbpRadarDetectionStart(
|
|
IN PRTMP_ADAPTER pAd)
|
|
{
|
|
UINT8 RadarPeriod;
|
|
|
|
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
|
|
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
|
|
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
|
|
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
|
|
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
|
|
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
|
|
|
|
#if 0
|
|
// toggle Rx enable bit for radar detection.
|
|
// it's Andy's recommand.
|
|
{
|
|
UINT32 Value;
|
|
RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
|
|
Value |= (0x1 << 3);
|
|
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
|
|
Value &= ~(0x1 << 3);
|
|
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
|
|
}
|
|
#endif
|
|
RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
|
|
(RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
|
|
|
|
RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
|
|
RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
|
|
|
|
RadarDetectionStart(pAd, 0, RadarPeriod);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
========================================================================
|
|
|
|
Routine Description:
|
|
Bbp Radar detection routine
|
|
|
|
Arguments:
|
|
pAd Pointer to our adapter
|
|
|
|
Return Value:
|
|
|
|
========================================================================
|
|
*/
|
|
VOID BbpRadarDetectionStop(
|
|
IN PRTMP_ADAPTER pAd)
|
|
{
|
|
RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
|
|
RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
|
|
|
|
RadarDetectionStop(pAd);
|
|
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;
|
|
|
|
|
|
// 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)
|
|
{
|
|
#if 1
|
|
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;
|
|
#else
|
|
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;
|
|
#endif
|
|
}
|
|
|
|
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.RadarDetect.RDDurRegion != JAP)
|
|
{
|
|
return pAd->CommonCfg.RadarDetect.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
|
|
|
|
}
|
|
|
|
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)
|
|
{
|
|
// need to check channel availability, after switch channel
|
|
if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
|
|
return;
|
|
|
|
// channel availability check time is 60sec, use 65 for assurance
|
|
if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
|
|
BbpRadarDetectionStop(pAd);
|
|
AsicEnableBssSync(pAd);
|
|
pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
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", __func__,
|
|
pAd->CommonCfg.RadarDetect.ChMovingTime));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
INT Set_LongPulseRadarTh_Proc(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN PUCHAR arg)
|
|
{
|
|
UINT8 Value;
|
|
|
|
Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
|
|
|
|
pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __func__,
|
|
pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|