761 lines
20 KiB
C
761 lines
20 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:
|
|
mlme.c
|
|
|
|
Abstract:
|
|
Major MLME state machiones here
|
|
|
|
Revision History:
|
|
Who When What
|
|
-------- ---------- ----------------------------------------------
|
|
John Chang 08-04-2003 created for 11g soft-AP
|
|
*/
|
|
|
|
#include "rt_config.h"
|
|
#include <stdarg.h>
|
|
|
|
#ifdef BTCOEX_CONCURRENT
|
|
extern void MT7662ReceCoexFromOtherCHip(
|
|
IN UCHAR channel,
|
|
IN UCHAR centralchannel,
|
|
IN UCHAR channel_bw
|
|
);
|
|
#endif
|
|
|
|
#ifdef DOT11_N_SUPPORT
|
|
|
|
int DetectOverlappingPeriodicRound;
|
|
|
|
|
|
#ifdef DOT11N_DRAFT3
|
|
VOID Bss2040CoexistTimeOut(
|
|
IN PVOID SystemSpecific1,
|
|
IN PVOID FunctionContext,
|
|
IN PVOID SystemSpecific2,
|
|
IN PVOID SystemSpecific3)
|
|
{
|
|
int apidx;
|
|
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("Bss2040CoexistTimeOut(): Recovery to original setting!\n"));
|
|
|
|
/* Recovery to original setting when next DTIM Interval. */
|
|
pAd->CommonCfg.Bss2040CoexistFlag &= (~BSS_2040_COEXIST_TIMER_FIRED);
|
|
NdisZeroMemory(&pAd->CommonCfg.LastBSSCoexist2040, sizeof(BSS_2040_COEXIST_IE));
|
|
pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_INFO_SYNC;
|
|
|
|
if (pAd->CommonCfg.bBssCoexEnable == FALSE)
|
|
{
|
|
/* TODO: Find a better way to handle this when the timer is fired and we disable the bBssCoexEable support!! */
|
|
DBGPRINT(RT_DEBUG_TRACE, ("Bss2040CoexistTimeOut(): bBssCoexEnable is FALSE, return directly!\n"));
|
|
return;
|
|
}
|
|
|
|
for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
|
|
SendBSS2040CoexistMgmtAction(pAd, MCAST_WCID, apidx, 0);
|
|
|
|
}
|
|
#endif /* DOT11N_DRAFT3 */
|
|
|
|
#endif /* DOT11_N_SUPPORT */
|
|
|
|
|
|
VOID APDetectOverlappingExec(
|
|
IN PVOID SystemSpecific1,
|
|
IN PVOID FunctionContext,
|
|
IN PVOID SystemSpecific2,
|
|
IN PVOID SystemSpecific3)
|
|
{
|
|
#ifdef DOT11_N_SUPPORT
|
|
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
|
|
|
|
if (DetectOverlappingPeriodicRound == 0)
|
|
{
|
|
/* switch back 20/40 */
|
|
if ((pAd->CommonCfg.Channel <=14) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40))
|
|
{
|
|
pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
|
|
pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset =
|
|
(UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((DetectOverlappingPeriodicRound == 25) || (DetectOverlappingPeriodicRound == 1))
|
|
{
|
|
if ((pAd->CommonCfg.Channel <=14) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth==BW_40))
|
|
{
|
|
SendBeaconRequest(pAd, 1);
|
|
SendBeaconRequest(pAd, 2);
|
|
SendBeaconRequest(pAd, 3);
|
|
}
|
|
|
|
}
|
|
DetectOverlappingPeriodicRound--;
|
|
}
|
|
#endif /* DOT11_N_SUPPORT */
|
|
}
|
|
|
|
|
|
/*
|
|
==========================================================================
|
|
Description:
|
|
This routine is executed every second -
|
|
1. Decide the overall channel quality
|
|
2. Check if need to upgrade the TX rate to any client
|
|
3. perform MAC table maintenance, including ageout no-traffic clients,
|
|
and release packet buffer in PSQ is fail to TX in time.
|
|
==========================================================================
|
|
*/
|
|
VOID APMlmePeriodicExec(
|
|
PRTMP_ADAPTER pAd)
|
|
{
|
|
/*
|
|
Reqeust by David 2005/05/12
|
|
It make sense to disable Adjust Tx Power on AP mode, since we can't
|
|
take care all of the client's situation
|
|
ToDo: need to verify compatibility issue with WiFi product.
|
|
*/
|
|
|
|
#ifdef BTCOEX_CONCURRENT
|
|
MT7662ReceCoexFromOtherCHip(pAd->CommonCfg.Channel,pAd->CommonCfg.CentralChannel,pAd->CommonCfg.BBPCurrentBW);
|
|
#endif
|
|
|
|
#ifdef RELEASE_EXCLUDE
|
|
/*
|
|
The following codes for TONE_RADAR from ARCH team, Roger.
|
|
Our new Tone Radar function in B mode spent more than one minutes restoring to Normal mode.
|
|
It is because the number of carrier detection interrupt is almost 0 in B mode when the Radar is disappear
|
|
To fix it, add the following codes to to detect whether the device stops sending interrupt or not during 1s.
|
|
If so, change AP to Normal mode.
|
|
*/
|
|
#endif /* RELEASE_EXCLUDE */
|
|
#ifdef CARRIER_DETECTION_SUPPORT
|
|
if (isCarrierDetectExist(pAd) == TRUE)
|
|
{
|
|
PCARRIER_DETECTION_STRUCT pCarrierDetect = &pAd->CommonCfg.CarrierDetect;
|
|
if (pCarrierDetect->OneSecIntCount < pCarrierDetect->CarrierGoneThreshold)
|
|
{
|
|
pCarrierDetect->CD_State = CD_NORMAL;
|
|
pCarrierDetect->recheck = pCarrierDetect->recheck1;
|
|
if (pCarrierDetect->Debug != RT_DEBUG_TRACE)
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("Carrier gone\n"));
|
|
/* start all TX actions. */
|
|
APMakeAllBssBeacon(pAd);
|
|
APUpdateAllBeaconFrame(pAd);
|
|
AsicEnableBssSync(pAd, pAd->CommonCfg.BeaconPeriod);
|
|
}
|
|
else
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("Carrier gone\n"));
|
|
}
|
|
}
|
|
pCarrierDetect->OneSecIntCount = 0;
|
|
}
|
|
|
|
#endif /* CARRIER_DETECTION_SUPPORT */
|
|
|
|
#ifdef RELEASE_EXCLUDE
|
|
/*
|
|
high-power issue:
|
|
request by Brian, If our 2070/3070/305x AP/Station is too close to receive the stations/APs signal,
|
|
we will dynamically tune the RF power(controlled by RF_R27).
|
|
The tuning rules are
|
|
1. If the connecting devices is too close, we will attenuate the RF power to 0V.
|
|
2. Otherwise, recover the RF power to original level (0.15V)
|
|
*/
|
|
#endif /* RELEASE_EXCLUDE */
|
|
RTMP_CHIP_HIGH_POWER_TUNING(pAd, &pAd->ApCfg.RssiSample);
|
|
|
|
|
|
/* Disable Adjust Tx Power for WPA WiFi-test. */
|
|
/* Because high TX power results in the abnormal disconnection of Intel BG-STA. */
|
|
/*#ifndef WIFI_TEST */
|
|
/* if (pAd->CommonCfg.bWiFiTest == FALSE) */
|
|
/* for SmartBit 64-byte stream test */
|
|
/* removed based on the decision of Ralink congress at 2011/7/06 */
|
|
/* if (pAd->MacTab.Size > 0) */
|
|
RTMP_CHIP_ASIC_ADJUST_TX_POWER(pAd);
|
|
/*#endif // WIFI_TEST */
|
|
|
|
RTMP_CHIP_ASIC_TEMPERATURE_COMPENSATION(pAd);
|
|
|
|
/* walk through MAC table, see if switching TX rate is required */
|
|
#if 0 /* move to mlme.c::MlmePeriodicExec */
|
|
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
|
|
APMlmeDynamicTxRateSwitching(pAd);
|
|
#endif
|
|
|
|
/* MAC table maintenance */
|
|
if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE == 0)
|
|
{
|
|
/* one second timer */
|
|
MacTableMaintenance(pAd);
|
|
|
|
#ifdef CONFIG_FPGA_MODE
|
|
if (pAd->fpga_ctl.fpga_tr_stop)
|
|
{
|
|
INT enable = FALSE, ctrl_type;
|
|
|
|
/* enable/disable tx/rx*/
|
|
switch (pAd->fpga_ctl.fpga_tr_stop)
|
|
{
|
|
case 3: //stop tx + rx
|
|
ctrl_type = ASIC_MAC_TXRX;
|
|
break;
|
|
case 2: // stop rx
|
|
ctrl_type = ASIC_MAC_RX;
|
|
break;
|
|
case 1: // stop tx
|
|
ctrl_type = ASIC_MAC_TX;
|
|
break;
|
|
case 4:
|
|
default:
|
|
enable = TRUE;
|
|
ctrl_type = ASIC_MAC_TXRX;
|
|
break;
|
|
}
|
|
AsicSetMacTxRx(pAd, ctrl_type, (BOOLEAN)enable);
|
|
}
|
|
#endif /* CONFIG_FPGA_MODE */
|
|
|
|
RTMPMaintainPMKIDCache(pAd);
|
|
|
|
#ifdef WDS_SUPPORT
|
|
WdsTableMaintenance(pAd);
|
|
#endif /* WDS_SUPPORT */
|
|
|
|
#ifdef MESH_SUPPORT
|
|
if(MESH_ON(pAd))
|
|
{
|
|
UCHAR idx;
|
|
/* period update Neighbor table. */
|
|
NeighborTableUpdate(pAd);
|
|
/* update Mesh Link */
|
|
MeshLinkTableMaintenace(pAd);
|
|
/* update Mesh multipath entry. */
|
|
for (idx = 0; idx < MAX_MESH_LINKS; idx ++)
|
|
{
|
|
if (PeerLinkValidCheck(pAd, idx))
|
|
MultipathEntryMaintain(pAd, idx);
|
|
}
|
|
}
|
|
#endif /* MESH_SUPPORT */
|
|
|
|
#ifdef CLIENT_WDS
|
|
CliWds_ProxyTabMaintain(pAd);
|
|
#endif /* CLIENT_WDS */
|
|
}
|
|
|
|
#ifdef AP_SCAN_SUPPORT
|
|
AutoChannelSelCheck(pAd);
|
|
#endif /* AP_SCAN_SUPPORT */
|
|
|
|
APUpdateCapabilityAndErpIe(pAd);
|
|
|
|
#ifdef APCLI_SUPPORT
|
|
if (pAd->Mlme.OneSecPeriodicRound % 2 == 0)
|
|
ApCliIfMonitor(pAd);
|
|
|
|
if (pAd->Mlme.OneSecPeriodicRound % 2 == 1
|
|
#ifdef APCLI_AUTO_CONNECT_SUPPORT
|
|
&& (pAd->ApCfg.ApCliAutoConnectChannelSwitching == FALSE)
|
|
#endif /* APCLI_AUTO_CONNECT_SUPPORT */
|
|
) {
|
|
ApCliIfUp(pAd);
|
|
}
|
|
|
|
{
|
|
INT loop;
|
|
ULONG Now32;
|
|
|
|
#ifdef MAC_REPEATER_SUPPORT
|
|
if (pAd->ApCfg.bMACRepeaterEn)
|
|
{
|
|
RTMPRepeaterReconnectionCheck(pAd);
|
|
}
|
|
#endif /* MAC_REPEATER_SUPPORT */
|
|
|
|
NdisGetSystemUpTime(&Now32);
|
|
for (loop = 0; loop < MAX_APCLI_NUM; loop++)
|
|
{
|
|
PAPCLI_STRUCT pApCliEntry = &pAd->ApCfg.ApCliTab[loop];
|
|
if ((pApCliEntry->Valid == TRUE)
|
|
&& (pApCliEntry->MacTabWCID < MAX_LEN_OF_MAC_TABLE))
|
|
{
|
|
/* update channel quality for Roaming and UI LinkQuality display */
|
|
MlmeCalculateChannelQuality(pAd,
|
|
&pAd->MacTab.Content[pApCliEntry->MacTabWCID], Now32);
|
|
}
|
|
}
|
|
}
|
|
#endif /* APCLI_SUPPORT */
|
|
|
|
#ifdef DOT11_N_SUPPORT
|
|
if (pAd->CommonCfg.bHTProtect) {
|
|
/*APUpdateCapabilityAndErpIe(pAd); */
|
|
APUpdateOperationMode(pAd);
|
|
if (pAd->CommonCfg.IOTestParm.bRTSLongProtOn == FALSE)
|
|
AsicUpdateProtect(pAd, (USHORT)pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode,
|
|
ALLN_SETPROTECT, FALSE, pAd->MacTab.fAnyStationNonGF);
|
|
}
|
|
#endif /* DOT11_N_SUPPORT */
|
|
|
|
#ifdef A_BAND_SUPPORT
|
|
if ( (pAd->CommonCfg.Channel > 14)
|
|
&& (pAd->CommonCfg.bIEEE80211H == 1))
|
|
{
|
|
#ifdef DFS_SUPPORT
|
|
ApRadarDetectPeriodic(pAd);
|
|
#else
|
|
pAd->Dot11_H.InServiceMonitorCount++;
|
|
if (pAd->Dot11_H.RDMode == RD_SILENCE_MODE)
|
|
{
|
|
if (pAd->Dot11_H.RDCount++ > pAd->Dot11_H.ChMovingTime)
|
|
{
|
|
AsicEnableBssSync(pAd, pAd->CommonCfg.BeaconPeriod);
|
|
pAd->Dot11_H.RDMode = RD_NORMAL_MODE;
|
|
}
|
|
}
|
|
#endif /* !DFS_SUPPORT */
|
|
}
|
|
#endif /* A_BAND_SUPPORT */
|
|
|
|
#ifdef DOT11R_FT_SUPPORT
|
|
FT_R1KHInfoMaintenance(pAd);
|
|
#endif /* DOT11R_FT_SUPPORT */
|
|
|
|
}
|
|
|
|
|
|
/*! \brief To substitute the message type if the message is coming from external
|
|
* \param *Fr The frame received
|
|
* \param *Machine The state machine
|
|
* \param *MsgType the message type for the state machine
|
|
* \return TRUE if the substitution is successful, FALSE otherwise
|
|
* \pre
|
|
* \post
|
|
*/
|
|
BOOLEAN APMsgTypeSubst(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN PFRAME_802_11 pFrame,
|
|
OUT INT *Machine,
|
|
OUT INT *MsgType)
|
|
{
|
|
USHORT Seq;
|
|
UCHAR EAPType;
|
|
BOOLEAN Return = FALSE;
|
|
#ifdef WSC_AP_SUPPORT
|
|
UCHAR EAPCode;
|
|
PMAC_TABLE_ENTRY pEntry;
|
|
#endif /* WSC_AP_SUPPORT */
|
|
#ifdef WPA3_SUPPORT
|
|
USHORT Alg;
|
|
#endif
|
|
|
|
/*
|
|
TODO:
|
|
only PROBE_REQ can be broadcast, all others must be unicast-to-me && is_mybssid;
|
|
otherwise, ignore this frame
|
|
*/
|
|
|
|
/* wpa EAPOL PACKET */
|
|
if (pFrame->Hdr.FC.Type == FC_TYPE_DATA)
|
|
{
|
|
#ifdef WSC_AP_SUPPORT
|
|
WSC_CTRL *wsc_ctrl;
|
|
/*WSC EAPOL PACKET */
|
|
pEntry = MacTableLookup(pAd, pFrame->Hdr.Addr2);
|
|
if (pEntry &&
|
|
((pEntry->bWscCapable) ||
|
|
(pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.AuthMode < Ndis802_11AuthModeWPA)))
|
|
{
|
|
/*
|
|
WSC AP only can service one WSC STA in one WPS session.
|
|
Forward this EAP packet to WSC SM if this EAP packets is from
|
|
WSC STA that WSC AP services or WSC AP doesn't service any
|
|
WSC STA now.
|
|
*/
|
|
wsc_ctrl = &pAd->ApCfg.MBSSID[pEntry->func_tb_idx].WscControl;
|
|
if ((MAC_ADDR_EQUAL(wsc_ctrl->EntryAddr, pEntry->Addr) ||
|
|
MAC_ADDR_EQUAL(wsc_ctrl->EntryAddr, ZERO_MAC_ADDR)) &&
|
|
IS_ENTRY_CLIENT(pEntry) &&
|
|
(wsc_ctrl->WscConfMode != WSC_DISABLE))
|
|
{
|
|
*Machine = WSC_STATE_MACHINE;
|
|
EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
|
|
EAPCode = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 4);
|
|
Return = WscMsgTypeSubst(EAPType, EAPCode, MsgType);
|
|
}
|
|
}
|
|
#endif /* WSC_AP_SUPPORT */
|
|
if (!Return)
|
|
{
|
|
*Machine = WPA_STATE_MACHINE;
|
|
EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
|
|
Return = WpaMsgTypeSubst(EAPType, (INT *) MsgType);
|
|
}
|
|
return Return;
|
|
}
|
|
|
|
if (pFrame->Hdr.FC.Type != FC_TYPE_MGMT)
|
|
return FALSE;
|
|
|
|
switch (pFrame->Hdr.FC.SubType)
|
|
{
|
|
case SUBTYPE_ASSOC_REQ:
|
|
*Machine = AP_ASSOC_STATE_MACHINE;
|
|
*MsgType = APMT2_PEER_ASSOC_REQ;
|
|
#ifdef RELEASE_EXCLUDE
|
|
DBGPRINT_RAW(RT_DEBUG_INFO,("SUBTYPE_ASSOC_REQ\n"));
|
|
#endif /* RELEASE_EXCLUDE */
|
|
|
|
break;
|
|
/*
|
|
case SUBTYPE_ASSOC_RSP:
|
|
*Machine = AP_ASSOC_STATE_MACHINE;
|
|
*MsgType = APMT2_PEER_ASSOC_RSP;
|
|
break;
|
|
*/
|
|
case SUBTYPE_REASSOC_REQ:
|
|
*Machine = AP_ASSOC_STATE_MACHINE;
|
|
*MsgType = APMT2_PEER_REASSOC_REQ;
|
|
break;
|
|
/*
|
|
case SUBTYPE_REASSOC_RSP:
|
|
*Machine = AP_ASSOC_STATE_MACHINE;
|
|
*MsgType = APMT2_PEER_REASSOC_RSP;
|
|
break;
|
|
*/
|
|
case SUBTYPE_PROBE_REQ:
|
|
*Machine = AP_SYNC_STATE_MACHINE;
|
|
*MsgType = APMT2_PEER_PROBE_REQ;
|
|
break;
|
|
|
|
/* For Active Scan */
|
|
case SUBTYPE_PROBE_RSP:
|
|
*Machine = AP_SYNC_STATE_MACHINE;
|
|
*MsgType = APMT2_PEER_PROBE_RSP;
|
|
break;
|
|
case SUBTYPE_BEACON:
|
|
*Machine = AP_SYNC_STATE_MACHINE;
|
|
*MsgType = APMT2_PEER_BEACON;
|
|
break;
|
|
/*
|
|
case SUBTYPE_ATIM:
|
|
*Machine = AP_SYNC_STATE_MACHINE;
|
|
*MsgType = APMT2_PEER_ATIM;
|
|
break;
|
|
*/
|
|
case SUBTYPE_DISASSOC:
|
|
*Machine = AP_ASSOC_STATE_MACHINE;
|
|
*MsgType = APMT2_PEER_DISASSOC_REQ;
|
|
break;
|
|
case SUBTYPE_AUTH:
|
|
/* get the sequence number from payload 24 Mac Header + 2 bytes algorithm */
|
|
NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
|
|
#ifdef RELEASE_EXCLUDE
|
|
DBGPRINT(RT_DEBUG_INFO,("AUTH seq=%d Octet=%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
|
Seq,
|
|
pFrame->Octet[0], pFrame->Octet[1], pFrame->Octet[2], pFrame->Octet[3],
|
|
pFrame->Octet[4], pFrame->Octet[5], pFrame->Octet[6], pFrame->Octet[7]));
|
|
#endif /* RELEASE_EXCLUDE */
|
|
|
|
*Machine = AP_AUTH_STATE_MACHINE;
|
|
#ifdef WPA3_SUPPORT
|
|
NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(USHORT));
|
|
if ((Seq < 0) || (Seq > 4)) {
|
|
DBGPRINT(RT_DEBUG_ERROR, ("%s() Rx auth with unexpected TransactionSeqNum:%d\n", __func__, Seq));
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
if (Seq == 1)
|
|
*MsgType = APMT2_PEER_AUTH_REQ;
|
|
else if (Seq == 3)
|
|
*MsgType = APMT2_PEER_AUTH_CONFIRM;
|
|
#ifdef WPA3_SUPPORT
|
|
else if (Seq == 2 && Alg == AUTH_MODE_SAE)
|
|
*MsgType = APMT2_PEER_AUTH_CONFIRM;
|
|
#endif
|
|
else
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE,("wrong AUTH seq=%d Octet=%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
|
Seq,
|
|
pFrame->Octet[0], pFrame->Octet[1], pFrame->Octet[2], pFrame->Octet[3],
|
|
pFrame->Octet[4], pFrame->Octet[5], pFrame->Octet[6], pFrame->Octet[7]));
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case SUBTYPE_DEAUTH:
|
|
*Machine = AP_AUTH_STATE_MACHINE; /*AP_AUTH_RSP_STATE_MACHINE;*/
|
|
*MsgType = APMT2_PEER_DEAUTH;
|
|
break;
|
|
|
|
case SUBTYPE_ACTION:
|
|
case SUBTYPE_ACTION_NO_ACK:
|
|
*Machine = ACTION_STATE_MACHINE;
|
|
/* Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support */
|
|
#ifdef P2P_SUPPORT
|
|
/* Vendor specific usage. */
|
|
if ((pFrame->Octet[0] & 0x7F) == MT2_ACT_VENDOR) /* Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support */
|
|
{
|
|
UCHAR P2POUIBYTE[4] = {0x50, 0x6f, 0x9a, 0x9};
|
|
|
|
DBGPRINT(RT_DEBUG_ERROR, ("Vendor Action frame OUI= 0x%x\n", *(PULONG)&pFrame->Octet[1]));
|
|
/* Now support WFA P2P */
|
|
if (RTMPEqualMemory(&pFrame->Octet[1], P2POUIBYTE, 4) && (P2P_INF_ON(pAd)))
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("Vendor Action frame P2P OUI= 0x%x\n", *(PULONG)&pFrame->Octet[1]));
|
|
*Machine = P2P_ACTION_STATE_MACHINE;
|
|
if (pFrame->Octet[5] <= MT2_MAX_PEER_SUPPORT)
|
|
{
|
|
*MsgType = pFrame->Octet[5]; /* subtype. */
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
#endif /* P2P_SUPPORT */
|
|
if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
|
|
{
|
|
*MsgType = MT2_ACT_INVALID;
|
|
}
|
|
else
|
|
{
|
|
*MsgType = (pFrame->Octet[0]&0x7F);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
========================================================================
|
|
Routine Description:
|
|
Periodic evaluate antenna link status
|
|
|
|
Arguments:
|
|
pAd - Adapter pointer
|
|
|
|
Return Value:
|
|
None
|
|
|
|
========================================================================
|
|
*/
|
|
VOID APAsicEvaluateRxAnt(
|
|
IN PRTMP_ADAPTER pAd)
|
|
{
|
|
ULONG TxTotalCnt;
|
|
|
|
#ifdef CONFIG_ATE
|
|
if (ATE_ON(pAd))
|
|
return;
|
|
#endif /* CONFIG_ATE */
|
|
#ifdef CARRIER_DETECTION_SUPPORT
|
|
if(pAd->CommonCfg.CarrierDetect.CD_State == CD_SILENCE)
|
|
return;
|
|
#endif /* CARRIER_DETECTION_SUPPORT */
|
|
|
|
#ifdef RT8592
|
|
// TODO: shiang-6590, for 8592, this EvaaluateRxAnt still need??
|
|
if (IS_RT8592(pAd))
|
|
return;
|
|
#endif /* RT8592 */
|
|
|
|
#ifdef RT65xx
|
|
if (IS_RT65XX(pAd))
|
|
return;
|
|
#endif /* RT76x0 */
|
|
|
|
#ifdef MT7601
|
|
if ( IS_MT7601(pAd) )
|
|
return;
|
|
#endif /* MT7601 */
|
|
|
|
#ifdef TXBF_SUPPORT
|
|
/* TODO: we didn't do RxAnt evaluate for 3x3 chips */
|
|
if (IS_RT3883(pAd) || IS_RT2883(pAd))
|
|
return;
|
|
#endif /* TXBF_SUPPORT */
|
|
|
|
#ifdef RELEASE_EXCLUDE
|
|
DBGPRINT(RT_DEBUG_INFO, ("AsicEvaluateRxAnt : RealRxPath=%d \n", pAd->Mlme.RealRxPath));
|
|
#endif /* RELEASE_EXCLUDE */
|
|
|
|
#ifdef DOT11_N_SUPPORT
|
|
#ifdef GREENAP_SUPPORT
|
|
if (pAd->ApCfg.bGreenAPActive == TRUE)
|
|
bbp_set_rxpath(pAd, 1);
|
|
else
|
|
#endif /* GREENAP_SUPPORT */
|
|
#endif /* DOT11_N_SUPPORT */
|
|
bbp_set_rxpath(pAd, pAd->Antenna.field.RxPath);
|
|
|
|
TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
|
|
pAd->RalinkCounters.OneSecTxRetryOkCount +
|
|
pAd->RalinkCounters.OneSecTxFailCount;
|
|
|
|
if (TxTotalCnt > 50)
|
|
{
|
|
RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
|
|
pAd->Mlme.bLowThroughput = FALSE;
|
|
}
|
|
else
|
|
{
|
|
RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
|
|
pAd->Mlme.bLowThroughput = TRUE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
========================================================================
|
|
Routine Description:
|
|
After evaluation, check antenna link status
|
|
|
|
Arguments:
|
|
pAd - Adapter pointer
|
|
|
|
Return Value:
|
|
None
|
|
|
|
========================================================================
|
|
*/
|
|
VOID APAsicRxAntEvalTimeout(RTMP_ADAPTER *pAd)
|
|
{
|
|
CHAR rssi[3], *target_rssi;
|
|
|
|
#ifdef CONFIG_ATE
|
|
if (ATE_ON(pAd))
|
|
return;
|
|
#endif /* CONFIG_ATE */
|
|
|
|
/* if the traffic is low, use average rssi as the criteria */
|
|
if (pAd->Mlme.bLowThroughput == TRUE)
|
|
target_rssi = &pAd->ApCfg.RssiSample.LastRssi[0];
|
|
else
|
|
target_rssi = &pAd->ApCfg.RssiSample.AvgRssi[0];
|
|
NdisMoveMemory(&rssi[0], target_rssi, 3);
|
|
|
|
#ifdef DOT11N_SS3_SUPPORT
|
|
if(pAd->Antenna.field.RxPath == 3)
|
|
{
|
|
CHAR larger = -127;
|
|
|
|
larger = max(rssi[0], rssi[1]);
|
|
if (pAd->CommonCfg.RxStream >= 3)
|
|
pAd->Mlme.RealRxPath = 3;
|
|
else
|
|
{
|
|
if (larger > (rssi[2] + 20))
|
|
pAd->Mlme.RealRxPath = 2;
|
|
else
|
|
pAd->Mlme.RealRxPath = 3;
|
|
}
|
|
}
|
|
#endif /* DOT11N_SS3_SUPPORT */
|
|
|
|
/* Disable the below to fix 1T/2R issue. It's suggested by Rory at 2007/7/11. */
|
|
#if 0
|
|
else if(pAd->Antenna.field.RxPath == 2)
|
|
{
|
|
if (rssi[0] > (rssi[1] + 20))
|
|
pAd->Mlme.RealRxPath = 1;
|
|
else
|
|
pAd->Mlme.RealRxPath = 2;
|
|
}
|
|
#endif
|
|
|
|
#ifdef DOT11_N_SUPPORT
|
|
#ifdef GREENAP_SUPPORT
|
|
if (pAd->ApCfg.bGreenAPActive == TRUE)
|
|
bbp_set_rxpath(pAd, 1);
|
|
else
|
|
#endif /* GREENAP_SUPPORT */
|
|
#endif /* DOT11_N_SUPPORT */
|
|
bbp_set_rxpath(pAd, pAd->Mlme.RealRxPath);
|
|
|
|
#ifdef RELEASE_EXCLUDE
|
|
DBGPRINT(RT_DEBUG_INFO, ("APAsicRxAntEvalTimeout : RealRxPath=%d, Rssi=%d, %d, %d \n",
|
|
pAd->Mlme.RealRxPath, rssi[0], rssi[1], rssi[2]));
|
|
#endif /* RELEASE_EXCLUDE */
|
|
}
|
|
|
|
|
|
/*
|
|
========================================================================
|
|
Routine Description:
|
|
After evaluation, check antenna link status
|
|
|
|
Arguments:
|
|
pAd - Adapter pointer
|
|
|
|
Return Value:
|
|
None
|
|
|
|
========================================================================
|
|
*/
|
|
VOID APAsicAntennaAvg(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN UCHAR AntSelect,
|
|
IN SHORT* RssiAvg)
|
|
{
|
|
SHORT realavgrssi;
|
|
LONG realavgrssi1;
|
|
ULONG recvPktNum = pAd->RxAnt.RcvPktNum[AntSelect];
|
|
|
|
realavgrssi1 = pAd->RxAnt.Pair1AvgRssiGroup1[AntSelect];
|
|
|
|
if(realavgrssi1 == 0)
|
|
{
|
|
*RssiAvg = 0;
|
|
return;
|
|
}
|
|
|
|
realavgrssi = (SHORT) (realavgrssi1 / recvPktNum);
|
|
|
|
pAd->RxAnt.Pair1AvgRssiGroup1[0] = 0;
|
|
pAd->RxAnt.Pair1AvgRssiGroup1[1] = 0;
|
|
pAd->RxAnt.Pair1AvgRssiGroup2[0] = 0;
|
|
pAd->RxAnt.Pair1AvgRssiGroup2[1] = 0;
|
|
pAd->RxAnt.RcvPktNum[0] = 0;
|
|
pAd->RxAnt.RcvPktNum[1] = 0;
|
|
#ifdef RELEASE_EXCLUDE
|
|
/* AP will increase the RSSI sample from STA's Data From, and calculate the Avg. RSSI
|
|
* when needed. In some embedded system, if we divide negative integer the result is
|
|
* in-correct. So we convert the negative integer to positive by adding 256.
|
|
*
|
|
* In COLLECT_RX_ANTENNA_AVERAGE_RSSI, we have add 256 for each RSSI sample.
|
|
* After average the RSSI, we should decrease 256 to convert it back.
|
|
*/
|
|
#endif /* RELEASE_EXCLUDE */
|
|
*RssiAvg = realavgrssi - 256;
|
|
}
|
|
|