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

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;
}