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

841 lines
22 KiB
C

/*
***************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
*
* (c) Copyright 2002-2006, 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.
***************************************************************************/
/****************************************************************************
Abstract:
***************************************************************************/
#ifdef DOT11K_RRM_SUPPORT
#include "rt_config.h"
/*
static CHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
*/
#if 0
static VOID RRM_BcnReortQuery(
IN PRTMP_ADAPTER pAd,
IN INT ApIdx,
IN PRRM_CONFIG pRrmCfg);
#endif
static VOID RRM_QuietOffsetTimeout(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);
static VOID RRM_QuietTimeout(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);
DECLARE_TIMER_FUNCTION(RRM_QuietOffsetTimeout);
DECLARE_TIMER_FUNCTION(RRM_QuietTimeout);
BUILD_TIMER_FUNCTION(RRM_QuietOffsetTimeout);
BUILD_TIMER_FUNCTION(RRM_QuietTimeout);
#if 0
static VOID RRM_BcnReortQuery(
IN PRTMP_ADAPTER pAd,
IN INT ApIdx,
IN PRRM_CONFIG pRrmCfg)
{
INT idx;
for (idx = pRrmCfg->QuietCB.CurAid; idx < (pAd->MacTab.Size+1); idx++)
{
PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[idx];
if (IS_RRM_CAPABLE(pEntry)
&& IS_RRM_BEACON_MEASURE(pEntry))
{
RRM_MLME_BCN_REQ_INFO BcnReq;
NdisZeroMemory(&BcnReq, sizeof(RRM_MLME_BCN_REQ_INFO));
COPY_MAC_ADDR(BcnReq.Bssid, BROADCAST_ADDR);
BcnReq.pSsid = (PUCHAR)pAd->ApCfg.MBSSID[ApIdx].Ssid;
BcnReq.SsidLen = pAd->ApCfg.MBSSID[ApIdx].SsidLen;
BcnReq.RegulatoryClass = pAd->CommonCfg.RegulatoryClass[0];
BcnReq.MeasureCh = pRrmCfg->QuietCB.MeasureCh;
BcnReq.MeasureMode = RRM_BCN_REQ_MODE_BCNTAB;
BcnReq.BcnReqCapFlag.field.ReportCondition = TRUE;
BcnReq.MeasureDuration = cpu2le16(pRrmCfg->QuietCB.QuietDuration);
if (BcnReq.MeasureCh == 255)
BcnReq.BcnReqCapFlag.field.ChannelRep = TRUE;
else
BcnReq.BcnReqCapFlag.field.ChannelRep = FALSE;
RRM_EnqueueBcnReq(pAd, pEntry->Aid, pEntry->func_tb_idx, &BcnReq);
pRrmCfg->QuietCB.CurAid = idx + 1;
break;
}
}
if (idx == (pAd->MacTab.Size + 1))
{
pRrmCfg->QuietCB.CurAid = 1;
pRrmCfg->QuietCB.MeasureCh =
(pRrmCfg->QuietCB.MeasureCh == 255) ? pAd->CommonCfg.Channel : 255;
}
}
#endif
static VOID RRM_QuietOffsetTimeout(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3)
{
INT idx;
PRRM_CONFIG pRrmCfg = NULL;
RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) SystemSpecific3;
for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++)
{
pRrmCfg = &pAd->ApCfg.MBSSID[idx].RrmCfg;
if (&pRrmCfg->QuietCB.QuietOffsetTimer == pTimer)
break;
}
/* start Quiet . */
if (idx == pAd->ApCfg.BssidNum)
return;
pRrmCfg = &pAd->ApCfg.MBSSID[idx].RrmCfg;
pRrmCfg->QuietCB.QuietState = RRM_QUIET_SILENT;
RTMPSetTimer(&pRrmCfg->QuietCB.QuietTimer,
pRrmCfg->QuietCB.QuietDuration);
return;
}
static VOID RRM_QuietTimeout(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3)
{
INT idx;
PRRM_CONFIG pRrmCfg = NULL;
RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) SystemSpecific3;
for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++)
{
pRrmCfg = &pAd->ApCfg.MBSSID[idx].RrmCfg;
if (&pRrmCfg->QuietCB.QuietTimer == pTimer)
break;
}
/* stop Quiet . */
if (idx == pAd->ApCfg.BssidNum)
return;
pRrmCfg = &pAd->ApCfg.MBSSID[idx].RrmCfg;
pRrmCfg->QuietCB.QuietState = RRM_QUIET_IDLE;
return;
}
void RRM_ReadParametersFromFile(
IN PRTMP_ADAPTER pAd,
RTMP_STRING *tmpbuf,
RTMP_STRING *buffer)
{
INT loop;
RTMP_STRING *macptr;
/* RRMEnable */
if (RTMPGetKeyParameter("RRMEnable", tmpbuf, 255, buffer, TRUE))
{
for (loop=0, macptr = rstrtok(tmpbuf,";");
(macptr && loop < MAX_MBSSID_NUM(pAd));
macptr = rstrtok(NULL,";"), loop++)
{
LONG Enable;
Enable = simple_strtol(macptr, 0, 10);
pAd->ApCfg.MBSSID[loop].RrmCfg.bDot11kRRMEnable =
(Enable > 0) ? TRUE : FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("%s::(bDot11kRRMEnable[%d]=%d)\n",
__FUNCTION__, loop,
pAd->ApCfg.MBSSID[loop].RrmCfg.bDot11kRRMEnable));
}
}
else
{
for (loop = 0; loop < MAX_MBSSID_NUM(pAd); loop++)
pAd->ApCfg.MBSSID[loop].RrmCfg.bDot11kRRMEnable = FALSE;
}
/* Regulatory Class */
if (RTMPGetKeyParameter("RegulatoryClass", tmpbuf, 255, buffer, TRUE))
{
LONG Value;
for (loop=0, macptr = rstrtok(tmpbuf,";");
(macptr && loop < MAX_NUM_OF_REGULATORY_CLASS);
macptr = rstrtok(NULL,";"), loop++)
{
Value = simple_strtol(macptr, 0, 10);
pAd->CommonCfg.RegulatoryClass[loop] = Value;
}
}
return;
}
INT Set_Dot11kRRM_Enable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
UCHAR ifIndex = pObj->ioctl_if;
ULONG Value;
if (ifIndex >= pAd->ApCfg.BssidNum)
{
DBGPRINT(RT_DEBUG_OFF, ("Unknow If index (%d)", ifIndex));
return -1;
}
Value = (UINT) simple_strtol(arg, 0, 10);
pAd->ApCfg.MBSSID[ifIndex].RrmCfg.bDot11kRRMEnable =
(BOOLEAN)(Value) == 0 ? FALSE : TRUE;
return 1;
}
INT Set_BeaconReq_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
INT Loop;
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
UCHAR ifIndex = pObj->ioctl_if;
UINT Aid = 1;
UINT ArgIdx;
RTMP_STRING *thisChar;
RRM_MLME_BCN_REQ_INFO BcnReq;
ArgIdx = 0;
NdisZeroMemory(&BcnReq, sizeof(RRM_MLME_BCN_REQ_INFO));
while ((thisChar = strsep((char **)&arg, "-")) != NULL)
{
switch(ArgIdx)
{
case 0: /* Aid. */
Aid = (UINT8) simple_strtol(thisChar, 0, 16);
if (!VALID_WCID(Aid))
{
DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
return TRUE;
}
break;
case 1: /* Meausre Duration. */
BcnReq.MeasureDuration = (UINT8) simple_strtol(thisChar, 0, 10);
case 2: /* Regulator Class */
BcnReq.RegulatoryClass = (UINT8) simple_strtol(thisChar, 0, 10);
break;
case 3: /* BSSID */
if(strlen(thisChar) != 17)
{
DBGPRINT(RT_DEBUG_ERROR,
("%s: invalid value BSSID.\n", __FUNCTION__));
return TRUE;
}
if(strlen(thisChar) == 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */
{
RTMP_STRING *value;
for (Loop=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":"))
{
if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
return FALSE; /*Invalid */
AtoH(value, &BcnReq.Bssid[Loop++], 1);
}
if(Loop != 6)
return TRUE;
}
break;
case 4: /* SSID */
BcnReq.pSsid = (PUINT8)thisChar;
BcnReq.SsidLen = strlen(thisChar);
break;
case 5: /* measure channel */
BcnReq.MeasureCh = (UINT8) simple_strtol(thisChar, 0, 10);
break;
case 6: /* measure mode. */
BcnReq.MeasureMode = (UINT8) simple_strtol(thisChar, 0, 10);
if (BcnReq.MeasureMode > RRM_BCN_REQ_MODE_BCNTAB)
{
DBGPRINT(RT_DEBUG_ERROR,
("%s: invalid Measure Mode. %d\n", __FUNCTION__, BcnReq.MeasureMode));
return TRUE;
}
case 7: /* regulatory class. */
{
RTMP_STRING *RegClassString;
int RegClassIdx;
RegClassIdx = 0;
while ((RegClassString = strsep((char **)&thisChar, "+")) != NULL)
{
BcnReq.ChRepRegulatoryClass[RegClassIdx] =
(UINT8) simple_strtol(RegClassString, 0, 10);
RegClassIdx++;
}
}
break;
}
ArgIdx++;
}
if (ArgIdx < 7 || ArgIdx > 8)
{
DBGPRINT(RT_DEBUG_ERROR,
("%s: invalid args (%d).\n", __FUNCTION__, ArgIdx));
DBGPRINT(RT_DEBUG_ERROR,
("eg: iwpriv ra0 set BcnReq=<Aid>-<Duration>-<RegulatoryClass>-<BSSID>-<SSID>-<MeasureCh>-<MeasureMode>-<ChRegClass>\n"));
return TRUE;
}
#ifdef RELEASE_EXCLUDE
DBGPRINT(RT_DEBUG_ERROR, ("%s::Aid = %d\n", __FUNCTION__, Aid));
DBGPRINT(RT_DEBUG_ERROR, ("%s::Bssid = %02x:%02x:%02x:%02x:%02x:%02x\n",
__FUNCTION__, BcnReq.Bssid[0], BcnReq.Bssid[1],
BcnReq.Bssid[2], BcnReq.Bssid[3],
BcnReq.Bssid[4], BcnReq.Bssid[5]));
DBGPRINT(RT_DEBUG_ERROR, ("%s::SsidLen = %d\n", __FUNCTION__,
BcnReq.SsidLen));
DBGPRINT(RT_DEBUG_ERROR, ("%s::MeasureCh = %d\n", __FUNCTION__,
BcnReq.MeasureCh));
DBGPRINT(RT_DEBUG_ERROR, ("%s::RegulatoryDuration=%d\n", __FUNCTION__, BcnReq.MeasureDuration));
DBGPRINT(RT_DEBUG_ERROR, ("%s::MeasureMode=%d\n", __FUNCTION__, BcnReq.MeasureMode));
DBGPRINT(RT_DEBUG_ERROR, ("RegulatoryClass="));
for (ArgIdx=0; ArgIdx<MAX_NUM_OF_REGULATORY_CLASS; ArgIdx++)
{
if (BcnReq.ChRepRegulatoryClass[ArgIdx] == 0)
break;
DBGPRINT(RT_DEBUG_ERROR, ("%d ", \
BcnReq.ChRepRegulatoryClass[ArgIdx]));
}
DBGPRINT(RT_DEBUG_ERROR, ("\n"));
#endif /* RELEASE_EXCLUDE */
BcnReq.BcnReqCapFlag.field.ReportCondition = TRUE;
if (BcnReq.MeasureCh == 255)
BcnReq.BcnReqCapFlag.field.ChannelRep = TRUE;
else
BcnReq.BcnReqCapFlag.field.ChannelRep = FALSE;
RRM_EnqueueBcnReq(pAd, Aid, ifIndex, &BcnReq);
return TRUE;
}
INT Set_LinkMeasureReq_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
UCHAR ifIndex = pObj->ioctl_if;
UINT Aid = 1;
Aid = simple_strtol(arg, 0, 10);
RRM_EnqueueLinkMeasureReq(pAd, Aid, ifIndex);
return TRUE;
}
INT Set_TxStreamMeasureReq_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
UCHAR ifIndex = pObj->ioctl_if;
UINT Aid = 1;
UINT ArgIdx;
RTMP_STRING *thisChar;
RRM_MLME_TRANSMIT_REQ_INFO TransmitReq;
PMAC_TABLE_ENTRY pMacEntry;
ArgIdx = 0;
NdisZeroMemory(&TransmitReq, sizeof(RRM_MLME_TRANSMIT_REQ_INFO));
while ((thisChar = strsep((char **)&arg, "-")) != NULL)
{
switch(ArgIdx)
{
case 0: /* Aid. */
Aid = (UINT8) simple_strtol(thisChar, 0, 10);
if (!VALID_WCID(Aid))
{
DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
return TRUE;
}
break;
case 1: /* DurationMandotory. */
TransmitReq.bDurationMandatory =
((UINT16)simple_strtol(thisChar, 0, 10) > 0 ? TRUE : FALSE);
break;
case 2: /* Measure Duration */
TransmitReq.MeasureDuration = (UINT16)simple_strtol(thisChar, 0, 10);
break;
case 3: /* TID */
TransmitReq.Tid = (UINT8) simple_strtol(thisChar, 0, 10);
break;
case 4: /* Bin 0 Range */
TransmitReq.BinRange = (UINT8) simple_strtol(thisChar, 0, 10);
break;
case 5: /* Averange Condition */
TransmitReq.ArvCondition =
((UINT8) simple_strtol(thisChar, 0, 10)) > 0 ? 1 : 0;
break;
case 6: /* Consecutive Condition */
TransmitReq.ConsecutiveCondition =
((UINT8) simple_strtol(thisChar, 0, 10)) > 0 ? 1 : 0;
break;
case 7: /* Delay Condition */
TransmitReq.DelayCondition =
((UINT8) simple_strtol(thisChar, 0, 10)) > 0 ? 1 : 0;
break;
case 8: /* Averange Error Threshold */
TransmitReq.AvrErrorThreshold =
(UINT8) simple_strtol(thisChar, 0, 10);
break;
case 9: /* Consecutive Error Threshold */
TransmitReq.ConsecutiveErrorThreshold =
(UINT8) simple_strtol(thisChar, 0, 10);
break;
case 10: /* Delay Threshold */
TransmitReq.DelayThreshold =
(UINT8) simple_strtol(thisChar, 0, 10);
break;
case 11: /* Measure counter */
TransmitReq.MeasureCnt =
(UINT8) simple_strtol(thisChar, 0, 10);
break;
case 12: /* Trigger time out */
TransmitReq.TriggerTimeout =
(UINT8) simple_strtol(thisChar, 0, 10);
break;
}
ArgIdx++;
}
if ((ArgIdx != 13) && (ArgIdx != 5))
{
DBGPRINT(RT_DEBUG_ERROR,
("%s: invalid args (%d).\n", __FUNCTION__, ArgIdx));
DBGPRINT(RT_DEBUG_ERROR,
("eg: iwpriv ra0 set txreq=<Aid>-<DurationMandortory>-<Duration>-<TID>-<BinRange>[-<AvrCond>-<ConsecutiveCond>-<DealyCond>-<AvrErrorThreshold>-<ConsecutiveErrorThreshold>-<DelayThreshold>-<MeasureCnt>-<TriggerTimeout>]\n"));
return TRUE;
}
if (ArgIdx == 5)
TransmitReq.bTriggerReport = 0;
else
TransmitReq.bTriggerReport = 1;
pMacEntry = &pAd->MacTab.Content[Aid];
DBGPRINT(RT_DEBUG_ERROR, ("%s::Aid=%d, PeerMac=%02x:%02x:%02x:%02x:%02x:%02x\n",
__FUNCTION__, Aid, pMacEntry->Addr[0], pMacEntry->Addr[1],
pMacEntry->Addr[2], pMacEntry->Addr[3], pMacEntry->Addr[4], pMacEntry->Addr[5]));
DBGPRINT(RT_DEBUG_ERROR, ("Duration=%d, Tid=%d, Bin 0 Range=%d\n",
TransmitReq.MeasureDuration, TransmitReq.Tid, TransmitReq.BinRange));
DBGPRINT(RT_DEBUG_ERROR, ("ArvCondition=%d, ConsecutiveCondition=%d, DelayCondition=%d\n",
TransmitReq.ArvCondition, TransmitReq.ConsecutiveCondition, TransmitReq.DelayCondition));
DBGPRINT(RT_DEBUG_ERROR, ("AvrErrorThreshold=%d, ConsecutiveErrorThreshold=%d\n",
TransmitReq.AvrErrorThreshold, TransmitReq.ConsecutiveErrorThreshold));
DBGPRINT(RT_DEBUG_ERROR, ("DelayThreshold=%d\n", TransmitReq.DelayThreshold));
DBGPRINT(RT_DEBUG_ERROR, ("MeasureCnt=%d, TriggerTimeout=%d\n",
TransmitReq.MeasureCnt, TransmitReq.TriggerTimeout));
RRM_EnqueueTxStreamMeasureReq(pAd, Aid, ifIndex, &TransmitReq);
return TRUE;
}
INT Set_RRM_Selftest_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
UINT Cmd = 1;
PMAC_TABLE_ENTRY pEntry;
UCHAR StaAddr[MAC_ADDR_LEN] = {0x00,0x0c,0x43,0x00,0x00,0x00};
Cmd = simple_strtol(arg, 0, 10);
switch(Cmd)
{
case 1: /* insert a STA for RRM Beacon Report request testing. */
pEntry = MacTableInsertEntry(pAd, StaAddr, wdev, ENTRY_CLIENT, OPMODE_AP, TRUE);
pEntry->Sst = SST_ASSOC;
pEntry->CapabilityInfo |= RRM_CAP_BIT;
pEntry->RrmEnCap.field.BeaconActiveMeasureCap = 1;
break;
}
return TRUE;
}
INT RRM_InfoDisplay_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
INT loop;
for (loop = 0; loop < pAd->ApCfg.BssidNum; loop++)
{
DBGPRINT(RT_DEBUG_OFF, ("%d: bDot11kRRMEnable=%d\n",
loop, pAd->ApCfg.MBSSID[loop].RrmCfg.bDot11kRRMEnable));
}
DBGPRINT(RT_DEBUG_OFF, ("Country Code=%s\n",
pAd->CommonCfg.CountryCode));
DBGPRINT(RT_DEBUG_OFF, ("Power Constraint=%d\n",
pAd->CommonCfg.PwrConstraint));
DBGPRINT(RT_DEBUG_OFF, ("Regulator Class="));
for (loop = 0; loop < MAX_NUM_OF_REGULATORY_CLASS; loop++)
{
if (pAd->CommonCfg.RegulatoryClass[loop] == 0)
break;
DBGPRINT(RT_DEBUG_OFF, ("%d ",
pAd->CommonCfg.RegulatoryClass[loop]));
}
DBGPRINT(RT_DEBUG_OFF, ("\n"));
DBGPRINT(RT_DEBUG_OFF, ("Regulator TxPowerPercentage=%ld\n",
pAd->CommonCfg.TxPowerPercentage));
return TRUE;
}
VOID RRM_CfgInit(
IN PRTMP_ADAPTER pAd)
{
INT loop;
PRRM_CONFIG pRrmCfg;
for (loop = 0; loop < MAX_MBSSID_NUM(pAd); loop++)
{
pRrmCfg = &pAd->ApCfg.MBSSID[loop].RrmCfg;
pRrmCfg->QuietCB.QuietPeriod = RRM_DEFAULT_QUIET_PERIOD;
pRrmCfg->QuietCB.QuietDuration = RRM_DEFAULT_QUIET_DURATION;
pRrmCfg->QuietCB.QuietOffset = RRM_DEFAULT_QUIET_OFFSET;
RTMPInitTimer(pAd, &pRrmCfg->QuietCB.QuietOffsetTimer, GET_TIMER_FUNCTION(RRM_QuietOffsetTimeout), pAd, FALSE);
RTMPInitTimer(pAd, &pRrmCfg->QuietCB.QuietTimer, GET_TIMER_FUNCTION(RRM_QuietTimeout), pAd, FALSE);
pRrmCfg->QuietCB.QuietState = RRM_QUIET_IDLE;
pRrmCfg->QuietCB.CurAid = 1;
pRrmCfg->bDot11kRRMEnable = TRUE;
pRrmCfg->bDot11kRRMNeighborRepTSFEnable = FALSE;
}
return;
}
VOID RRM_QuietUpdata(
IN PRTMP_ADAPTER pAd)
{
INT loop;
PRRM_CONFIG pRrmCfg;
for (loop = 0; loop < pAd->ApCfg.BssidNum; loop++)
{
if (pAd->ApCfg.MBSSID[loop].MSSIDDev == NULL)
continue;
if (!(pAd->ApCfg.MBSSID[loop].MSSIDDev->flags & IFF_UP))
continue;
pRrmCfg = &pAd->ApCfg.MBSSID[loop].RrmCfg;
if (pRrmCfg->bDot11kRRMEnable != TRUE)
continue;
if (pRrmCfg->QuietCB.QuietCnt == pRrmCfg->QuietCB.QuietPeriod)
{
/* issue Bcn Report Request to STAs supported RRM-Bcn Report. */
/* Voice-enterpise doesn't require it in testing-event3 so remove it. */
/*RRM_BcnReortQuery(pAd, loop, pRrmCfg); */
}
if ((pRrmCfg->QuietCB.QuietCnt == 0)
&& (pRrmCfg->QuietCB.QuietState == RRM_QUIET_IDLE))
{
if (pRrmCfg->QuietCB.QuietOffset != 0)
{
/* Start QuietOffsetTimer. */
RTMPSetTimer(&pRrmCfg->QuietCB.QuietOffsetTimer,
pRrmCfg->QuietCB.QuietOffset);
}
else
{
/* Start Quiet Timer. */
pRrmCfg->QuietCB.QuietState = RRM_QUIET_SILENT;
RTMPSetTimer(&pRrmCfg->QuietCB.QuietTimer,
pRrmCfg->QuietCB.QuietDuration);
}
}
RRM_QUIET_CNT_DEC(pRrmCfg->QuietCB.QuietCnt, pRrmCfg->QuietCB.QuietPeriod);
}
return;
}
VOID RRM_PeerNeighborReqAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
PUCHAR pFramePtr = pFr->Octet;
PMAC_TABLE_ENTRY pEntry;
UINT8 DialogToken;
PCHAR pSsid = NULL;
UINT8 SsidLen = 0;
DBGPRINT(RT_DEBUG_TRACE, ("%s::\n", __FUNCTION__));
/* skip Category and action code. */
pFramePtr += 2;
pEntry = MacTableLookup(pAd, pFr->Hdr.Addr2);
if (!pEntry || (pEntry->Sst != SST_ASSOC))
return;
if (RRM_PeerNeighborReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &pSsid, &SsidLen))
{
DBGPRINT(RT_DEBUG_TRACE, ("DialogToken=%x\n", DialogToken));
DBGPRINT(RT_DEBUG_TRACE, ("pSsid=%s\n", pSsid));
DBGPRINT(RT_DEBUG_TRACE, ("SsidLen=%d\n", SsidLen));
RRM_EnqueueNeighborRep(pAd, pEntry, DialogToken, pSsid, SsidLen);
}
return;
}
VOID RRM_BeaconReportHandler(
IN PRTMP_ADAPTER pAd,
IN PRRM_BEACON_REP_INFO pBcnRepInfo,
IN LONG Length)
{
CHAR Rssi;
USHORT LenVIE = 0;
NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
UCHAR VarIE[MAX_VIE_LEN];
ULONG Idx = BSS_NOT_FOUND;
LONG RemainLen = Length;
PRRM_BEACON_REP_INFO pBcnRep;
PUINT8 ptr;
RRM_BEACON_REP_INFO_FIELD BcnReqInfoField;
UINT32 Ptsf;
BCN_IE_LIST *ie_list = NULL;
os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST));
if (ie_list == NULL) {
DBGPRINT(RT_DEBUG_ERROR, ("%s(): Alloc ie_list failed!\n", __FUNCTION__));
return;
}
NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST));
ptr = (PUINT8)pBcnRepInfo;
pBcnRep = (PRRM_BEACON_REP_INFO)ptr;
Ptsf = le2cpu32(pBcnRep->ParentTSF);
BcnReqInfoField.word = pBcnRep->RepFrameInfo;
DBGPRINT(RT_DEBUG_TRACE, ("%s:: ReqClass=%d, Channel=%d\n",
__FUNCTION__, pBcnRep->RegulatoryClass, pBcnRep->ChNumber));
DBGPRINT(RT_DEBUG_TRACE, ("Bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
PRINT_MAC(pBcnRep->Bssid)));
Rssi = pBcnRep->RCPI + pAd->BbpRssiToDbmDelta;
RemainLen -= sizeof(RRM_BEACON_REP_INFO);
ptr += sizeof(RRM_BEACON_REP_INFO);
/* check option sub element IE. */
while (RemainLen > 0)
{
PRRM_SUBFRAME_INFO pRrmSubFrame;
pRrmSubFrame = (PRRM_SUBFRAME_INFO)ptr;
switch(pRrmSubFrame->SubId)
{
case 1:
if (BcnReqInfoField.field.ReportFrameType == 0)
{
/* Init Variable IE structure */
pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
pVIE->Length = 0;
PeerBeaconAndProbeRspSanity(pAd,
pRrmSubFrame->Oct,
pRrmSubFrame->Length,
pBcnRep->ChNumber,
ie_list,
&LenVIE,
pVIE,
FALSE);
}
break;
case 221:
DBGPRINT(RT_DEBUG_TRACE, ("%s:: SubIe: ID=%x, Len=%d\n",
__FUNCTION__, pRrmSubFrame->SubId, pRrmSubFrame->Length));
break;
}
RemainLen -= (pRrmSubFrame->Length + 2);
ptr += (pRrmSubFrame->Length + 2);
/* avoid infinite loop. */
if (pRrmSubFrame->Length == 0)
break;
}
if (NdisEqualMemory(pBcnRep->Bssid, ie_list->Bssid, MAC_ADDR_LEN) == FALSE)
{
DBGPRINT(RT_DEBUG_WARN, ("%s():BcnReq->BSSID not equal ie_list->Bssid!\n", __FUNCTION__));
}
#ifdef AP_SCAN_SUPPORT
Idx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, Rssi, LenVIE, pVIE);
if (Idx != BSS_NOT_FOUND)
{
BSS_ENTRY *pBssEntry = &pAd->ScanTab.BssEntry[Idx];
NdisMoveMemory(pBssEntry->PTSF, (PUCHAR)&Ptsf, 4);
pBssEntry->RegulatoryClass = pBcnRep->RegulatoryClass;
pBssEntry->CondensedPhyType = BcnReqInfoField.field.CondensePhyType;
pBssEntry->RSNI = pBcnRep->RSNI;
}
#endif /* AP_SCAN_SUPPORT */
return;
}
VOID RRM_PeerMeasureRepAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
PUCHAR pFramePtr = pFr->Octet;
ULONG MsgLen = Elem->MsgLen;
PMEASURE_REQ_ENTRY pDialogEntry;
PMAC_TABLE_ENTRY pEntry;
UINT8 DialogToken;
DBGPRINT(RT_DEBUG_TRACE, ("%s::\n", __FUNCTION__));
/* skip Category and action code. */
pFramePtr += 2;
MsgLen -= 2;
/* get DialogToken. */
NdisMoveMemory(&DialogToken, pFramePtr, 1);
pFramePtr += 1;
MsgLen -= 1;
/*
Not a autonomous measure report (non zero DialogToken).
check the dialog token field.
drop it if the dialog token doesn't match.
*/
pDialogEntry = NULL;
if ((DialogToken != 0)
&& ((pDialogEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL))
return;
if (pDialogEntry != NULL)
MeasureReqDelete(pAd, pDialogEntry->DialogToken);
do
{
PEID_STRUCT eid_ptr;
MEASURE_REPORT_MODE ReportMode;
UINT8 ReportType;
PRRM_BEACON_REP_INFO pMeasureRep;
/* Is the STA associated. Dorp the Measure report if it's not. */
pEntry = MacTableLookup(pAd, pFr->Hdr.Addr2);
if (!pEntry || (pEntry->Sst != SST_ASSOC))
break;
eid_ptr = (PEID_STRUCT)pFramePtr;
while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
{
switch(eid_ptr->Eid)
{
case IE_MEASUREMENT_REPORT:
{
LONG BcnRepLen = (LONG)eid_ptr->Len - 3;
NdisMoveMemory(&ReportMode, eid_ptr->Octet + 1, 1);
NdisMoveMemory(&ReportType, eid_ptr->Octet + 2, 1);
pMeasureRep = (PVOID)(eid_ptr->Octet + 3);
if (ReportType == RRM_MEASURE_SUBTYPE_BEACON)
RRM_BeaconReportHandler(pAd, pMeasureRep,
BcnRepLen);
}
break;
default:
break;
}
eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
}
} while(FALSE);
return;
}
#endif /* DOT11K_RRM_SUPPORT */