Murat Demirtas 612db32659 FIXED
2016-10-30 14:40:00 +00:00

5999 lines
188 KiB
C

/*
***************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
*
* (c) Copyright 2002-2010, 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:
p2p.c
Abstract:
Peer to peer is also called Wifi Direct. P2P is a Task Group of WFA.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Jan Lee 2009-10-05 created for Peer-to-Peer(Wifi Direct)
*/
#include "rt_config.h"
/* Vendor Specific OUI for P2P defined by WFA. */
UCHAR P2POUIBYTE[4] = {0x50, 0x6f, 0x9a, 0x9}; /* spec. 1.14 OUI */
extern UCHAR ZERO_MAC_ADDR[];
extern UCHAR STA_Wsc_Pri_Dev_Type[];
UCHAR WILDP2PSSID[7] = {'D', 'I', 'R', 'E', 'C', 'T','-'};
UCHAR WILDP2PSSIDLEN = 7;
UCHAR WIFIDIRECT_OUI[] = {0x50, 0x6f, 0x9a, 0x09}; /* spec. 1.14 OUI */
/* UCHAR DEFAULTWPAPSKEY[8] = {0x33, 0x35, 0x33, 0x34, 0x33, 0x36, 0x31, 0x34};*/
/* Like to key in 12345678 */
UCHAR DEFAULTWPAPSKEY[8] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38};
#ifdef CONFIG_MULTI_CHANNEL
extern INT Show_StaStayTime_Proc(
IN PRTMP_ADAPTER pAd,
OUT PSTRING pBuf,
IN ULONG BufLen);
extern INT Show_P2pStayTime_Proc(
IN PRTMP_ADAPTER pAd,
OUT PSTRING pBuf,
IN ULONG BufLen);
#endif /* CONFIG_MULTI_CHANNEL */
extern INT Set_P2p_OpMode_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
extern INT Set_AP_WscSsid_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
extern INT Set_AP_WscConfMode_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
extern INT Set_AP_WscConfStatus_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
extern INT Set_AP_WscMode_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
extern INT Set_AP_WscGetConf_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
extern INT Set_AP_WscPinCode_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
extern INT Set_P2pCli_WscSsid_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
extern INT Set_P2pCli_Ssid_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
extern INT Set_P2pCli_Enable_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
/*
==========================================================================
Description:
Called once when the card is being initialized.
Parameters:
Note:
==========================================================================
*/
#include "rt_config.h"
#include "p2p.h"
VOID P2pCfgInit(
IN PRTMP_ADAPTER pAd)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
pP2PCtrl->P2p_OpMode = P2P_CONCURRENT;
pP2PCtrl->bKeepSlient = FALSE;
pP2PCtrl->NoAIndex = MAX_P2P_GROUP_SIZE;
pP2PCtrl->ListenChannel = 1;
pP2PCtrl->GroupChannel = 1;
pP2PCtrl->GroupOpChannel = 1;
P2pSetListenIntBias(pAd, 3);
pP2PCtrl->Manufacturer[0] = 0x20;
pP2PCtrl->ManufacturerLen = 0x01;
pP2PCtrl->ModelName[0] = 0x20;
pP2PCtrl->ModelNameLen = 0x01;
pP2PCtrl->ModelNumber[0] = 0x20;
pP2PCtrl->ModelNumberLen = 0x01;
pP2PCtrl->SerialNumber[0] = 0x20;
pP2PCtrl->SerialNumberLen = 0x01;
pP2PCtrl->DeviceNameLen = 10;
pP2PCtrl->DeviceName[0] = 'R';
pP2PCtrl->DeviceName[1] = 'a';
pP2PCtrl->DeviceName[2] = 'l';
pP2PCtrl->DeviceName[3] = 'i';
pP2PCtrl->DeviceName[4] = 'n';
pP2PCtrl->DeviceName[5] = 'k';
pP2PCtrl->DeviceName[6] = '-';
pP2PCtrl->DeviceName[7] = 'P';
pP2PCtrl->DeviceName[8] = 0x32;
pP2PCtrl->DeviceName[9] = 'P';
/*pP2PCtrl->P2PDiscoProvState = P2P_DISABLE; */
pP2PCtrl->P2PConnectState = P2P_CONNECT_IDLE;
/* Set Dpid to "not specified". it means, GUI doesn't set for connection yet. */
pP2PCtrl->Dpid = DEV_PASS_ID_NOSPEC;
pP2PCtrl->P2pManagedParm.APP2pManageability = 0xff;
pP2PCtrl->P2pManagedParm.ICSStatus = ICS_STATUS_DISABLED;
P2pGroupTabInit(pAd);
P2pCrednTabClean(pAd);
P2pScanChannelDefault(pAd);
RTMPZeroMemory(pAd->P2pCfg.SSID, MAX_LEN_OF_SSID);
RTMPMoveMemory(pAd->P2pCfg.SSID, WILDP2PSSID, WILDP2PSSIDLEN);
/*RTMPMoveMemory(pAd->P2pCfg.Bssid, pAd->P2pCfg.CurrentAddress, MAC_ADDR_LEN); */
pP2PCtrl->SSIDLen = WILDP2PSSIDLEN;
pP2PCtrl->GONoASchedule.bValid = FALSE;
pP2PCtrl->GONoASchedule.bInAwake = TRUE;
pP2PCtrl->GONoASchedule.bWMMPSInAbsent = FALSE; /* Set to FALSE if changes state to Awake */
pP2PCtrl->GONoASchedule.Token = 0;
pP2PCtrl->GoIntentIdx = 0;
pP2PCtrl->Rule = P2P_IS_DEVICE;
pP2PCtrl->WscMode = WSC_PIN_MODE;
pP2PCtrl->DefaultConfigMethod = P2P_REG_CM_DISPLAY;
pP2PCtrl->bExtListen = FALSE;
pP2PCtrl->bIntraBss = FALSE;
pP2PCtrl->ExtListenInterval = P2P_EXT_LISTEN_INTERVAL;
pP2PCtrl->ExtListenPeriod = P2P_EXT_LISTEN_PERIOD;
pP2PCtrl->GONoASchedule.Count = 0;
pP2PCtrl->GONoASchedule.Duration = 0;
pP2PCtrl->GONoASchedule.Interval = 0;
pP2PCtrl->DevDiscPeriod = P2P_SCAN_PERIOD;
/* P2P WSC_IR default value */
pP2PCtrl->DevInfo.Version = WSC_VERSION;
pP2PCtrl->bConfiguredAP = TRUE;
pP2PCtrl->DevInfo.RfBand |= WSC_RFBAND_24GHZ; /* 2.4G */
NdisMoveMemory(&pP2PCtrl->DevInfo.PriDeviceType, &STA_Wsc_Pri_Dev_Type[0], 8);
/* zero means no 2nd Device Type List*/
pP2PCtrl->DevInfo.SecDevTypList[0]=0x00;
pP2PCtrl->bSigmaEnabled = FALSE;
pP2PCtrl->bP2pCliPmEnable = FALSE;
pP2PCtrl->bLowRateQoSNULL = FALSE;
pP2PCtrl->bP2pCliReConnect = FALSE;
pP2PCtrl->bStopAuthRsp = TRUE;
pP2PCtrl->bP2pReSendTimerRunning = FALSE;
pP2PCtrl->DevDiscPeriod = P2P_SCAN_PERIOD;
pP2PCtrl->bPeriodicListen = TRUE;
/* Reset bConfirmByUI to its default value */
pP2PCtrl->bConfirmByUI = CONFIRM_BY_UI_DEFAULT;;
pP2PCtrl->p2pMaxEntry = 0;
pP2PCtrl->bProvAutoRsp = TRUE;
pP2PCtrl->P2pProvIndex = 0xFF;
pP2PCtrl->P2pProvUserNotify = 0;
pP2PCtrl->pGoNegoRspOutBuffer = NULL;
pP2PCtrl->bSentProbeRSP = FALSE;
/*
Bit[31] : Software Based NoA implementation
Bit[23] : Opps, not use.
Bit[22] : Service Discovey, not use.
Bit[21] : Extent Listen
Bit[20] : Client Discovery
Bit[16:19] : OpChannel, not use
Bit[15] : IntraBss
Bit[12:14] : Config Method, not use.
Bit[8:11] : Default Channel, not use.
Bit[4:7] : GO Intent, not use.
Bit[3] : Invite
Bit[2] : Persistent, not use.
Bit[1] : Managed
Bit[0] : Enable, not use.
*/
pP2PCtrl->P2pControl.word = 0x80108008;
DBGPRINT(RT_DEBUG_ERROR, ("%s:: \n", __FUNCTION__));
}
/*
==========================================================================
Description:
Periodic Routine for P2P.
Parameters:
Note:
==========================================================================
*/
VOID P2pPeriodicExec(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3)
{
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
ULONG BssIdx = BSS_NOT_FOUND;
if ((pP2PCtrl->P2pCounter.bListen) && (pP2PCtrl->P2pCounter.ListenInterval > 0))
pP2PCtrl->P2pCounter.ListenInterval--; /* update Listen interval */
if (pP2PCtrl->P2pCounter.NextScanRound > 0)
pP2PCtrl->P2pCounter.NextScanRound--; /* update Next Scan Round */
if (pP2PCtrl->P2pCounter.CounterAftrScanButton > 0)
pP2PCtrl->P2pCounter.CounterAftrScanButton--; /* update Device Discovery period */
if (pP2PCtrl->P2pCounter.CounterAftrSetEvent != 0xffffffff)
pP2PCtrl->P2pCounter.CounterAftrSetEvent++;
if (pP2PCtrl->P2pCounter.ClientConnectedCounter > 0)
pP2PCtrl->P2pCounter.ClientConnectedCounter--;
if (pP2PCtrl->P2pCounter.ManageAPEnReconCounter > 0)
pP2PCtrl->P2pCounter.ManageAPEnReconCounter--;
DBGPRINT(RT_DEBUG_INFO, ("%s : Counter100ms[%ld] CounterAftScanButton[%ld] ClientConnCnt[%ld] MngAPEnReconnCnt[%ld] DisableRetryGrpFormCnt[%ld] NextScanRound[%ld]\n",
__FUNCTION__, pP2PCtrl->P2pCounter.Counter100ms, pP2PCtrl->P2pCounter.CounterAftrScanButton, pP2PCtrl->P2pCounter.ClientConnectedCounter,
pP2PCtrl->P2pCounter.CounterAftrSetEvent, pP2PCtrl->P2pCounter.DisableRetryGrpFormCounter, pP2PCtrl->P2pCounter.NextScanRound));
/* Scan period expired. Return to listen state. Only do once. So check value equal. */
if ((pP2PCtrl->P2pCounter.bStartScan == TRUE) && (pAd->P2pCfg.P2pCounter.CounterAftrScanButton == 0))
P2PDevDiscTimerExec(pAd, 0);
/* Check whether to start a P2P scan /search process. */
if ((pP2PCtrl->P2pCounter.bListen) && (pP2PCtrl->P2pCounter.ListenInterval == 0))
P2PListenTimerExec(pAd, 0);
if ((pP2PCtrl->P2pCounter.bNextScan == TRUE) && (pP2PCtrl->P2pCounter.NextScanRound == 0))
P2PNextScanTimerExec(pAd, 0);
if (pAd->P2pCfg.P2pCounter.UserAccept > 0)
{
pAd->P2pCfg.P2pCounter.UserAccept--;
}
if ((pP2PCtrl->bProvAutoRsp == FALSE) && (pP2PCtrl->P2pProvIndex != P2P_NOT_FOUND) )
{
if (pP2PCtrl->P2pCounter.UserAccept == 0)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
pP2PCtrl->P2pProvUserNotify = 0;
pP2PCtrl->P2pProvIndex = P2P_NOT_FOUND;
}
}
/* ====================================> */
/* P2P connect state maintain */
if (((pP2PCtrl->P2PConnectState == P2P_DO_GO_SCAN_BEGIN)
|| (pP2PCtrl->P2PConnectState == P2P_DO_GO_NEG_DONE_CLIENT)
|| (pP2PCtrl->P2PConnectState == P2P_DO_GO_SCAN_OP_BEGIN))
&& (pP2PCtrl->P2pCounter.Counter100ms == pP2PCtrl->P2pCounter.NextScanRound))
{
DBGPRINT(RT_DEBUG_ERROR, ("P2P P2pPeriodicExec Scan Begin NextScanRound = %ld \n", pP2PCtrl->P2pCounter.NextScanRound));
MlmeEnqueue(pAd,
MLME_CNTL_STATE_MACHINE,
OID_802_11_BSSID_LIST_SCAN,
0,
"",
0);
MlmeHandler(pAd);
pP2PCtrl->P2pCounter.Counter100ms = 0;
pP2PCtrl->P2pCounter.NextScanRound = (RandomByte(pAd) % P2P_RANDOM_WPS_BASE) + 4;
}
else if ((pAd->P2pCfg.P2PConnectState == P2P_DO_GO_SCAN_DONE)
|| (pAd->P2pCfg.P2PConnectState == P2P_DO_GO_SCAN_OP_DONE))
{
/* if(pP2PCtrl->PortSubtype != PORTSUBTYPE_P2PGO) */
if (!P2P_GO_ON(pAd))
{
DBGPRINT(RT_DEBUG_ERROR, ("P2PConnectState[%s] : Do BssTableSearch\n", decodeP2PState(pP2PCtrl->P2PConnectState)));
/* BssIdx = BssTableSearch(pAd, &pAd->ScanTab, pAd->P2pCfg.Bssid, pAd->StaCfg.WscControl.WscAPChannel); */
BssIdx = BssTableSearch(&pAd->ScanTab, pAd->P2pCfg.Bssid, pAd->MlmeAux.Channel);
}
/* Since can't find the target AP in the list.
Go back to scan state again to scan the target AP. */
if (BssIdx == BSS_NOT_FOUND)
{
pP2PCtrl->P2PConnectState = P2P_DO_GO_SCAN_BEGIN;
pP2PCtrl->P2pCounter.Counter100ms = 0;
pP2PCtrl->P2pCounter.NextScanRound = 10; /* start scan after 1 s */
DBGPRINT(RT_DEBUG_ERROR, ("CNTL - Nr= %d. Channel = %d. BSSID not found. %02x:%02x:%02x:%02x:%02x:%02x.\n", pAd->ScanTab.BssNr, pAd->MlmeAux.Channel /*pAd->StaCfg.WscControl.WscAPChannel*/, PRINT_MAC(pP2PCtrl->Bssid)));
DBGPRINT(RT_DEBUG_ERROR, ("CNTL - BSSID not found. Goback to %s \n", decodeP2PState(pP2PCtrl->P2PConnectState)));
return;
}
else if (pAd->ScanTab.BssEntry[BssIdx].SsidLen < 9)
{
pP2PCtrl->P2PConnectState = P2P_DO_GO_SCAN_BEGIN;
pP2PCtrl->P2pCounter.Counter100ms = 0;
pP2PCtrl->P2pCounter.NextScanRound = 5; /* start scan after 500ms */
DBGPRINT(RT_DEBUG_ERROR, ("CNTL -Nr= %d. Channel = %d. SSID is %c%c%c%c%c%c \n", pAd->ScanTab.BssNr, pAd->MlmeAux.Channel /*pAd->StaCfg.WscControl.WscAPChannel*/, pAd->P2pCfg.SSID[0], pAd->P2pCfg.Bssid[1],pAd->P2pCfg.SSID[2],pAd->P2pCfg.SSID[3],pAd->P2pCfg.SSID[4],pAd->P2pCfg.SSID[5]));
DBGPRINT(RT_DEBUG_ERROR, ("CNTL - Goback to %s \n", decodeP2PState(pAd->P2pCfg.P2PConnectState)));
return;
}
/* Now copy the scanned SSID to my CommonCfg.Ssid */
RTMPMoveMemory(pP2PCtrl->PortCfg.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid,32);
pP2PCtrl->PortCfg.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
DBGPRINT(RT_DEBUG_ERROR, ("P2P P2pPeriodicExec P2P_DO_GO_SCAN_DONE. Find BssIdx = %ld\n", BssIdx));
DBGPRINT(RT_DEBUG_ERROR, ("Change P2PConnectState[%s -> %s]\n", decodeP2PState(pP2PCtrl->P2PConnectState), decodeP2PState(P2P_DO_WPS_ENROLLEE)));
pP2PCtrl->P2PConnectState = P2P_DO_WPS_ENROLLEE;
}
/* <<==================================== */
P2pGroupMaintain(pAd);
/* P2P_ANY_IN_FORMATION_AS_GO means I am AutoGO. AutoGo also need to do scan. So don't return here. */
if (IS_P2P_CONNECTING(pAd) && (pP2PCtrl->P2PConnectState != P2P_ANY_IN_FORMATION_AS_GO))
{
return;
}
/* <<==================================== */
/* Maintain listen state when in Concurrent mode. STA+P2P
check if need to resume NoA Schedule. */
}
BOOLEAN P2pResetNoATimer(
IN PRTMP_ADAPTER pAd,
IN ULONG DiffTimeInus)
{
ULONG GPDiff;
/*ULONG Value;*/
BOOLEAN brc = FALSE;
/*
Software based timer means don't use GP interrupt to get precise timer calculation.
So need to check time offset caused by software timer.
*/
if (IS_SW_NOA_TIMER(pAd))
{
GPDiff = (DiffTimeInus>>10) & 0xffff;
if (GPDiff > 0)
{
GPDiff++;
RTMPSetTimer(&pAd->P2pCfg.P2pSwNoATimer, GPDiff);
/* Increase timer tick counter. */
pAd->P2pCfg.GONoASchedule.SwTimerTickCounter++;
brc = TRUE;
/* Will go to awake later. Set a pre-enter-absence timer that the time out is smaller the GPDiff. */
if (pAd->P2pCfg.GONoASchedule.bInAwake == FALSE)
{
if (GPDiff > 10)
{
RTMPSetTimer(&pAd->P2pCfg.P2pPreAbsenTimer, (GPDiff - 10));
}
}
}
}
else
{
brc = P2pSetGP(pAd, DiffTimeInus);
}
return brc;
}
/*
==========================================================================
Description:
Start P2P Search State
Parameters:
Note:
==========================================================================
*/
VOID P2pScan(
IN PRTMP_ADAPTER pAd)
{
BOOLEAN Cancelled;
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
{
/* Stop Scan and resume */
RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
pAd->MlmeAux.Channel = 0;
ScanNextChannel(pAd, OPMODE_STA);
}
P2pGotoIdle(pAd);
P2pGroupTabInit(pAd);
P2PInitDevDiscTimer(pAd, 0);
P2PInitNextScanTimer(pAd, 0);
/* Set P2P Device Discovery Timer */
P2PSetDevDiscTimer(pAd, 0);
P2PSetNextScanTimer(pAd, 10);
}
/*
==========================================================================
Description:
Stop connect command to connect with current MAC becuase the connect process already bagan.
Parameters:
Note:
==========================================================================
*/
VOID P2pStopConnectThis(
IN PRTMP_ADAPTER pAd)
{
RTMPZeroMemory(&pAd->P2pCfg.ConnectingMAC[0], MAC_ADDR_LEN);
}
/*
==========================================================================
Description:
Set parameter stop P2P Search State when P2P has started Group Formation.
Parameters:
Note:
==========================================================================
*/
VOID P2pStopScan(
IN PRTMP_ADAPTER pAd)
{
BOOLEAN Cancelled;
DBGPRINT(RT_DEBUG_INFO, ("<---- P2P - P2pStopScan @channel = %d.\n", pAd->MlmeAux.Channel));
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
{
/* Stop Scan and resume */
RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
pAd->MlmeAux.Channel = 0;
ScanNextChannel(pAd, OPMODE_STA);
}
/* Set scan channel to Last one to stop Scan Phase. Because SCannextchannel will use channel to judge if it should stop scan. */
P2PInitDevDiscTimer(pAd, 0);
P2PInitListenTimer(pAd, 0);
P2PInitNextScanTimer(pAd, 0);
P2pGotoIdle(pAd);
/* update P2P Ctrl State Machine status. */
MlmeEnqueue(pAd, P2P_CTRL_STATE_MACHINE, P2P_CTRL_DISC_CANL_EVT, 0, NULL, 0);
RTMP_MLME_HANDLER(pAd);
DBGPRINT(RT_DEBUG_INFO, ("----> P2P - P2pStopScan @channel = %d.\n", pAd->MlmeAux.Channel));
}
/*
==========================================================================
Description:
Goto Idle state. Update necessary parameters.
Parameters:
Note:
==========================================================================
*/
VOID P2pGotoIdle(
IN PRTMP_ADAPTER pAd)
{
/* pAd->P2pCfg.P2PDiscoProvState = P2P_ENABLE_LISTEN_ONLY; */
pAd->P2pCfg.P2pCounter.Counter100ms = 0;
/* Set a randon period to start next Listen State. */
/* pAd->P2pCfg.P2pCounter.NextScanRound = (RandomByte(pAd) % P2P_RANDOM_BASE) + P2P_RANDOM_BIAS; */
pAd->P2pCfg.CtrlCurrentState = P2P_CTRL_IDLE;
pAd->P2pCfg.DiscCurrentState = P2P_DISC_IDLE;
pAd->P2pCfg.GoFormCurrentState = P2P_GO_FORM_IDLE;
}
/*
==========================================================================
Description:
Goto Scan/Search state. Update necessary parameters.
Parameters:
Note:
==========================================================================
*/
VOID P2pGotoScan(
IN PRTMP_ADAPTER pAd)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
/* Reset 100ms Counter to zero. */
pAd->P2pCfg.P2pCounter.Counter100ms = 0;
/* Set a short time to start next search State for the 1st time. */
pAd->P2pCfg.P2pCounter.NextScanRound = 5;
DBGPRINT(RT_DEBUG_ERROR, ("P2pGotoScan! Set pP2PCtrl->NextScanRound = %ld Here!!!\n", pP2PCtrl->P2pCounter.NextScanRound));
}
/*
==========================================================================
Description:
When I am GO, start a P2P NoA schedule.
Parameters:
S - pointer to the association state machine
Note:
The state machine looks like the following as name implies its function
==========================================================================
*/
VOID P2pGOStartNoA(
IN PRTMP_ADAPTER pAd)
{
ULONG Value;
ULONG TimeTillTbtt;
ULONG temp;
pAd->P2pCfg.GONoASchedule.Token++;
pAd->P2pCfg.GONoASchedule.bValid = TRUE;
/* Start Time */
RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &pAd->P2pCfg.GONoASchedule.TsfHighByte);
DBGPRINT(RT_DEBUG_TRACE,("P2pGOStartNoA parameter.!!!!HighByte = %lx \n", pAd->P2pCfg.GONoASchedule.TsfHighByte));
RTMP_IO_READ32(pAd, TBTT_TIMER, &TimeTillTbtt);
TimeTillTbtt = TimeTillTbtt&0x1ffff;
DBGPRINT(RT_DEBUG_TRACE,(" .!!!!TimeTillTbtt = %ld \n", TimeTillTbtt));
RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &Value);
DBGPRINT(RT_DEBUG_TRACE,(" .!!!!Current Tsf LSB = = %ld \n", Value));
temp = TimeTillTbtt*64+Value;
DBGPRINT(RT_DEBUG_TRACE,(" .!!!!Tsf LSB + TimeTillTbtt= %ld \n", temp));
/* Wait five beacon 0x7d00 for 5 beacon interval. 0x6400 is set to 25%*beacon interval */
pAd->P2pCfg.GONoASchedule.StartTime = Value + TimeTillTbtt*64 + 512000 + 25600;
pAd->P2pCfg.GONoASchedule.NextTargetTimePoint = Value + TimeTillTbtt*64 + 512000 + 25600 + pAd->P2pCfg.GONoASchedule.Duration;
pAd->P2pCfg.GONoASchedule.ThreToWrapAround = pAd->P2pCfg.GONoASchedule.StartTime + 0x7fffffff;
P2pSetGP(pAd, (TimeTillTbtt*64 + 512000 + 25600));
temp = Value + TimeTillTbtt*64 + 0x7D000 + 0x6400;
DBGPRINT(RT_DEBUG_TRACE,(" .!!!!Expect Starttime= %ld. ThreToWrapAround = %ld. \n", temp, pAd->P2pCfg.GONoASchedule.ThreToWrapAround));
temp = temp - Value;
DBGPRINT(RT_DEBUG_TRACE,(" .!!!!more = %ld to start time \n", temp));
pAd->P2pCfg.GONoASchedule.bInAwake = TRUE;
}
VOID P2pStopNoA(
IN PRTMP_ADAPTER pAd,
IN PMAC_TABLE_ENTRY pMacClient)
{
ULONG Value;
BOOLEAN Cancelled;
DBGPRINT(RT_DEBUG_TRACE,("P2pStopNoA.!!!! \n"));
RTMPCancelTimer(&pAd->P2pCfg.P2pPreAbsenTimer, &Cancelled);
pAd->P2pCfg.bKeepSlient = FALSE;
pAd->P2pCfg.bPreKeepSlient = FALSE;
if (pMacClient != NULL)
{
pMacClient->P2pInfo.NoADesc[0].Count = 0xf3;
pMacClient->P2pInfo.NoADesc[0].bValid = FALSE;
pMacClient->P2pInfo.NoADesc[0].bInAwake = TRUE;
/*
Try set Token to a value that has smallest chane the same as the Next Token GO will use.
So decrease 1
*/
pMacClient->P2pInfo.NoADesc[0].Token--;
}
RTMPCancelTimer(&pAd->P2pCfg.P2pSwNoATimer, &Cancelled);
pAd->P2pCfg.GONoASchedule.bValid = FALSE;
pAd->P2pCfg.GONoASchedule.bInAwake = TRUE;
pAd->P2pCfg.GONoASchedule.bWMMPSInAbsent = FALSE; /* Set to FALSE if changes state to Awake */
/* If need not resume NoA. Can reset all parameters. */
if (pAd->P2pCfg.GONoASchedule.bNeedResumeNoA == FALSE)
{
pAd->P2pCfg.GONoASchedule.Count = 1;
pAd->P2pCfg.GONoASchedule.Duration = 0xc800;
pAd->P2pCfg.GONoASchedule.Interval = 0x19000;
}
RTMP_IO_READ32(pAd, INT_TIMER_EN, &Value);
Value &= (0xfffffffd);
RTMP_IO_WRITE32(pAd, INT_TIMER_EN, Value);
pAd->P2pCfg.GONoASchedule.SwTimerTickCounter = 0;
/* Set to false again. */
pAd->P2pCfg.bPreKeepSlient = FALSE;
}
VOID P2pStartOpPS(
IN PRTMP_ADAPTER pAd)
{
if (pAd->P2pCfg.GONoASchedule.bValid == TRUE)
P2pStopNoA(pAd, NULL);
DBGPRINT(RT_DEBUG_TRACE,("P2P : !! P2pStartOpPS \n"));
pAd->P2pCfg.CTWindows = 0x8a;
/* Wait next beacon period to really start queue packet. */
pAd->P2pCfg.bKeepSlient = FALSE;
}
VOID P2pStopOpPS(
IN PRTMP_ADAPTER pAd)
{
if (pAd->P2pCfg.GONoASchedule.bValid == FALSE)
pAd->P2pCfg.bKeepSlient = FALSE;
if (P2P_TEST_BIT(pAd->P2pCfg.CTWindows, P2P_OPPS_BIT))
pAd->P2pCfg.bFirstTimeCancelOpps = TRUE;
pAd->P2pCfg.CTWindows = 0;
}
/*
==========================================================================
Description:
When I am P2P Client , Handle NoA Attribute.
Parameters:
S - pointer to the association state machine
Note:
The state machine looks like the following as name implies its function
==========================================================================
*/
VOID P2pPreAbsenTimeOut(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3)
{
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
pAd->P2pCfg.bPreKeepSlient = TRUE;
}
/*
==========================================================================
Description:
When I am P2P Client , Handle NoA Attribute.
Parameters:
S - pointer to the association state machine
Note:
The state machine looks like the following as name implies its function
==========================================================================
*/
VOID P2pSwNoATimeOut(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3)
{
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
P2pGPTimeOutHandle(pAd);
}
/*
==========================================================================
Description:
When I am P2P GO / Client , Handle P2P session execute WSC in 30secs.
Parameters:
S - pointer to the association state machine
Note:
The state machine looks like the following as name implies its function
==========================================================================
*/
VOID P2pWscTimeOut(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3)
{
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
BOOLEAN Cancelled;
PRT_P2P_CONFIG pP2pCtrl = &pAd->P2pCfg;
DBGPRINT(RT_DEBUG_ERROR, ("%s:: P2P Execute WSC has expire %dsecs, Stop it!\n", __FUNCTION__, (P2P_WSC_TIMER/1000)));
RTMPCancelTimer(&pP2pCtrl->P2pWscTimer, &Cancelled);
if (P2P_CLI_ON(pAd))
{
#ifdef RTMP_MAC_USB
RTEnqueueInternalCmd(pAd, CMDTHREAD_SET_P2P_LINK_DOWN, NULL, 0);
#endif /* RTMP_MAC_USB */
}
else if (P2P_GO_ON(pAd))
{
UINT32 i, p2pEntryCnt=0;
MAC_TABLE_ENTRY *pEntry;
PWSC_CTRL pWscControl = &pAd->ApCfg.MBSSID[0].WscControl;
for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
{
pEntry = &pAd->MacTab.Content[i];
if (IS_P2P_GO_ENTRY(pEntry) && (pEntry->WpaState == AS_PTKINITDONE))
p2pEntryCnt++;
}
DBGPRINT(RT_DEBUG_ERROR, ("P2pWscTimeOut - Total= %d. p2pEntry = %d.\n", pAd->MacTab.Size, p2pEntryCnt));
if ((p2pEntryCnt == 0) && (pAd->flg_p2p_OpStatusFlags == P2P_GO_UP))
#ifdef RTMP_MAC_USB
RTEnqueueInternalCmd(pAd, CMDTHREAD_SET_P2P_LINK_DOWN, NULL, 0);
#endif /* RTMP_MAC_USB */
}
else
DBGPRINT(RT_DEBUG_ERROR, ("%s:: not P2P GO / CLI on !!\n", __FUNCTION__));
}
VOID P2pReSendTimeOut(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3)
{
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
PRT_P2P_CLIENT_ENTRY pP2pEntry = NULL;
BOOLEAN Cancelled;
PRT_P2P_CONFIG pP2pCtrl = &pAd->P2pCfg;
UCHAR BBPValue = 0;
UCHAR p2pindex = P2P_NOT_FOUND;
ULONG FrameLen;
USHORT ConfigMthd;
DBGPRINT(RT_DEBUG_ERROR, ("%s:: P2P Send to %02x:%02x:%02x:%02x:%02x:%02x\n",
__FUNCTION__, PRINT_MAC(pP2pCtrl->ConnectingMAC)));
pP2pCtrl->bP2pReSendTimerRunning = FALSE;
RTMPCancelTimer(&pP2pCtrl->P2pReSendTimer, &Cancelled);
p2pindex = P2pGroupTabSearch(pAd, pP2pCtrl->ConnectingMAC);
if (p2pindex < MAX_P2P_GROUP_SIZE)
{
pP2pEntry = &pAd->P2pTable.Client[p2pindex];
pP2pEntry->ReTransmitCnt++;
if (pP2pEntry->ReTransmitCnt >= 10)
{
DBGPRINT(RT_DEBUG_ERROR, ("ReTransmitCnt limit! stop connect this p2p device!\n"));
P2pStopConnectThis(pAd);
}
pP2pEntry->GeneralToken++;
switch(pP2pEntry->P2pClientState)
{
case P2PSTATE_SENT_PROVISION_REQ:
if (pP2pCtrl->ConfigMethod == WSC_CONFMET_DISPLAY)
{
DBGPRINT(RT_DEBUG_ERROR, ("Re-Send PROVISION REQ. KEYPAD\n"));
ConfigMthd = WSC_CONFMET_KEYPAD;
}
else if (pP2pCtrl->ConfigMethod == WSC_CONFMET_KEYPAD)
{
DBGPRINT(RT_DEBUG_ERROR, ("Re-Send PROVISION REQ. DISPLAY\n"));
ConfigMthd = WSC_CONFMET_DISPLAY;
}
else if (pP2pCtrl->ConfigMethod == WSC_CONFMET_PBC)
{
DBGPRINT(RT_DEBUG_ERROR, ("Re-Send PROVISION REQ. PBC\n"));
ConfigMthd = WSC_CONFMET_PBC;
}
else
{
DBGPRINT(RT_DEBUG_ERROR, ("Re-Send PROVISION REQ. wrong Config Method(%d)\n",
pP2pCtrl->ConfigMethod));
return;
}
P2PSendProvisionReq(pAd, ConfigMthd, pP2pEntry->GeneralToken, pP2pEntry->addr, &FrameLen);
break;
case P2PSTATE_SENT_GO_NEG_REQ:
DBGPRINT(RT_DEBUG_ERROR, ("Re-Send GO NEGO REQ.\n"));
P2pStartGroupForm(pAd, pP2pCtrl->ConnectingMAC, p2pindex);
break;
case P2PSTATE_SENT_PROVISION_RSP:
if ( pP2pCtrl->bProvAutoRsp == TRUE )
break;
if ( pP2pCtrl->P2pProvUserNotify == 1 )
{
if ( pP2pEntry->ReTransmitCnt < 9 )
{
P2PSendProvisionRsp(pAd, pP2pCtrl->P2pProvConfigMethod, pP2pCtrl->P2pProvToken, pP2pCtrl->ConnectingMAC, &FrameLen);
}
else
{
pP2pCtrl->P2pProvUserNotify = 0;
pP2pCtrl->P2pProvIndex = P2P_NOT_FOUND;
pP2pCtrl->P2pProvUserNotify = FALSE;
pAd->P2pCfg.P2pCounter.UserAccept = 0;
}
}
else
{
if ( pP2pEntry->ReTransmitCnt < 2 )
P2PSendProvisionRsp(pAd, 0, pP2pCtrl->P2pProvToken, pP2pCtrl->ConnectingMAC, &FrameLen);
else
pP2pCtrl->P2pProvUserNotify = 0;
}
break;
default:
DBGPRINT(RT_DEBUG_ERROR, ("ReSendTimeout execute with unknown state - %s\n", decodeP2PClientState(pP2pEntry->P2pClientState)));
}
}
}
VOID P2pCliReConnectTimeOut(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3)
{
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
PRT_P2P_CLIENT_ENTRY pP2pEntry = NULL;
BOOLEAN Cancelled;
PRT_P2P_CONFIG pP2pCtrl = &pAd->P2pCfg;
UCHAR BBPValue = 0;
UCHAR p2pindex = P2P_NOT_FOUND;
ULONG FrameLen;
USHORT ConfigMthd;
DBGPRINT(RT_DEBUG_ERROR, ("%s:: P2P Send to %02x:%02x:%02x:%02x:%02x:%02x\n",
__FUNCTION__, PRINT_MAC(pP2pCtrl->ConnectingMAC)));
pP2pCtrl->bP2pCliReConnectTimerRunning = FALSE;
RTMPCancelTimer(&pP2pCtrl->P2pCliReConnectTimer, &Cancelled);
/* Tear Down the P2P Connection */
P2pLinkDown(pAd, P2P_DISCONNECTED);
}
/*
==========================================================================
Description:
When I am P2P Client , Handle NoA Attribute.
Parameters:
S - pointer to the association state machine
Note:
The state machine looks like the following as name implies its function
==========================================================================
*/
BOOLEAN P2pHandleNoAAttri(
IN PRTMP_ADAPTER pAd,
IN PMAC_TABLE_ENTRY pMacClient,
IN PUCHAR pData)
{
PP2P_NOA_DESC pNoADesc;
ULONG Value, GPDiff;
UCHAR index;
ULONG NoALen;
ULONG StartTime;
if (pMacClient == NULL)
return FALSE;
if ((*pData == SUBID_P2P_NOA))
{
NoALen = *(pData+1);
if (NoALen == 2)
{
pMacClient->P2pInfo.CTWindow = *(pData+4);
if (pMacClient->P2pInfo.NoADesc[0].bValid == TRUE)
P2pStopNoA(pAd, pMacClient);
/*
Copy my GO's CTWindow to P2Pcfg.CTWindow parameters,
Then As Client, I don't need to search for Client when I want to use CTWindow Value.
*/
pAd->P2pCfg.CTWindows = *(pData+4);
return TRUE;
}
index = *(pData+3);
pMacClient->P2pInfo.CTWindow = *(pData+4);
/*
Copy GO's CTWindow to P2Pcfg.CTWindow parameters,
Then As Client, I don't need to search for Client when I want to use CTWindow Value.
*/
pAd->P2pCfg.CTWindows = *(pData+4);
pNoADesc = (PP2P_NOA_DESC)(pData+5);
pMacClient->P2pInfo.NoADesc[0].Count = pNoADesc->Count;
pMacClient->P2pInfo.NoADesc[0].Duration = *(PUINT32)&pNoADesc->Duration[0];
pMacClient->P2pInfo.NoADesc[0].Interval = *(PUINT32)&pNoADesc->Interval[0];
pMacClient->P2pInfo.NoADesc[0].StartTime = *(PUINT32)&pNoADesc->StartTime[0];
StartTime = *(PUINT32)&pNoADesc->StartTime[0];
if (pMacClient->P2pInfo.NoADesc[0].Token == index)
{
/* The same NoA. Doesn't need to set this NoA again. */
return FALSE;
}
DBGPRINT(RT_DEBUG_TRACE,("P2P : !!!NEW NOA Here =[%d, %d] Count = %d. Duration = %ld \n", pMacClient->P2pInfo.NoADesc[0].Token, index, pNoADesc->Count, pMacClient->P2pInfo.NoADesc[0].Duration));
DBGPRINT(RT_DEBUG_TRACE,("P2P : !!!NEW NOA Here = CTWindow = %x \n", pMacClient->P2pInfo.CTWindow));
pMacClient->P2pInfo.NoADesc[0].Token = index;
/*RTMP_IO_FORCE_READ32(pAd, TSF_TIMER_DW0, &Value); */
Value = pAd->P2pCfg.GONoASchedule.LastBeaconTimeStamp;
DBGPRINT(RT_DEBUG_TRACE,("Interval = %ld. StartTime = %ld. TSF timer Register = %ld\n", pMacClient->P2pInfo.NoADesc[0].Interval, pMacClient->P2pInfo.NoADesc[0].StartTime, Value));
if ((pMacClient->P2pInfo.NoADesc[0].Duration <= 0x40) || (pMacClient->P2pInfo.NoADesc[0].Interval <= 0x40))
{
DBGPRINT(RT_DEBUG_TRACE, ("!!!!!Interval or Duration too small. ignore. = %lx return 1\n", Value));
return FALSE;
}
else if ((pMacClient->P2pInfo.NoADesc[0].Duration >= pMacClient->P2pInfo.NoADesc[0].Interval)
&& (pMacClient->P2pInfo.NoADesc[0].Count > 1))
{
DBGPRINT(RT_DEBUG_TRACE, ("!!!!!Duration > Inveral. return 2\n"));
return FALSE;
}
/* if Start time point is in the future. */
pAd->P2pCfg.GONoASchedule.CurrentTargetTimePoint = pMacClient->P2pInfo.NoADesc[0].StartTime;
if (Value < StartTime)
{
GPDiff = pMacClient->P2pInfo.NoADesc[0].StartTime - Value;
pMacClient->P2pInfo.NoADesc[0].NextTargetTimePoint = pMacClient->P2pInfo.NoADesc[0].StartTime + pMacClient->P2pInfo.NoADesc[0].Duration;
pAd->P2pCfg.GONoASchedule.OngoingAwakeTime = pMacClient->P2pInfo.NoADesc[0].NextTargetTimePoint;
pAd->P2pCfg.GONoASchedule.NextTimePointForWMMPSCounting = pMacClient->P2pInfo.NoADesc[0].StartTime;
DBGPRINT(RT_DEBUG_TRACE,("!!!!! GPDiff = %ld = 0x%lx. NextTargetTimePoint = %ld\n", GPDiff, GPDiff, pMacClient->P2pInfo.NoADesc[0].NextTargetTimePoint));
/* try to set General Timer. */
pAd->P2pCfg.GONoASchedule.LastBeaconTimeStamp += GPDiff;
if (P2pResetNoATimer(pAd, GPDiff))
{
DBGPRINT(RT_DEBUG_TRACE,("!!!!!Start NoA 1 GPDiff = %ld \n", GPDiff));
pMacClient->P2pInfo.NoADesc[0].bValid = TRUE;
pMacClient->P2pInfo.NoADesc[0].bInAwake = TRUE;
pMacClient->P2pInfo.NoADesc[0].Token = index;
return TRUE;
}
}
/* else if Start time point is in the past. */
else if (Value >= StartTime)
{
do
{
StartTime += pMacClient->P2pInfo.NoADesc[0].Interval;
if ((StartTime > Value) && ((StartTime-Value) > 0x80))
{
GPDiff = StartTime - Value;
pMacClient->P2pInfo.NoADesc[0].NextTargetTimePoint = StartTime /*+ pMacClient->P2pInfo.NoADesc[0].Interval*/ - pMacClient->P2pInfo.NoADesc[0].Duration;
pAd->P2pCfg.GONoASchedule.OngoingAwakeTime = pMacClient->P2pInfo.NoADesc[0].NextTargetTimePoint;
pAd->P2pCfg.GONoASchedule.LastBeaconTimeStamp += GPDiff;
if (P2pResetNoATimer(pAd, GPDiff))
{
DBGPRINT(RT_DEBUG_TRACE,("!!!!!Start NoA 2 GPDiff = %ld\n", GPDiff));
pMacClient->P2pInfo.NoADesc[0].bValid = TRUE;
pMacClient->P2pInfo.NoADesc[0].bInAwake = TRUE;
pMacClient->P2pInfo.NoADesc[0].Token = index;
return TRUE;
}
}
}while(TRUE);
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("Start time in before ..!!Check \n"));
}
}
return FALSE;
}
BOOLEAN P2pSetGP(
IN PRTMP_ADAPTER pAd,
IN ULONG DiffTimeInus)
{
ULONG GPDiff;
ULONG Value;
GPDiff = (DiffTimeInus/64) & 0xffff;
if (GPDiff > 0)
{
GPDiff = GPDiff<<16;
RTMP_IO_WRITE32(pAd, INT_TIMER_CFG, GPDiff);
RTMP_IO_READ32(pAd, INT_TIMER_EN, &Value);
Value |= 0x2;
RTMP_IO_WRITE32(pAd, INT_TIMER_EN, Value);
return TRUE;
}
return FALSE;
}
BOOLEAN P2pAdjustSwNoATimer(
IN PRTMP_ADAPTER pAd,
IN ULONG CurrentTimeStamp,
IN ULONG NextTimePoint)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
ULONG AwakeDuration, NewStartTime;
UCHAR FakeNoAAttribute[32];
RTMPZeroMemory(FakeNoAAttribute, 32);
AwakeDuration = pP2PCtrl->GONoASchedule.Interval - pP2PCtrl->GONoASchedule.Duration;
if (CurrentTimeStamp < pP2PCtrl->GONoASchedule.CurrentTargetTimePoint)
{
/* If offset is more than 1/4 of duration. */
if ((pP2PCtrl->GONoASchedule.OngoingAwakeTime) >= (AwakeDuration>> 2))
{
DBGPRINT(RT_DEBUG_TRACE,("P2pAdjustSwNoATimer HERE HERE!!!! \n"));
DBGPRINT(RT_DEBUG_TRACE,("OngoingAwakeTime = %ld. CurrentTimeStamp = %ld.!!!! \n", pP2PCtrl->GONoASchedule.OngoingAwakeTime, CurrentTimeStamp));
P2pStopNoA(pAd, &pAd->MacTab.Content[pP2PCtrl->MyGOwcid]);
FakeNoAAttribute[0] = SUBID_P2P_NOA;
NewStartTime = pP2PCtrl->GONoASchedule.StartTime + (pP2PCtrl->GONoASchedule.SwTimerTickCounter - 1)*(pP2PCtrl->GONoASchedule.Interval);
P2PMakeFakeNoATlv(pAd, NewStartTime, &FakeNoAAttribute[0]);
pAd->MacTab.Content[pP2PCtrl->MyGOwcid].P2pInfo.NoADesc[0].Token--;
P2pHandleNoAAttri(pAd, &pAd->MacTab.Content[pP2PCtrl->MyGOwcid], &FakeNoAAttribute[0]);
}
/* Update expected next Current Target Time Point with NextTimePoint */
pP2PCtrl->GONoASchedule.CurrentTargetTimePoint = NextTimePoint;
/* Can immediately dequeue packet because peer already in awake period. */
return TRUE;
}
else
{
/* Update expected next Current Target Time Point with NextTimePoint */
pP2PCtrl->GONoASchedule.CurrentTargetTimePoint = NextTimePoint;
return FALSE;
}
}
VOID P2pGPTimeOutHandle(
IN PRTMP_ADAPTER pAd)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
MAC_TABLE_ENTRY *pEntry;
ULONG MacValue;
ULONG Value;
ULONG GPDiff;
ULONG NextDiff;
ULONG SavedNextTargetTimePoint;
RTMP_IO_READ32(pAd, INT_TIMER_EN, &Value);
Value &= 0xfffffffd;
RTMP_IO_WRITE32(pAd, INT_TIMER_EN, Value);
/* GO operating or Autonomous GO */
if (P2P_GO_ON(pAd))
{
if (pP2PCtrl->GONoASchedule.bValid == TRUE)
{
if ((pP2PCtrl->GONoASchedule.Count > 0) && (pP2PCtrl->GONoASchedule.Count < 255))
{
/*
Sometimes go to awake, sometime go to silence. Two state counts One count down.
so only minus Count when I change from Sleep to Awake
*/
if (pP2PCtrl->GONoASchedule.bInAwake == FALSE)
pP2PCtrl->GONoASchedule.Count--;
}
if (pP2PCtrl->GONoASchedule.Count == 0)
{
P2pStopNoA(pAd, NULL);
DBGPRINT(RT_DEBUG_TRACE,("P2pGPTimeOutHandle.!!StopGP. return.1 \n"));
return;
}
if (pP2PCtrl->GONoASchedule.bInAwake == TRUE)
NextDiff = pP2PCtrl->GONoASchedule.Duration;
else
NextDiff = pP2PCtrl->GONoASchedule.Interval - pP2PCtrl->GONoASchedule.Duration;
/* Prepare next time. */
/*RTMP_IO_FORCE_READ32(pAd, TSF_TIMER_DW0, &Value); */
Value = pAd->P2pCfg.GONoASchedule.LastBeaconTimeStamp;
/* Check whether we should to renew the NoA because at least 2^31 us should update once according to spec. */
if (pP2PCtrl->GONoASchedule.ThreToWrapAround > pP2PCtrl->GONoASchedule.StartTime)
{
if (Value > pP2PCtrl->GONoASchedule.ThreToWrapAround)
{
pP2PCtrl->GONoASchedule.bNeedResumeNoA = TRUE;
P2pStopNoA(pAd, NULL);
DBGPRINT(RT_DEBUG_TRACE,("P2pGPTimeOutHandle.!!StopGP. return.3. will resume.\n"));
return;
}
}
else
{
if ((Value > pP2PCtrl->GONoASchedule.ThreToWrapAround) && (Value < pP2PCtrl->GONoASchedule.StartTime))
{
pP2PCtrl->GONoASchedule.bNeedResumeNoA = TRUE;
P2pStopNoA(pAd, NULL);
DBGPRINT(RT_DEBUG_TRACE,("P2pGPTimeOutHandle.!!StopGP. return.4. will resume. \n"));
return;
}
}
SavedNextTargetTimePoint = pP2PCtrl->GONoASchedule.NextTargetTimePoint;
if (Value <= pP2PCtrl->GONoASchedule.NextTargetTimePoint)
{
GPDiff = pP2PCtrl->GONoASchedule.NextTargetTimePoint - Value;
pP2PCtrl->GONoASchedule.NextTimePointForWMMPSCounting = pP2PCtrl->GONoASchedule.NextTargetTimePoint;
pP2PCtrl->GONoASchedule.NextTargetTimePoint += NextDiff;
P2pResetNoATimer(pAd, GPDiff);
DBGPRINT(RT_DEBUG_INFO,(" NextTargetTimePoint = %ld. \n", pAd->P2pCfg.GONoASchedule.NextTargetTimePoint));
DBGPRINT(RT_DEBUG_INFO,(" Value = %ld. GPDiff = %ld.\n", Value, GPDiff));
}
else
{
/* driver restart NoA due to our GP timer's delay. */
if (pP2PCtrl->GONoASchedule.Count == 255)
{
pP2PCtrl->GONoASchedule.bNeedResumeNoA = TRUE;
DBGPRINT(RT_DEBUG_TRACE,(" Prepare resume NoA. \n"));
}
P2pStopNoA(pAd, NULL);
DBGPRINT(RT_DEBUG_TRACE,("3 NextTargetTimePoint = %ld. \n", pP2PCtrl->GONoASchedule.NextTargetTimePoint));
DBGPRINT(RT_DEBUG_TRACE,(" 3 Value = %ld= 0x%lx NextDiff = %ld.\n", Value, Value, NextDiff));
DBGPRINT(RT_DEBUG_TRACE,("3 P2pGPTimeOutHandle.!!StopGP. return.2 \n"));
return;
}
if (pP2PCtrl->GONoASchedule.bInAwake == TRUE)
{
DBGPRINT(RT_DEBUG_TRACE,(" ----------------------->>> NoA Go to SLEEP \n"));
pP2PCtrl->GONoASchedule.bWMMPSInAbsent = TRUE; /* Set to FALSE if changes state to absent */
pP2PCtrl->bKeepSlient = TRUE;
pP2PCtrl->bPreKeepSlient = TRUE;
pP2PCtrl->GONoASchedule.bInAwake = FALSE;
/* roughly check that if duration > 100ms, we should call Pause beacon. */
if (pP2PCtrl->GONoASchedule.Duration >= 0x19000)
{
P2pPauseBssSync(pAd);
}
}
else
{
DBGPRINT(RT_DEBUG_TRACE,(" NoA Wake UP ----------------------->>> \n"));
pP2PCtrl->GONoASchedule.bInAwake = TRUE;
pP2PCtrl->GONoASchedule.bWMMPSInAbsent = FALSE; /* Set to FALSE if changes state to Awake */
pP2PCtrl->bKeepSlient = FALSE;
pP2PCtrl->bPreKeepSlient = FALSE;
if (pP2PCtrl->GONoASchedule.Duration >= 0x19000)
{
P2pResumeBssSync(pAd);
}
if (IS_SW_NOA_TIMER(pAd)
&& (pP2PCtrl->GONoASchedule.Count > 100))
{
if (TRUE == P2pAdjustSwNoATimer(pAd, Value, SavedNextTargetTimePoint))
{
/*DBGPRINT(RT_DEBUG_TRACE,("SwBasedNoA : Dequeue here. %d\n", pAd->TxSwNoAMgmtQueue.Number));*/
/*RTMPDeQueueNoAMgmtPacket(pAd);*/
RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
}
}
else
{
/*RTMPDeQueueNoAMgmtPacket(pAd);*/
RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
}
}
}
}
else if (P2P_CLI_ON(pAd))
{
if (pP2PCtrl->NoAIndex >= MAX_LEN_OF_MAC_TABLE)
return;
if (pP2PCtrl->NoAIndex != pP2PCtrl->MyGOwcid)
DBGPRINT(RT_DEBUG_TRACE,("P2pGPTimeOutHandle. !bug, please check driver %d. \n", pP2PCtrl->NoAIndex));
pEntry = &pAd->MacTab.Content[pP2PCtrl->NoAIndex];
if (pEntry->P2pInfo.NoADesc[0].bValid == TRUE)
{
if ((pEntry->P2pInfo.NoADesc[0].Count > 0) && (pEntry->P2pInfo.NoADesc[0].Count < 255))
{
/*
Sometimes go to awake, sometime go to silence. Two state counts One count down.
so only minus Count when I change from Sleep to Awake
*/
if (pEntry->P2pInfo.NoADesc[0].bInAwake == FALSE)
pEntry->P2pInfo.NoADesc[0].Count--;
}
if (pEntry->P2pInfo.NoADesc[0].Count == 0)
{
P2pStopNoA(pAd, pEntry);
DBGPRINT(RT_DEBUG_TRACE,("P2pGPTimeOutHandle. Count down to zero!!StopGP. return.1 \n"));
return;
}
/* To enter absence period, stop transmission a little bit earlier to leave HW to clean the queue. */
if (pEntry->P2pInfo.NoADesc[0].bInAwake == FALSE)
NextDiff = pEntry->P2pInfo.NoADesc[0].Duration - 0x200;
else
NextDiff = pEntry->P2pInfo.NoADesc[0].Interval - pEntry->P2pInfo.NoADesc[0].Duration + 0x200;
/* Prepare next time. */
MacValue = 0x333;
/*RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &MacValue); */
MacValue = pAd->P2pCfg.GONoASchedule.LastBeaconTimeStamp;
DBGPRINT(RT_DEBUG_INFO,("2 Tsf Timer = %ld= 0x%lx NextTargetTimePoint = %ld.\n", MacValue, MacValue,pEntry->P2pInfo.NoADesc[0].NextTargetTimePoint));
SavedNextTargetTimePoint = pEntry->P2pInfo.NoADesc[0].NextTargetTimePoint;
if (MacValue <= pEntry->P2pInfo.NoADesc[0].NextTargetTimePoint)
{
GPDiff = pEntry->P2pInfo.NoADesc[0].NextTargetTimePoint - MacValue;
pAd->P2pCfg.GONoASchedule.NextTimePointForWMMPSCounting = pEntry->P2pInfo.NoADesc[0].NextTargetTimePoint;
pEntry->P2pInfo.NoADesc[0].NextTimePointForWMMPSCounting = pEntry->P2pInfo.NoADesc[0].NextTargetTimePoint;
pEntry->P2pInfo.NoADesc[0].NextTargetTimePoint += NextDiff;
P2pResetNoATimer(pAd, GPDiff);
DBGPRINT(RT_DEBUG_INFO,("3 Continue next NOA NextTargetTimePoint = %lx. \n", pEntry->P2pInfo.NoADesc[0].NextTargetTimePoint));
DBGPRINT(RT_DEBUG_INFO,("3 Value = %lx. NextDiff = %lx.\n", MacValue, NextDiff));
}
else
{
P2pStopNoA(pAd, pEntry);
DBGPRINT(RT_DEBUG_TRACE,("4 NOA NextTargetTimePoint = %ld. \n", pEntry->P2pInfo.NoADesc[0].NextTargetTimePoint));
DBGPRINT(RT_DEBUG_TRACE,("4 Value = %ld = 0x%lx. NextDiff = %ld.\n", MacValue, MacValue, NextDiff));
return;
}
if (pEntry->P2pInfo.NoADesc[0].bInAwake == TRUE)
{
pEntry->P2pInfo.NoADesc[0].bInAwake = FALSE;
pP2PCtrl->bKeepSlient = TRUE;
pP2PCtrl->bPreKeepSlient = TRUE;
DBGPRINT(RT_DEBUG_TRACE,("Enter Absence now ======> %d\n", pP2PCtrl->bKeepSlient));
}
else
{
pEntry->P2pInfo.NoADesc[0].bInAwake = TRUE;
pP2PCtrl->bKeepSlient = FALSE;
pP2PCtrl->bPreKeepSlient = FALSE;
if (IS_SW_NOA_TIMER(pAd)
&& (pP2PCtrl->GONoASchedule.Count > 100))
{
if (TRUE == P2pAdjustSwNoATimer(pAd, Value, SavedNextTargetTimePoint))
{
/*DBGPRINT(RT_DEBUG_TRACE,("SwBasedNoA : Dequeue here. %d\n", pAd->TxSwNoAMgmtQueue.Number));*/
/*RTMPDeQueueNoAMgmtPacket(pAd);*/
RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
}
}
else
{
/*RTMPDeQueueNoAMgmtPacket(pAd);*/
RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
}
DBGPRINT(RT_DEBUG_TRACE,("Enter Awake now ======= %d\n", pAd->P2pCfg.bKeepSlient));
}
}
}
}
/*
==========================================================================
Description:
IRQL = DISPATCH_LEVEL
==========================================================================
*/
VOID P2pPauseBssSync(
IN PRTMP_ADAPTER pAd)
{
/*BCN_TIME_CFG_STRUC csr;*/
DBGPRINT(RT_DEBUG_TRACE, ("--->P2pPauseBssSync %s\n", decodeP2PState(pAd->P2pCfg.P2PConnectState)));
AsicDisableSync(pAd);
}
/*
==========================================================================
Description:
IRQL = DISPATCH_LEVEL
==========================================================================
*/
VOID P2pResumeBssSync(
IN PRTMP_ADAPTER pAd)
{
/*BCN_TIME_CFG_STRUC csr;*/
DBGPRINT(RT_DEBUG_TRACE, ("--->P2pResumeBssSync %s\n", decodeP2PState(pAd->P2pCfg.P2PConnectState)));
AsicEnableP2PGoSync(pAd);
}
/*
==========================================================================
Description:
OppPS CTWindows timer.
Parameters:
Note:
==========================================================================
*/
VOID P2PCTWindowTimer(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3)
{
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
PRT_P2P_CONFIG pP2pCtrl = &pAd->P2pCfg;
if (P2P_TEST_BIT(pP2pCtrl->CTWindows, P2P_OPPS_BIT))
pP2pCtrl->bKeepSlient = TRUE;
}
/*
==========================================================================
Description:
Before reinvoke a persistent group, copy persistent parameter to pAd->P2pCfg..
Parameters:
Perstindex : the index for entry in Persistent Table.
Note:
==========================================================================
*/
VOID P2pCopyPerstParmToCfg(
IN PRTMP_ADAPTER pAd,
IN UCHAR Perstindex)
{
}
/*
==========================================================================
Description:
Get Random SSID "DIRECT-xx"
Parameters:
pSSID : output SSID
pSSIDLen : Length of pSSID
Note:
==========================================================================
*/
VOID P2pGetRandomSSID(
IN PRTMP_ADAPTER pAd,
OUT PSTRING pSSID,
OUT PUCHAR pSSIDLen)
{
UCHAR tmp[52];
UCHAR i;
//gen a-z , A-Z tmp array!
for(i=0 ; i < 26 ; i++)
{
tmp[i]='a'+i;
tmp[i+26]='A'+i;
}
NdisMoveMemory(pSSID, "DIRECT-", 7);
pSSID[7] = tmp[RandomByte(pAd)%52];
pSSID[8] = tmp[RandomByte(pAd)%52];
NdisMoveMemory((pSSID + 9), pAd->P2pCfg.DeviceName, pAd->P2pCfg.DeviceNameLen);
(*pSSIDLen) = 9 + pAd->P2pCfg.DeviceNameLen;
}
/*
==========================================================================
Description:
Parameters:
Note:
==========================================================================
*/
VOID P2pSetListenIntBias(
IN PRTMP_ADAPTER pAd,
IN UCHAR Bias)
{
pAd->P2pCfg.P2pCounter.ListenIntervalBias = Bias;
if (INFRA_ON(pAd))
pAd->P2pCfg.P2pCounter.ListenIntervalBias = 1;
}
/*
==========================================================================
Description:
The routine that decide my Rule as GO or Client?
And then do necessary setting : update channel, Bssid, SSID etc.
Parameters:
Note:
==========================================================================
*/
VOID P2pSetRule(
IN PRTMP_ADAPTER pAd,
IN UCHAR Index,
IN PUCHAR PeerBssid,
IN UCHAR PeerGOIntentAttri,
IN UCHAR Channel)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
PRT_P2P_CLIENT_ENTRY pP2pEntry = &pAd->P2pTable.Client[Index];
UCHAR RealIntent;
USHORT PeerWscMethod;
DBGPRINT(RT_DEBUG_TRACE, (" P2pSetRule - Channel = %d. GoIntent = %x\n", Channel, PeerGOIntentAttri));
RealIntent = PeerGOIntentAttri>>1;
if (RealIntent > pP2PCtrl->GoIntentIdx)
{
pP2pEntry->Rule = P2P_IS_GO;
pP2pEntry->GoIntent = RealIntent;
/* Use peer addr as bssid */
RTMPMoveMemory(pP2PCtrl->PortCfg.Bssid, PeerBssid, MAC_ADDR_LEN);
RTMPMoveMemory(pP2PCtrl->Bssid, PeerBssid, MAC_ADDR_LEN);
RTMPMoveMemory(pP2PCtrl->SSID, pP2pEntry->Ssid, 32);
pP2PCtrl->SSIDLen = pP2pEntry->SsidLen;
pP2PCtrl->P2PConnectState = P2P_ANY_IN_FORMATION_AS_CLIENT;
/*
The Operating Channel attribute may be present in the P2P IE.
If Channel is 0, use self configuration.
*/
if (Channel != 0)
pP2PCtrl->GroupOpChannel = Channel;
else
pP2PCtrl->GroupOpChannel = pP2PCtrl->GroupChannel;
#ifdef CONFIG_MULTI_CHANNEL
if (INFRA_ON(pAd) && (!pAd->P2pCfg.bStartP2pConnect) && (pAd->Multi_Channel_Enable == TRUE))
{
pAd->P2pCfg.bStartP2pConnect=TRUE;
RTMPSetTimer(&pAd->Mlme.ConcurrentP2PConnectTimer, (1000*15));
pAd->Mlme.ConcurrentP2PConnectTimerRunning = TRUE;
}
#endif /*CONFIG_MULTI_CHANNEL*/
/* Update My WPS Mode. */
P2P_SetWscRule(pAd, Index, &PeerWscMethod);
DBGPRINT(RT_DEBUG_TRACE, (" P2P - I become Internal Enrollee!! Enrollee. !! GOGOGO\n"));
}
else if (RealIntent < pP2PCtrl->GoIntentIdx)
{
pP2pEntry->Rule = P2P_IS_CLIENT;
pP2pEntry->GoIntent = RealIntent;
/* Use my addr as bssid */
RTMPMoveMemory(pP2PCtrl->Bssid, pP2PCtrl->CurrentAddress, MAC_ADDR_LEN);
RTMPMoveMemory(pP2PCtrl->PortCfg.Bssid, pP2PCtrl->CurrentAddress, MAC_ADDR_LEN);
pP2PCtrl->P2PConnectState = P2P_ANY_IN_FORMATION_AS_GO;
pP2PCtrl->GroupOpChannel = pP2PCtrl->GroupChannel;
/* Update My WPS Config Method. */
P2P_SetWscRule(pAd, Index, &PeerWscMethod);
DBGPRINT(RT_DEBUG_TRACE, (" P2P - MyIntent = %d, PeerIntent = %d\n", pP2PCtrl->GoIntentIdx, RealIntent));
DBGPRINT(RT_DEBUG_TRACE, (" P2P - I become Internal REGISTRA!! REGISTRA. !! GOGOGO\n"));
}
else if (((PeerGOIntentAttri&1) == 1) && (RealIntent == pP2PCtrl->GoIntentIdx))
{
DBGPRINT(RT_DEBUG_ERROR, ("P2pSetRule Peer Tie Breaker bit is On. %x \n", RealIntent));
pP2pEntry->Rule = P2P_IS_GO;
pP2pEntry->GoIntent = RealIntent;
/* Use peer addr as bssid */
RTMPMoveMemory(pP2PCtrl->PortCfg.Bssid, PeerBssid, MAC_ADDR_LEN);
RTMPMoveMemory(pP2PCtrl->Bssid, PeerBssid, MAC_ADDR_LEN);
RTMPMoveMemory(pP2PCtrl->SSID, pP2pEntry->Ssid, 32);
pP2PCtrl->SSIDLen = pP2pEntry->SsidLen;
pP2PCtrl->P2PConnectState = P2P_ANY_IN_FORMATION_AS_CLIENT;
/*
The Operating Channel attribute may be present in the P2P IE.
If Channel is 0, use self configuration.
*/
if (Channel != 0)
pP2PCtrl->GroupOpChannel = Channel;
else
pP2PCtrl->GroupOpChannel = pP2PCtrl->GroupChannel;
/* Update My WPS Config Method. */
P2P_SetWscRule(pAd, Index, &PeerWscMethod);
DBGPRINT(RT_DEBUG_TRACE, (" P2P - I become Internal Enrollee!! Enrollee. !! GOGOGO\n"));
}
else if (((PeerGOIntentAttri & 0x1) == 0) && (RealIntent == pP2PCtrl->GoIntentIdx))
{
DBGPRINT(RT_DEBUG_TRACE, ("P2pSetRule Peer Tie Breaker bit is Off. %x \n", RealIntent));
pP2pEntry->Rule = P2P_IS_CLIENT;
pP2pEntry->GoIntent = RealIntent;
/* Use my addr as bssid */
RTMPMoveMemory(pP2PCtrl->Bssid, pP2PCtrl->CurrentAddress, MAC_ADDR_LEN);
RTMPMoveMemory(pP2PCtrl->PortCfg.Bssid, pP2PCtrl->CurrentAddress, MAC_ADDR_LEN);
pP2PCtrl->P2PConnectState = P2P_ANY_IN_FORMATION_AS_GO;
pP2PCtrl->GroupOpChannel = pP2PCtrl->GroupChannel;
/* Update My WPS Config Method. */
P2P_SetWscRule(pAd, Index, &PeerWscMethod);
DBGPRINT(RT_DEBUG_TRACE, (" P2P - I become Internal REGISTRA!! REGISTRA. !! GOGOGO\n"));
}
/* Fix reply GO-Neg-Confirm too late (over 100ms) issue, change the following debug level to TRACE */
DBGPRINT(RT_DEBUG_TRACE, ("P2pSetRule pPort Bssid = %02x %02x %02x %02x %02x %02x \n", pP2PCtrl->PortCfg.Bssid[0], pP2PCtrl->PortCfg.Bssid[1],pP2PCtrl->PortCfg.Bssid[2],pP2PCtrl->PortCfg.Bssid[3],pP2PCtrl->PortCfg.Bssid[4],pP2PCtrl->PortCfg.Bssid[5]));
DBGPRINT(RT_DEBUG_TRACE, ("GroupOpChannel = %d \n",pP2PCtrl->GroupOpChannel));
DBGPRINT(RT_DEBUG_TRACE, (" P2pSetRule - pP2pEntry->Rule = %s. \n", decodeMyRule(pP2pEntry->Rule)));
}
/*
==========================================================================
Description:
Start Provisionint process. Send out Provision Discovery Request frame.
Parameters:
Note:
==========================================================================
*/
BOOLEAN P2pProvision(
IN PRTMP_ADAPTER pAd,
IN PUCHAR Addr)
{
UCHAR p2pindex, Channel;
DBGPRINT(RT_DEBUG_ERROR, ("P2pProvision = %02x:%02x:%02x:%02x:%02x:%02x. \n", PRINT_MAC(Addr)));
p2pindex = P2pGroupTabSearch(pAd, Addr);
if (p2pindex < MAX_P2P_GROUP_SIZE)
{
DBGPRINT(RT_DEBUG_TRACE, ("Start P2pProvision = %02x:%02x:%02x:%02x:%02x:%02x. \n", PRINT_MAC(Addr)));
pAd->P2pTable.Client[p2pindex].GeneralToken++;
pAd->P2pTable.Client[p2pindex].P2pClientState = P2PSTATE_PROVISION_COMMAND;
/* Stop Scan and switch to peer's Listen Channel. */
P2pStopScan(pAd);
Channel = pAd->P2pTable.Client[p2pindex].ListenChannel;
AsicSwitchChannel(pAd, Channel, FALSE);
AsicLockChannel(pAd, Channel);
pAd->P2pCfg.DiscCurrentState = P2P_DISC_SEARCH;
COPY_MAC_ADDR(pAd->P2pCfg.ConnectingMAC, pAd->P2pTable.Client[p2pindex].addr);
return TRUE;
}
return FALSE;
}
/*
==========================================================================
Description:
Connect to Addr. Include all "Connect" cenario. GO_nego, invite, etc. Addr might be P2P GO, or a P2P Device.
Parameters:
Note:
==========================================================================
*/
BOOLEAN P2pConnect(
IN PRTMP_ADAPTER pAd)
{
UCHAR Channel, p2pIdx;
/* Stop Scan and switch to peer's Listen Channel. */
P2pStopScan(pAd);
p2pIdx = P2pGroupTabSearch(pAd, pAd->P2pCfg.ConnectingMAC);
if (p2pIdx >= MAX_P2P_GROUP_SIZE)
return FALSE;
Channel = pAd->P2pTable.Client[p2pIdx].ListenChannel;
if (Channel == 0)
Channel = 1;
AsicSwitchChannel(pAd, Channel, FALSE);
AsicLockChannel(pAd, Channel);
pAd->P2pCfg.DiscCurrentState = P2P_DISC_SEARCH;
DBGPRINT(RT_DEBUG_ERROR, ("P2pConnect = \n"));
DBGPRINT(RT_DEBUG_ERROR, ("Addr = %02x:%02x:%02x:%02x:%02x:%02x. \n", PRINT_MAC(pAd->P2pCfg.ConnectingMAC)));
DBGPRINT(RT_DEBUG_ERROR, ("ListenChannel = %d\n", Channel));
return TRUE;
}
VOID P2pConnectPrepare(
IN PRTMP_ADAPTER pAd,
IN PUCHAR Addr,
IN UINT32 ConnType)
{
UCHAR Channel, p2pindex;
p2pindex = P2pGroupTabSearch(pAd, Addr);
if (p2pindex < MAX_P2P_GROUP_SIZE)
{
#ifdef CONFIG_MULTI_CHANNEL
if (INFRA_ON(pAd) && (pAd->Multi_Channel_Enable == TRUE))
{
pAd->P2pCfg.bStartP2pConnect=TRUE;
RTMPSetTimer(&pAd->Mlme.ConcurrentP2PConnectTimer, (1000*15));
pAd->Mlme.ConcurrentP2PConnectTimerRunning = TRUE;
}
#endif /*CONFIG_MULTI_CHANNEL*/
pAd->P2pCfg.bConfirmByUI = TRUE;
/* Stop Scan and switch to peer's Listen Channel. */
P2pStopScan(pAd);
OS_WAIT(200);
pAd->P2pCfg.bPeriodicListen = FALSE;
if ((pAd->P2pTable.Client[p2pindex].P2pClientState == P2PSTATE_DISCOVERY_GO))
Channel = pAd->P2pTable.Client[p2pindex].OpChannel;
else
Channel = pAd->P2pTable.Client[p2pindex].ListenChannel;
#ifdef CONFIG_MULTI_CHANNEL
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
(INFRA_ON(pAd))
&&(pAd->CommonCfg.Channel == pAd->LatchRfRegs.Channel ||
pAd->CommonCfg.CentralChannel == pAd->LatchRfRegs.Channel))
{
RTMPSendNullFrame(pAd,
pAd->CommonCfg.TxRate,
(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE),
PWR_SAVE);
OS_WAIT(200);
DBGPRINT(RT_DEBUG_TRACE, ("P2pConnectPrepare():Send PWA NullData frame to notify the associated AP!\n"));
}
#endif /*CONFIG_MULTI_CHANNEL*/
if (INFRA_ON(pAd) || P2P_GO_ON(pAd))
{
if (pAd->CommonCfg.BBPCurrentBW == BW_40)
rtmp_bbp_set_bw(pAd, BW_20);
}
AsicSwitchChannel(pAd, Channel, FALSE);
AsicLockChannel(pAd, Channel);
/* Copy pEntry MAC Address in ConnectinfMAC. */
pAd->P2pCfg.ConnectingIndex = 0;
COPY_MAC_ADDR(pAd->P2pCfg.ConnectingMAC, pAd->P2pTable.Client[p2pindex].addr);
/* Set Connecting Timer for Periodic Timer use. */
pAd->P2pTable.Client[p2pindex].StateCount = 0;
pAd->P2pTable.Client[p2pindex].bValid = TRUE;
/* Set pEntry Client Status. */
if ((pAd->P2pTable.Client[p2pindex].P2pClientState == P2PSTATE_DISCOVERY_GO))
{
COPY_MAC_ADDR(pAd->P2pCfg.ConnectingMAC, pAd->P2pTable.Client[p2pindex].bssid);
pAd->P2pTable.Client[p2pindex].P2pClientState = P2PSTATE_PROVISION_COMMAND;
}
else
pAd->P2pTable.Client[p2pindex].P2pClientState = ConnType;
DBGPRINT(RT_DEBUG_ERROR, ("P2P Connect Command Type = %s\n", decodeP2PClientState(ConnType)));
P2PPrintP2PEntry(pAd, p2pindex);
/* Change Discovery State Machine State. */
pAd->P2pCfg.DiscCurrentState = P2P_DISC_SEARCH;
pAd->P2pCfg.GoFormCurrentState = P2P_GO_FORM_IDLE;
}
}
/*
==========================================================================
Description:
Ready to connect to Addr. Include all "Connect" cenario. GO_nego, invite, etc. Addr might be P2P GO, or a P2P Device.
Parameters:
Note:
==========================================================================
*/
BOOLEAN P2pConnectAfterScan(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN bBeacon,
IN UCHAR idx)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
BOOLEAN brc = TRUE;
UCHAR index;/*, i; */
UCHAR GrpIndex = idx;
BOOLEAN bAction = FALSE;
DBGPRINT(RT_DEBUG_ERROR, (" P2pConnectAfterScan %d. %s \n", pAd->P2pTable.Client[idx].P2pClientState, decodeP2PClientState(pAd->P2pTable.Client[idx].P2pClientState)));
DBGPRINT(RT_DEBUG_ERROR, (" GroupOpChannel = %d \n", pP2PCtrl->GroupOpChannel));
if (GrpIndex >= MAX_P2P_GROUP_SIZE)
{
DBGPRINT(RT_DEBUG_TRACE, ("P2pConnectAfterScan Check - Reach Device Limit. return. \n"));
return FALSE;
}
/*
peer is a P2P GO.
Peer is a P2P Device. Need to have Go Nego procedure first.
Or can reinvoke a persistent
*/
if (pAd->P2pTable.Client[GrpIndex].P2pClientState == P2PSTATE_DISCOVERY)
{
/* Decide connect method when I am in Connect_Idle state. This means I am a P2P Device. */
if (P2P_CLI_ON(pAd) || (P2P_GO_ON(pAd)))
{
/* Invite Case 1 */
pAd->P2pTable.Client[GrpIndex].P2pClientState = P2PSTATE_INVITE_COMMAND;
DBGPRINT(RT_DEBUG_TRACE, (" P2pConnectAfterScan - Use Invite %d.\n", GrpIndex));
bAction = TRUE;
}
else if (IS_P2P_CONNECT_IDLE(pAd))
{
index = P2pPerstTabSearch(pAd, pAd->P2pTable.Client[GrpIndex].addr,
pAd->P2pTable.Client[GrpIndex].bssid,
pAd->P2pTable.Client[GrpIndex].InterfaceAddr);
DBGPRINT(RT_DEBUG_ERROR, (" P2pConnectAfterScan - Perst index %d. \n", index));
DBGPRINT(RT_DEBUG_ERROR, (" P2pConnectAfterScan - EnablePresistent %d. \n",
pP2PCtrl->P2pControl.field.EnablePresistent));
if ((index < MAX_P2P_TABLE_SIZE) && IS_PERSISTENT_ON(pAd))
{
/* Invite Case 3: */
pAd->P2pTable.Client[GrpIndex].P2pClientState = P2PSTATE_INVITE_COMMAND;
DBGPRINT(RT_DEBUG_ERROR, (" P2pConnectAfterScan - Use reinvoke Invite %d. \n", index));
bAction = TRUE;
}
else
{
DBGPRINT(RT_DEBUG_TRACE, (" P2pConnectAfterScan - Start From Group Forming \n"));
/* Start Scan and Then go to Group Forming process. */
pAd->P2pTable.Client[idx].P2pClientState = P2PSTATE_CONNECT_COMMAND;
bAction = TRUE;
}
}
if (bAction == TRUE)
{
/* Now only support connect to ONE. So set ConnectingIndex to MAX_P2P_GROUP_SIZE to stop connect further MAC. */
P2pConnectAction(pAd, bBeacon, idx);
}
}
else if ((pAd->P2pTable.Client[GrpIndex].P2pClientState == P2PSTATE_DISCOVERY_GO))
{
DBGPRINT(RT_DEBUG_TRACE, (" case 1 = peer is go \n"));
P2pStopConnectThis(pAd);
brc = P2pConnectP2pGo(pAd, GrpIndex);
}
/* peer is a P2P client in a P2P Group. */
else if ((pAd->P2pTable.Client[GrpIndex].P2pClientState == P2PSTATE_DISCOVERY_CLIENT))
{
DBGPRINT(RT_DEBUG_TRACE, (" case 2 = peer is client \n"));
P2pStopConnectThis(pAd);
P2pConnectP2pClient(pAd,GrpIndex);
}
else
DBGPRINT(RT_DEBUG_TRACE, (" P2pConnectAfterScan - Peer state %s \n",
decodeP2PClientState(pAd->P2pTable.Client[GrpIndex].P2pClientState)));
return brc;
}
/*
==========================================================================
Description:
Prepare to connect to Connecting MAC. ConnectingMAC might contain several MAC address that I can connect to One after one.
Parameters:
Note:
==========================================================================
*/
VOID P2pConnectAction(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN bBeacon,
IN UCHAR index)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
BOOLEAN bresult = FALSE;
UCHAR perstindex;
DBGPRINT(RT_DEBUG_ERROR, (" P2pConnectAction %d. %s \n", pAd->P2pTable.Client[index].P2pClientState, decodeP2PClientState(pAd->P2pTable.Client[index].P2pClientState)));
if (bBeacon == TRUE)
{
DBGPRINT(RT_DEBUG_ERROR, (" P2pConnectAction from bBeacon \n"));
/* Check If ever have a command to connect to this peer. */
if (pAd->P2pTable.Client[index].P2pClientState == P2PSTATE_CONNECT_COMMAND
||(pAd->P2pTable.Client[index].P2pClientState == P2PSTATE_INVITE_COMMAND))
{
pP2PCtrl->P2PConnectState = P2P_ANY_IN_FORMATION_AS_CLIENT;
P2pGoNegoDone(pAd, &pAd->P2pTable.Client[index]);
}
else if (pAd->P2pTable.Client[index].P2pClientState == P2PSTATE_GO_DISCO_COMMAND)
{
bresult = P2pClientDiscovery(pAd, pAd->P2pTable.Client[index].addr, index);
}
}
else
{
DBGPRINT(RT_DEBUG_ERROR, (" P2pConnectAction not from bBeacon \n"));
if ((pAd->P2pTable.Client[index].P2pClientState == P2PSTATE_CONNECT_COMMAND)
|| (pAd->P2pTable.Client[index].P2pClientState == P2PSTATE_INVITE_COMMAND))
{
/* The check sequence must be the same as in where we set P2PSTATE_INVITE_COMMAND in P2PConnect() */
if ((P2P_GO_ON(pAd)) || (P2P_CLI_ON(pAd)))
{
DBGPRINT(RT_DEBUG_TRACE, (" case 1 \n"));
/* Invite Case 1 : I am Auto GO to invite a P2P Device or when I am P2P Client */
bresult = P2pInvite(pAd, pAd->P2pTable.Client[index].addr, MAX_P2P_TABLE_SIZE, index);
}
else if (pAd->P2pTable.Client[index].Rule == P2P_IS_GO)
{
DBGPRINT(RT_DEBUG_TRACE, (" case 2 \n"));
/* directly associate to GO. */
pP2PCtrl->P2PConnectState = P2P_ANY_IN_FORMATION_AS_CLIENT;
P2pGoNegoDone(pAd, &pAd->P2pTable.Client[index]);
}
else if (IS_P2P_CONNECT_IDLE(pAd))
{
UCHAR Channel;
P2P_CMD_STRUCT P2pCmd;
UCHAR ClientState = pAd->P2pTable.Client[index].P2pClientState;
DBGPRINT(RT_DEBUG_ERROR, (" case 3 \n"));
/* since I am idle, */
perstindex = P2pPerstTabSearch(pAd, pAd->P2pTable.Client[index].addr,
pAd->P2pTable.Client[index].bssid,
pAd->P2pTable.Client[index].InterfaceAddr);
if ((perstindex < MAX_P2P_TABLE_SIZE) && (IS_PERSISTENT_ON(pAd)))
{
/*
I have credential, my persistent is enabled, peer 's persistent is enabled.
So use Reinvoke method to start P2P group.
Stop Scan and switch to peer's Listen Channel.
*/
P2pStopScan(pAd);
Channel = pAd->P2pTable.Client[index].ListenChannel;
AsicSwitchChannel(pAd, Channel, FALSE);
AsicLockChannel(pAd, Channel);
ClientState = P2PSTATE_INVITE_COMMAND;
pAd->P2pCfg.P2PConnectState = P2P_CONNECT_IDLE;
}
else
{
ClientState = P2PSTATE_CONNECT_COMMAND;
}
COPY_MAC_ADDR(&P2pCmd.Addr[0], pAd->P2pTable.Client[index].addr);
P2pCmd.Idx = index;
MlmeEnqueue(pAd, P2P_GO_FORM_STATE_MACHINE, P2P_START_COMMUNICATE_CMD_EVT, sizeof(P2P_CMD_STRUCT), &P2pCmd, ClientState);
RTMP_MLME_HANDLER(pAd);
}
else
DBGPRINT(RT_DEBUG_TRACE, (" case 4 ?????? \n"));
if (bresult == TRUE)
{
/* do nothing */
}
}
}
pP2PCtrl->P2pCounter.GoScanBeginCounter100ms = 0;
}
/*
==========================================================================
Description:
Connect to Addr. Addr is already in a P2P Group.
Parameters:
Note:
==========================================================================
*/
VOID P2pConnectP2pClient(
IN PRTMP_ADAPTER pAd,
IN UCHAR GrpIndex)
{
BOOLEAN bGoToScan = FALSE;
UCHAR GoP2pIndex;
DBGPRINT(RT_DEBUG_TRACE, ("P2pConnect to P2pClient====>. \n"));
/* Decide connect method when I am in COnnect_Idle state. This means I am a P2P Device. */
if (IS_P2P_CONNECT_IDLE(pAd))
{
GoP2pIndex = pAd->P2pTable.Client[GrpIndex].MyGOIndex;
if ((pAd->P2pTable.Client[GrpIndex].DevCapability & DEVCAP_CLIENT_DISCOVER) == 0)
{
DBGPRINT(RT_DEBUG_TRACE, ("P2P Client Not support Discoverability %x \n", pAd->P2pTable.Client[GrpIndex].DevCapability));
}
else
DBGPRINT(RT_DEBUG_TRACE, ("P2P Client CAN Support Discoverability %x \n", pAd->P2pTable.Client[GrpIndex].DevCapability));
DBGPRINT(RT_DEBUG_TRACE, ("P2P Client DevCapability %x. GoP2pIndex = %d. \n", pAd->P2pTable.Client[GrpIndex].DevCapability, GoP2pIndex));
if ((GoP2pIndex < MAX_P2P_GROUP_SIZE) && (pAd->P2pTable.Client[GoP2pIndex].P2pClientState == P2PSTATE_DISCOVERY_GO))
{
pAd->P2pTable.Client[GrpIndex].P2pClientState = P2PSTATE_CLIENT_DISCO_COMMAND;
pAd->P2pTable.Client[GoP2pIndex].P2pClientState = P2PSTATE_GO_DISCO_COMMAND;
DBGPRINT(RT_DEBUG_TRACE,("P2P GrpIndex %d . GoP2pIndex = %d\n", GrpIndex, GoP2pIndex));
bGoToScan = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE, (" P2pConnectIdle - peer device's state %s \n", decodeP2PClientState(pAd->P2pTable.Client[GrpIndex].P2pClientState)));
}
if (bGoToScan == TRUE)
{
P2pSetListenIntBias(pAd, 12);
pAd->P2pCfg.P2pCounter.CounterAftrScanButton = 0;
P2pGotoScan(pAd);
}
}
/*
==========================================================================
Description:
Connect to Addr. Addr is already in a P2P Group.
Parameters:
Note:
==========================================================================
*/
BOOLEAN P2pConnectP2pGo(
IN PRTMP_ADAPTER pAd,
IN UCHAR idx)
{
BOOLEAN brc = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("P2pConnectP2pGo. %s\n", decodeP2PState(pAd->P2pCfg.P2PConnectState)));
DBGPRINT(RT_DEBUG_TRACE, ("pAd->P2pCfg.Dpid = %d \n", pAd->P2pCfg.Dpid));
/* Decide connect method when I am in COnnect_Idle state. This means I am a P2P Device. */
if (P2P_GO_ON(pAd))
return brc;
if (pAd->P2pCfg.P2PConnectState == P2P_CONNECT_IDLE)
{
pAd->P2pTable.Client[idx].P2pClientState = P2PSTATE_PROVISION_COMMAND;
DBGPRINT(RT_DEBUG_TRACE,("P2p : Use Provision first before connecting to GO with Bssid %x. %x. %x. %x. %x. %x. \n", pAd->P2pTable.Client[idx].bssid[0], pAd->P2pTable.Client[idx].bssid[1],pAd->P2pTable.Client[idx].bssid[2],pAd->P2pTable.Client[idx].bssid[3],pAd->P2pTable.Client[idx].bssid[4],pAd->P2pTable.Client[idx].bssid[5]));
DBGPRINT(RT_DEBUG_TRACE,("P2p : its GroupCapability= %x. DevCapability= %x. \n", pAd->P2pTable.Client[idx].GroupCapability, pAd->P2pTable.Client[idx].DevCapability));
brc = TRUE;
}
else if (P2P_CLI_ON(pAd))
{
}
else
DBGPRINT(RT_DEBUG_ERROR, ("invalid P2pConnectP2pGo command when %s \n", decodeP2PState(pAd->P2pCfg.P2PConnectState)));
return brc;
}
/*
==========================================================================
Description:
Try to connect to a P2P Client. So Use Client discovery first. CLient Discvoery frame is
forwarded by the help of GO.
Parameters:
P2pTabIdx is GO's index in P2P table.
Note:
==========================================================================
*/
BOOLEAN P2pClientDiscovery(
IN PRTMP_ADAPTER pAd,
IN PUCHAR Addr,
IN UCHAR GoP2pTabIdx)
{
UCHAR ClientP2PIndex = P2P_NOT_FOUND;
UCHAR i;
ULONG TotalFrameLen;
DBGPRINT(RT_DEBUG_ERROR, ("P2pClientDiscovery %d\n", GoP2pTabIdx));
if (GoP2pTabIdx >= MAX_P2P_GROUP_SIZE)
return FALSE;
/* Search what is the P2P client that I was about to ask it's existence. */
for (i = 0; i < MAX_P2P_GROUP_SIZE;i++)
{
if (pAd->P2pTable.Client[i].P2pClientState == P2PSTATE_CLIENT_DISCO_COMMAND)
ClientP2PIndex = i;
}
DBGPRINT(RT_DEBUG_ERROR, ("P2pClientDiscovery. ClientP2PIndex= %d\n", ClientP2PIndex));
if (ClientP2PIndex == P2P_NOT_FOUND)
return FALSE;
P2PSendDevDisReq(pAd, pAd->P2pTable.Client[GoP2pTabIdx].addr, pAd->P2pTable.Client[GoP2pTabIdx].addr, pAd->P2pTable.Client[ClientP2PIndex].addr, &TotalFrameLen);
if (TotalFrameLen > 0)
{
DBGPRINT(RT_DEBUG_ERROR, ("P2pClientDiscovery. ClientP2PIndex = %d\n", ClientP2PIndex));
return TRUE;
}
else
return FALSE;
}
/*
==========================================================================
Description:
Invite can be used for reinvoke persistent entry or just to connect to an P2P client. So
Has 2 index for those choices. Only one is used.
invitation procedure is an optional procedure used for the following :
1. A P2P group owner inviting a P2P Device to become a P2P Client in its P2P Group.
2. A P2P client invitin another P2P Device to join the P2P Group of which the P2P Client is a member
because it wished to use some service of the P2P Device.
3. Requesting to invoke a Persistent P2P Group for which both P2P Devices have previouslt been provisioned.
Parameters:
Note:
==========================================================================
*/
BOOLEAN P2pInviteAsRule(
IN PRTMP_ADAPTER pAd,
IN UCHAR MyRule,
IN UCHAR P2pTabIdx)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
RT_P2P_CLIENT_ENTRY *pClient;
ULONG FrameLen;
/* Reflash this flag on the next Invitation or DPID setting. */
DBGPRINT(RT_DEBUG_TRACE, ("P2pInviteAsRule MyRule = %d. P2pTabIdx= %d \n", MyRule, P2pTabIdx));
pClient = &pAd->P2pTable.Client[P2pTabIdx];
P2PMakeInviteReq(pAd, MyRule, 0, pClient->addr, pP2PCtrl->CurrentAddress, &FrameLen);
DBGPRINT(RT_DEBUG_TRACE, ("P2pInviteAsRule FrameLen = %ld. \n", FrameLen));
if (FrameLen > 0)
return TRUE;
return FALSE;
}
/*
==========================================================================
Description:
Invite can be used for reinvoke persistent entry or just to connect to an P2P client. So
Has 2 index for those choices. Only one is used.
invitation procedure is an optional procedure used for the following :
1. A P2P group owner inviting a P2P Device to become a P2P Client in its P2P Group.
2. A P2P client invitin another P2P Device to join the P2P Group of which the P2P Client is a member
because it wished to use some service of the P2P Device.
3. Requesting to invoke a Persistent P2P Group for which both P2P Devices have previouslt been provisioned.
Parameters:
Note:
==========================================================================
*/
BOOLEAN P2pInvite(
IN PRTMP_ADAPTER pAd,
IN PUCHAR Addr,
IN UCHAR PersistentTabIdx,
IN UCHAR P2pTabIdx)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
RT_P2P_PERSISTENT_ENTRY *pEntry;
RT_P2P_CLIENT_ENTRY *pClient;
/* UCHAR index; */
ULONG FrameLen;
BOOLEAN brc = FALSE;
/* Get one index that is valid to use during invitation procedure. */
if (PersistentTabIdx < MAX_P2P_TABLE_SIZE)
{
/* those who can save to persistent table must also support persistent . So can use invite procedure now. */
pEntry = &pAd->P2pTable.PerstEntry[PersistentTabIdx];
if (P2pTabIdx < MAX_P2P_GROUP_SIZE)
{
pAd->P2pCfg.PhraseKeyLen = (UCHAR)pEntry->Profile.KeyLength;
RTMPMoveMemory(pAd->P2pCfg.PhraseKey, pEntry->Profile.Key, pEntry->Profile.KeyLength);
pClient = &pAd->P2pTable.Client[P2pTabIdx];
RTMPMoveMemory(pAd->P2pCfg.SSID, pEntry->Profile.SSID.Ssid, 32);
pP2PCtrl->SSIDLen = (UCHAR)pEntry->Profile.SSID.SsidLength;
RTMPMoveMemory(pP2PCtrl->SSID, pEntry->Profile.SSID.Ssid, pP2PCtrl->SSIDLen);
if (pEntry->MyRule == P2P_IS_CLIENT)
{
pClient->Rule = P2P_IS_GO;
pClient->P2pClientState = P2PSTATE_GO_WPS;
RTMPMoveMemory(pAd->P2pCfg.Bssid, pEntry->Addr, MAC_ADDR_LEN);
}
else
{
pClient->Rule = P2P_IS_CLIENT;
pClient->P2pClientState = P2PSTATE_CLIENT_WPS;
RTMPMoveMemory(pAd->P2pCfg.Bssid, pAd->CurrentAddress, MAC_ADDR_LEN);
}
P2PMakeInviteReq(pAd, pEntry->MyRule, P2P_INVITE_FLAG_REINVOKE, pEntry->Addr, pP2PCtrl->CurrentAddress, &FrameLen);
if (FrameLen > 0)
{
brc = TRUE;
pClient->P2pClientState = P2PSTATE_SENT_INVITE_REQ;
}
}
}
else if (P2pTabIdx < MAX_P2P_GROUP_SIZE)
{
if ((pAd->P2pTable.Client[P2pTabIdx].DevCapability & DEVCAP_INVITE) == DEVCAP_INVITE)
{
/*if (pP2PCtrl->PortSubtype == PORTSUBTYPE_P2PGO) */
if (P2P_GO_ON(pAd))
{
brc = P2pInviteAsRule(pAd, P2P_IS_GO, P2pTabIdx);
}
else if (P2P_CLI_ON(pAd))
brc = P2pInviteAsRule(pAd, P2P_IS_CLIENT, P2pTabIdx);
}
else
DBGPRINT(RT_DEBUG_TRACE, ("Peer doesn't support Invite. DevCapability = %x \n", pAd->P2pTable.Client[P2pTabIdx].DevCapability));
}
else
DBGPRINT(RT_DEBUG_TRACE, ("invalid P2pInvite command. %d %d \n", PersistentTabIdx, P2pTabIdx));
return brc;
}
/*
==========================================================================
Description:
Start Group Formation Process. will send out Go Negociation Request frame.
Parameters:
Note:
==========================================================================
*/
BOOLEAN P2pStartGroupForm(
IN PRTMP_ADAPTER pAd,
IN PUCHAR Addr,
IN UCHAR idx)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
NDIS_STATUS NStatus;
PUCHAR pOutBuffer = NULL;
ULONG FrameLen = 0;
/* Insert this candidate to p2p client table. */
if (idx < MAX_P2P_GROUP_SIZE)
{
if ((pAd->P2pTable.Client[idx].P2pClientState == P2PSTATE_CONNECT_COMMAND)||
(pAd->P2pTable.Client[idx].P2pClientState == P2PSTATE_DISCOVERY) ||
(pAd->P2pTable.Client[idx].P2pClientState == P2PSTATE_SENT_GO_NEG_REQ))
{
/* Reset Scan Counter to Zero . So Won't do Scan too sooon because group forming is started. */
pAd->P2pCfg.P2pCounter.Counter100ms = 0;
if (IS_EXT_LISTEN_ON(pAd))
{
pAd->P2pCfg.ExtListenInterval = P2P_EXT_LISTEN_INTERVAL;
pAd->P2pCfg.ExtListenPeriod = P2P_EXT_LISTEN_PERIOD;
}
{
pP2PCtrl->P2PConnectState = P2P_ANY_IN_FORMATION_AS_CLIENT;
DBGPRINT(RT_DEBUG_ERROR, ("%s:: Start GroupForm . \n", __FUNCTION__));
/* allocate and send out ProbeRsp frame */
NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); /* Get an unused nonpaged memory */
if (NStatus != NDIS_STATUS_SUCCESS)
return FALSE;
pAd->P2pTable.Client[idx].P2pClientState = P2PSTATE_SENT_GO_NEG_REQ;
pAd->P2pTable.Client[idx].StateCount = 0;
pAd->P2pTable.Client[idx].bValid = FALSE;
/* Set as Client temporarily. Later when I get the GO Rsp, will update this based on correct Intent. */
P2PMakeGoNegoReq(pAd, idx, Addr, pOutBuffer, &FrameLen);
pP2PCtrl->bP2pReSendTimerRunning = TRUE;
RTMPSetTimer(&pP2PCtrl->P2pReSendTimer, P2P_TRANSMIT_TIMER);
MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer);
DBGPRINT(RT_DEBUG_ERROR, (" P2P - Make GO Negociation Req FrameLen = %ld. \n", FrameLen));
}
/* Once dwell in a listen and start group formation process, should stop scan right away. */
return TRUE;
}
}
return FALSE;
}
/*
==========================================================================
Description:
Check if the addr is in my MAC wish list if any.
Parameters:
Note:
==========================================================================
*/
BOOLEAN P2PDeviceMatch(
IN PRTMP_ADAPTER pAd,
IN PUCHAR Addr,
IN PUCHAR DeviceName,
IN ULONG DeviceNameLen)
{
UCHAR i;
UCHAR *ptr;
ptr = &pAd->P2pCfg.ConnectingMAC[0];
return TRUE;
if (NdisEqualMemory(Addr, ZERO_MAC_ADDR, 6))
return FALSE;
/* If didn't assign MAC connecting wish list, allow all and return TRUE. */
if (NdisEqualMemory(pAd->P2pCfg.ConnectingMAC, ZERO_MAC_ADDR, 6))
return TRUE;
for (i = 0;i<MAX_P2P_GROUP_SIZE;i++)
{
if (NdisEqualMemory(Addr, ptr, 6))
return TRUE;
ptr += MAC_ADDR_LEN;
}
DBGPRINT(RT_DEBUG_ERROR, ("P2p : P2PDevice Not Match from %02x:%02x:%02x:%02x:%02x:%02x.. = %s \n", PRINT_MAC(Addr), decodeP2PState(pAd->P2pCfg.P2PConnectState)));
return FALSE;
}
/*
==========================================================================
Description:
Set WPS related parameters
Parameters:
Note:
==========================================================================
*/
VOID P2pSetWps(
IN PRTMP_ADAPTER pAd,
IN PRT_P2P_CLIENT_ENTRY pP2pEntry)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
BOOLEAN bChangeInitBW = FALSE;
PAPCLI_STRUCT pApCliEntry = NULL;
MAC_TABLE_ENTRY *pEntry = NULL;
int i;
DBGPRINT(RT_DEBUG_ERROR, ("%s:: ==> P2P Connect State = %d. %s.\n",
__FUNCTION__, pP2PCtrl->P2PConnectState, decodeP2PState(pP2PCtrl->P2PConnectState)));
#ifdef HE_BD_SUPPORT
/* Store Assoc info */
if (pP2PCtrl->Rule == P2P_IS_GO)
{
if( pP2PCtrl->AssocList.maclist_count < 3)
{
BOOLEAN is_found = FALSE;
int j;
for ( j = 0 ; j < pP2PCtrl->AssocList.maclist_count ; j ++ )
if ( NdisEqualMemory(&pP2PCtrl->AssocList.device_name[j].ssid , pP2pEntry->DeviceName, 32) )
is_found = TRUE;
if ( ! is_found )
{
int i = pP2PCtrl->AssocList.maclist_count;
DBGPRINT(RT_DEBUG_TRACE,("pP2PCtrl->AssocList.maclist_count = %d\n", pP2PCtrl->AssocList.maclist_count));
DBGPRINT(RT_DEBUG_TRACE,("pP2pEntry->InterfaceAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", PRINT_MAC(pP2pEntry->InterfaceAddr)));
DBGPRINT(RT_DEBUG_TRACE,("pP2pEntry->addr = %02X:%02X:%02X:%02X:%02X:%02X\n", PRINT_MAC(pP2pEntry->addr)));
DBGPRINT(RT_DEBUG_TRACE,("pP2pEntry->bssid = %02X:%02X:%02X:%02X:%02X:%02X\n", PRINT_MAC(pP2pEntry->bssid)));
DBGPRINT(RT_DEBUG_TRACE,("pP2pEntry->DeviceName = %s\n", pP2pEntry->DeviceName));
NdisMoveMemory(&pP2PCtrl->AssocList.device_type[i].dev_type, &pP2pEntry->PrimaryDevType, 8);
NdisMoveMemory(&pP2PCtrl->AssocList.maclist[i].octet, &pP2pEntry->InterfaceAddr, MAC_ADDR_LEN);
NdisZeroMemory(&pP2PCtrl->AssocList.device_name[i].ssid, 33);
pP2PCtrl->AssocList.is_p2p[i] = TRUE;
NdisMoveMemory(&pP2PCtrl->AssocList.device_name[i].ssid, &pP2pEntry->DeviceName, pP2pEntry->DeviceNameLen);
pP2PCtrl->AssocList.maclist_count++;
}
}
}
else
{
NdisMoveMemory(&pP2PCtrl->AssocList.device_type[0].dev_type, &pP2pEntry->PrimaryDevType, 8);
NdisMoveMemory(&pP2PCtrl->AssocList.maclist[0].octet, &pP2pEntry->InterfaceAddr, MAC_ADDR_LEN);
NdisZeroMemory(&pP2PCtrl->AssocList.device_name[0].ssid, 33);
//NdisMoveMemory(&pP2PCtrl->AssocList.maclist[0].octet, &pP2PCtrl->SSID, pP2PCtrl->SSIDLen);
NdisMoveMemory(&pP2PCtrl->AssocList.device_name[0].ssid, &pP2PCtrl->SSID, pP2PCtrl->SSIDLen);
pP2PCtrl->AssocList.maclist_count = 1;
}
#endif /* HE_BD_SUPPORT */
P2pStopConnectThis(pAd); /* clean Connecting MAC Address. */
P2pStopScan(pAd);
pObj->ioctl_if_type = INT_P2P;
//pP2PCtrl->bConfirmByUI = FALSE;
if ((pP2PCtrl->Rule == P2P_IS_GO) && (P2P_GO_ON(pAd)))
{
PWSC_CTRL pWscControl = &pAd->ApCfg.MBSSID[0].WscControl;
/* Set Channel. */
DBGPRINT(RT_DEBUG_ERROR, ("(%d, %d)\n", pAd->LatchRfRegs.Channel != pP2PCtrl->GroupChannel));
if (pAd->LatchRfRegs.Channel != pP2PCtrl->GroupChannel)
bChangeInitBW = TRUE;
else
{
pApCliEntry = &pAd->ApCfg.ApCliTab[BSS0];
if (!INFRA_ON(pAd)&& !P2P_GO_ON(pAd) && (pApCliEntry->Valid == FALSE))
bChangeInitBW = TRUE;
else
{
if (INFRA_ON(pAd) || P2P_GO_ON(pAd))
{
if ((pAd->CommonCfg.BBPCurrentBW == BW_40) && (pAd->LatchRfRegs.Channel != pAd->CommonCfg.CentralChannel))
bChangeInitBW = TRUE;
}
}
}
if (bChangeInitBW == TRUE)
{
UCHAR rf_channel;
// TODO: shiang-6590, check this for P2P + STA concurrnet mode!!
if (!INFRA_ON(pAd))
{
pAd->CommonCfg.Channel = pP2PCtrl->GroupOpChannel;
if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)
&& pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
N_SetCenCh(pAd, pAd->CommonCfg.Channel);
rf_channel = pAd->CommonCfg.CentralChannel;
}
else
{
if ((pAd->CommonCfg.Channel != pAd->CommonCfg.CentralChannel) && (pAd->CommonCfg.BBPCurrentBW == BW_40))
rf_channel = pAd->CommonCfg.CentralChannel;
else
rf_channel = pAd->CommonCfg.Channel;
}
// TODO: shiang-6590, check this for BW setting here!!
if (rf_channel != pAd->CommonCfg.Channel)
rtmp_bbp_set_bw(pAd, BW_40);
else
rtmp_bbp_set_bw(pAd, BW_20);
AsicSwitchChannel(pAd, rf_channel, FALSE);
AsicLockChannel(pAd, rf_channel);
}
DBGPRINT(RT_DEBUG_ERROR, ("%s:: Rule = %s. OpChannel = %d. CentralChannel = %d\n",
__FUNCTION__, decodeMyRule(pP2PCtrl->Rule), pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
DBGPRINT(RT_DEBUG_ERROR, (" SSID[%d] = %s. BSSID = %02x:%02x:%02x:%02x:%02x:%02x.\n",
pP2PCtrl->SSIDLen, pP2PCtrl->SSID, PRINT_MAC(pP2PCtrl->CurrentAddress)));
pP2PCtrl->P2pCapability[1] |= GRPCAP_OWNER;
/* P2P GO up. */
if (pWscControl->WscConfStatus == WSC_SCSTATE_CONFIGURED)
{
DBGPRINT(RT_DEBUG_ERROR, ("P2P_FIXED_MODE && WSC_SCSTATE_CONFIGURED\n"));
AsicBBPAdjust(pAd);
}
else
{
Set_P2p_OpMode_Proc(pAd, "1");
}
/* GO WPS trigger. */
if (pP2PCtrl->WscMode == WSC_PIN_MODE)
{
if (pP2PCtrl->ConfigMethod == WSC_CONFMET_KEYPAD)
{
Set_AP_WscConfMode_Proc(pAd, "5"); /* Registrar / Enrollee */
Set_AP_WscMode_Proc(pAd, "1"); /* PIN */
/* note 2011-10-12 : only AutoGO need WscPinCode command */
/*
To use ConfirmByUI flag to block WPS operation,
once UI/wpa_supplicant ready, it will call P2pConnectPrepare to toggle ConfirmByUI
*/
if (pP2PCtrl->bSigmaEnabled == TRUE || pAd->P2pCfg.bConfirmByUI == TRUE) {
if ((!(pAd->flg_p2p_OpStatusFlags & P2P_FIXED_MODE)) ||
(pP2PCtrl->bSigmaEnabled == TRUE))
{
Set_AP_WscPinCode_Proc(pAd, pP2PCtrl->PinCode);
OS_WAIT(700);
}
Set_AP_WscGetConf_Proc(pAd, "1");
DBGPRINT(RT_DEBUG_ERROR, ("%s:: WSC_CONFMET_KEYPAD, bConfirmByUI == TRUE, do further WSC operation!!\n", __func__));
/* Reset bConfirmByUI to its default value */
pP2PCtrl->bConfirmByUI = CONFIRM_BY_UI_DEFAULT;
}
else
DBGPRINT(RT_DEBUG_ERROR, ("%s:: WSC_CONFMET_KEYPAD, bConfirmByUI == FALSE, wait for Upper layer Trigger WSC operation!!\n", __func__));
}
else if (pP2PCtrl->ConfigMethod == WSC_CONFMET_DISPLAY)
{
Set_AP_WscConfMode_Proc(pAd, "5"); /* Registrar / Enrollee */
Set_AP_WscMode_Proc(pAd, "1"); /* PIN */
OS_WAIT(700);
Set_AP_WscGetConf_Proc(pAd, "1");
}
}
else if (pP2PCtrl->WscMode == WSC_PBC_MODE)
{
Set_AP_WscConfMode_Proc(pAd, "5"); /* Registrar / Enrollee */
Set_AP_WscMode_Proc(pAd, "2"); /* PBC */
/*
To use ConfirmByUI flag to block WPS operation,
once UI/wpa_supplicant ready, it will call P2pConnectPrepare to toggle ConfirmByUI
*/
if (pAd->P2pCfg.bConfirmByUI == TRUE) {
OS_WAIT(700);
Set_AP_WscGetConf_Proc(pAd, "1");
DBGPRINT(RT_DEBUG_ERROR, ("%s:: WSC_PBC_MODE, bConfirmByUI == TRUE, do further WSC operation!!\n", __func__));
/* Reset bConfirmByUI to its default value */
pP2PCtrl->bConfirmByUI = CONFIRM_BY_UI_DEFAULT;
}
else
DBGPRINT(RT_DEBUG_ERROR, ("%s:: WSC_PBC_MODE, bConfirmByUI == FALSE, wait for Upper layer Trigger WSC operation!!\n", __func__));
}
RTMPSetTimer(&pAd->P2pCfg.P2pWscTimer, P2P_WSC_TIMER);
}
else if ((pP2PCtrl->Rule == P2P_IS_CLIENT) && (P2P_CLI_ON(pAd)))
{
#ifdef CONFIG_MULTI_CHANNEL
if (!INFRA_ON(pAd))
{
pAd->CommonCfg.Channel = pP2PCtrl->GroupOpChannel;
AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
AsicLockChannel(pAd, pAd->CommonCfg.Channel);
DBGPRINT(RT_DEBUG_ERROR, ("%s:: !INFRA_ON Rule = %s. OpChannel = %d. CentralChannel = %d\n",
__FUNCTION__, decodeMyRule(pP2PCtrl->Rule), pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
DBGPRINT(RT_DEBUG_ERROR, (" SSID[%d] = %s. BSSID = %02x:%02x:%02x:%02x:%02x:%02x.\n",
pP2PCtrl->SSIDLen, pP2PCtrl->SSID, PRINT_MAC(pP2PCtrl->Bssid)));
}
else
{
pAd->ApCliMlmeAux.Channel = pP2PCtrl->GroupOpChannel;
/*N_SetCenCh(pAd); */
AsicSwitchChannel(pAd, pAd->ApCliMlmeAux.Channel , FALSE);
AsicLockChannel(pAd, pAd->ApCliMlmeAux.Channel );
DBGPRINT(RT_DEBUG_ERROR, ("%s:: INFRA_ON Rule = %s. OpChannel = %d. CentralChannel = %d\n",
__FUNCTION__, decodeMyRule(pP2PCtrl->Rule), pAd->ApCliMlmeAux.Channel , pAd->ApCliMlmeAux.CentralChannel));
DBGPRINT(RT_DEBUG_ERROR, (" SSID[%d] = %s. BSSID = %02x:%02x:%02x:%02x:%02x:%02x.\n",
pP2PCtrl->SSIDLen, pP2PCtrl->SSID, PRINT_MAC(pP2PCtrl->Bssid)));
}
#else
/* Set Channel. */
pAd->CommonCfg.Channel = pP2PCtrl->GroupOpChannel;
AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
AsicLockChannel(pAd, pAd->CommonCfg.Channel);
DBGPRINT(RT_DEBUG_ERROR, ("%s:: Rule = %s. OpChannel = %d. CentralChannel = %d\n",
__FUNCTION__, decodeMyRule(pP2PCtrl->Rule), pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
DBGPRINT(RT_DEBUG_ERROR, (" SSID[%d] = %s. BSSID = %02x:%02x:%02x:%02x:%02x:%02x.\n",
pP2PCtrl->SSIDLen, pP2PCtrl->SSID, PRINT_MAC(pP2PCtrl->Bssid)));
#endif /*CONFIG_MULTI_CHANNEL*/
/* P2P CLIENT up. */
Set_P2p_OpMode_Proc(pAd, "2");
/* P2P AP-Client Enable. */
Set_P2pCli_Enable_Proc(pAd, "1");
/* CLIENT WPS trigger. */
if (pP2PCtrl->WscMode == WSC_PIN_MODE)
{
if (pP2PCtrl->ConfigMethod == WSC_CONFMET_KEYPAD)
{
Set_AP_WscConfMode_Proc(pAd, "1"); /* Enrollee */
Set_AP_WscMode_Proc(pAd, "1"); /* PIN */
Set_P2pCli_WscSsid_Proc(pAd, &pP2PCtrl->SSID[0]);
/* Need Enter PIN Code and trigger WPS. */
/*
To use ConfirmByUI flag to block WPS operation,
once UI/wpa_supplicant ready, it will call P2pConnectPrepare to toggle ConfirmByUI
*/
if (pP2PCtrl->bSigmaEnabled == TRUE || pAd->P2pCfg.bConfirmByUI == TRUE) {
Set_AP_WscPinCode_Proc(pAd, pP2PCtrl->PinCode);
OS_WAIT(700);
Set_AP_WscGetConf_Proc(pAd, "1");
DBGPRINT(RT_DEBUG_ERROR, ("%s:: WSC_CONFMET_KEYPAD, bConfirmByUI == TRUE, do further WSC operation!!\n", __func__));
/* Reset bConfirmByUI to its default value */
pP2PCtrl->bConfirmByUI = CONFIRM_BY_UI_DEFAULT;
}
else
DBGPRINT(RT_DEBUG_ERROR, ("%s:: WSC_CONFMET_KEYPAD, bConfirmByUI == FALSE, wait for Upper layer Trigger WSC operation!!\n", __func__));
}
else if (pP2PCtrl->ConfigMethod == WSC_CONFMET_DISPLAY)
{
Set_AP_WscConfMode_Proc(pAd, "1"); /* Enrollee */
Set_AP_WscMode_Proc(pAd, "1"); /* PIN */
Set_P2pCli_Ssid_Proc(pAd, &pP2PCtrl->SSID[0]);
Set_AP_WscGetConf_Proc(pAd, "1");
}
/*COPY_MAC_ADDR(pAd->ApCfg.ApCliTab[0].CfgApCliBssid, pP2PCtrl->Bssid);*/
}
else if (pP2PCtrl->WscMode == WSC_PBC_MODE)
{
Set_AP_WscConfMode_Proc(pAd, "1"); /* Enrollee */
Set_AP_WscMode_Proc(pAd, "2"); /* PBC */
Set_P2pCli_WscSsid_Proc(pAd, &pP2PCtrl->SSID[0]);
/*
To use ConfirmByUI flag to block WPS operation,
once UI/wpa_supplicant ready, it will call P2pConnectPrepare to toggle ConfirmByUI
*/
if (pAd->P2pCfg.bConfirmByUI == TRUE) {
OS_WAIT(700);
Set_AP_WscGetConf_Proc(pAd, "1");
DBGPRINT(RT_DEBUG_ERROR, ("%s:: WSC_PBC_MODE, bConfirmByUI == TRUE, do further WSC operation!!\n", __func__));
/* Reset bConfirmByUI to its default value */
pP2PCtrl->bConfirmByUI = CONFIRM_BY_UI_DEFAULT;
}
else
DBGPRINT(RT_DEBUG_ERROR, ("%s:: WSC_PBC_MODE, bConfirmByUI == FALSE, wait for Upper layer Trigger WSC operation!!\n", __func__));
}
RTMPSetTimer(&pAd->P2pCfg.P2pWscTimer, P2P_WSC_TIMER);
}
}
/*
==========================================================================
Description:
Call this function after a successful Go negociation. will do coreessponding action as GO or Client.
Parameters:
Note:
==========================================================================
*/
VOID P2pGoNegoDone(
IN PRTMP_ADAPTER pAd,
IN PRT_P2P_CLIENT_ENTRY pP2pEntry)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
if (pP2PCtrl->P2PConnectState == P2P_ANY_IN_FORMATION_AS_GO)
{
/* Set MyRule in P2P GroupFormat */
pP2PCtrl->Rule = P2P_IS_GO;
pAd->flg_p2p_OpStatusFlags |= P2P_GO_UP;
P2pSetWps(pAd, pP2pEntry);
}
else if (pP2PCtrl->P2PConnectState == P2P_ANY_IN_FORMATION_AS_CLIENT)
{
DBGPRINT(RT_DEBUG_ERROR, ("pAd->P2pCfg.Dpid = %s \n", decodeDpid(pP2PCtrl->Dpid)));
/* Set MyRule in P2P GroupFormat */
pP2PCtrl->Rule = P2P_IS_CLIENT;
pAd->flg_p2p_OpStatusFlags = P2P_CLI_UP;
/* If WPS not triggered, don't so WPS AP now. Wait until P2PPRofile called */
if (pP2PCtrl->Dpid != DEV_PASS_ID_NOSPEC)
{
/* Update Per client state */
pP2pEntry->P2pClientState = P2PSTATE_GO_WPS;
/* Update Global State. Prepare to scan for GO beacon. So as to connect using WPS. */
pP2PCtrl->P2PConnectState = P2P_DO_GO_SCAN_BEGIN;
pP2PCtrl->P2pCounter.Counter100ms = 0;
/* When Counter100ms reaches NextScanRound in P2P_DO_GO_NEG_DONE_CLIENT State, */
/* Will start a site survey again. Because P2P GO start beacon after Go Negociation. */
pP2PCtrl->P2pCounter.NextScanRound = 20 + pP2pEntry->ConfigTimeOut * 10;
/*pAd->StaCfg.WscControl.WscAPChannel = pP2PCtrl->GroupOpChannel; */
DBGPRINT(RT_DEBUG_ERROR, ("P2pGoNegoDone. NextScanRound= %ld\n", pP2PCtrl->P2pCounter.NextScanRound));
DBGPRINT(RT_DEBUG_ERROR, ("2 WscMode = %lx \n", pP2PCtrl->WscMode));
/* Start WPS. */
P2pSetWps(pAd, pP2pEntry);
}
}
else
DBGPRINT(RT_DEBUG_ERROR, ("P2pGoNegoDone- invalid p2pstate = %s\n", decodeP2PState(pP2PCtrl->P2PConnectState)));
}
/*
==========================================================================
Description:
Call this function after a successful WPS provisioning. do coreessponding action as GO or Client.
Parameters:
Note:
==========================================================================
*/
VOID P2pWpsDone(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr)
{
}
VOID P2pLinkDown(
IN PRTMP_ADAPTER pAd,
IN INT32 type)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
INT if_type = pObj->ioctl_if_type;
UCHAR BBPValue = 0;
/*
Android except below format for P2P-GROUP-REMOVE event
P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED
since it need client or GO role content,
so moving send event to here,
to make if (P2P_GO_ON(pAd))/if (P2P_CLI_ON(pAd)) function still work before P2P_GoStop function.
*/
#ifdef RT_P2P_SPECIFIC_WIRELESS_EVENT
if (type == P2P_CONNECT_FAIL)
type = RT_P2P_CONNECT_FAIL;
else if (type == P2P_DISCONNECTED)
type = RT_P2P_DISCONNECTED;
P2pSendWirelessEvent(pAd, type, NULL, NULL);
#endif /* RT_P2P_SPECIFIC_WIRELESS_EVENT */
DBGPRINT(RT_DEBUG_ERROR, ("%s:: ==> P2P Connect State = %d. %s.\n", __FUNCTION__, pP2PCtrl->P2PConnectState, decodeP2PState(pP2PCtrl->P2PConnectState)));
P2pStopConnectThis(pAd); /* clean Connecting MAC Address. */
pP2PCtrl->P2PConnectState = P2P_CONNECT_IDLE;
/*
pP2PCtrl->CtrlCurrentState = P2P_CTRL_IDLE;
pP2PCtrl->DiscCurrentState = P2P_DISC_LISTEN;
pP2PCtrl->GoFormCurrentState = P2P_GO_FORM_IDLE;
*/
P2pStopScan(pAd);
P2pGroupTabInit(pAd);
pP2PCtrl->GoFormCurrentState = P2P_GO_FORM_IDLE;
/* Restore P2P WSC Mode / Config Method */
pP2PCtrl->WscMode = WSC_PIN_MODE; /* PIN */
pP2PCtrl->ConfigMethod = 0x188;
pP2PCtrl->Dpid = DEV_PASS_ID_NOSPEC;
/*MlmeEnqueue(pAd, P2P_DISC_STATE_MACHINE, P2P_DISC_CANL_CMD_EVT, 0, NULL, 0);*/
/* Set bConfirmByUI to default */
pP2PCtrl->bConfirmByUI = CONFIRM_BY_UI_DEFAULT;
pObj->ioctl_if_type = INT_P2P;
#ifdef WIFI_P2P_CONCURRENT_FAST_SCAN
/* reset to not doing improved scan when both STA & P2P are LinkDown */
if (!INFRA_ON(pAd))
pAd->StaCfg.bImprovedScan = FALSE;
#endif
if (P2P_CLI_ON(pAd))
{
#ifdef CONFIG_MULTI_CHANNEL
pAd->P2pCfg.bStartP2pConnect = FALSE;
#endif /*CONFIG_MULTI_CHANNEL*/
Set_P2pCli_Enable_Proc(pAd, "0");
}
if (P2P_GO_ON(pAd))
{
PWSC_CTRL pWscControl = &pAd->ApCfg.MBSSID[0].WscControl;
pWscControl->WscState = WSC_STATE_OFF;
}
Set_P2p_OpMode_Proc(pAd, "0");
pObj->ioctl_if_type = if_type;
pAd->ApCfg.ApCliTab[0].WscControl.WscConfStatus = WSC_SCSTATE_UNCONFIGURED;
pAd->ApCfg.MBSSID[0].WscControl.WscConfStatus = WSC_SCSTATE_UNCONFIGURED;
P2pGetRandomSSID(pAd, pAd->ApCfg.MBSSID[MAIN_MBSSID].Ssid, &(pAd->ApCfg.MBSSID[MAIN_MBSSID].SsidLen));
pAd->P2pCfg.SSIDLen = pAd->ApCfg.MBSSID[MAIN_MBSSID].SsidLen;
NdisMoveMemory(pAd->P2pCfg.SSID, pAd->ApCfg.MBSSID[MAIN_MBSSID].Ssid, pAd->P2pCfg.SSIDLen);
/* Set Channel. */
if ((INFRA_ON(pAd)) && (pAd->StaActive.SupportedHtPhy.ChannelWidth == BW_40))
{
}
else
{
BOOLEAN bDisableMAC = FALSE;
UINT32 Data = 0, macStatus;
UINT32 MTxCycle;
rtmp_bbp_set_bw(pAd, BW_20);
if (!INFRA_ON(pAd))
{
pAd->CommonCfg.Channel = pP2PCtrl->ListenChannel;
pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen);
}
if (pAd->CommonCfg.BBPCurrentBW == BW_20)
pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
}
if (IS_PERSISTENT_ON(pAd) && pP2PCtrl->bP2pCliReConnect)
{
COPY_MAC_ADDR(pAd->P2pCfg.ConnectingMAC, pAd->P2pTable.PerstEntry[0].Addr);
DBGPRINT(RT_DEBUG_ERROR, ("P2P CLIENT Re-Connect to %02x:%02x:%02x:%02x:%02x:%02x\n",
PRINT_MAC(pAd->P2pCfg.ConnectingMAC)));
}
#ifdef RT_P2P_SPECIFIC_WIRELESS_EVENT
if (type == P2P_CONNECT_FAIL)
type = RT_P2P_CONNECT_FAIL;
else if (type == P2P_DISCONNECTED)
type = RT_P2P_DISCONNECTED;
P2pSendWirelessEvent(pAd, type, NULL, NULL);
#endif /* RT_P2P_SPECIFIC_WIRELESS_EVENT */
}
/*
==========================================================================
Description:
Start autonomous GO function/
Parameters:
Note:
==========================================================================
*/
VOID P2pStartAutoGo(
IN PRTMP_ADAPTER pAd)
{
}
VOID P2pEnable(
IN PRTMP_ADAPTER pAd)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
RTMPMoveMemory(pP2PCtrl->SSID, WILDP2PSSID, WILDP2PSSIDLEN);
pP2PCtrl->P2pCapability[0] = 0;
pP2PCtrl->P2pCapability[1] = 0;
if (IS_PERSISTENT_ON(pAd))
{
pAd->P2pCfg.P2pCapability[1] |= GRPCAP_PERSISTENT;
pAd->P2pCfg.P2pCapability[1] |= GRPCAP_PERSISTENT_RECONNECT;
pAd->P2pCfg.P2pCapability[0] |= DEVCAP_INVITE;
pAd->P2pCfg.ExtListenInterval = P2P_EXT_LISTEN_INTERVAL;
pAd->P2pCfg.ExtListenPeriod = P2P_EXT_LISTEN_PERIOD;
}
else
{
/* When Persistent is disabled, I won't support extended listening, so set to Zero. */
pAd->P2pCfg.ExtListenInterval = 0;
pAd->P2pCfg.ExtListenPeriod = 0;
}
/* P2P Device Capability */
pP2PCtrl->P2pCapability[0] |= DEVCAP_INVITE;
if (pP2PCtrl->P2p_OpMode == P2P_CONCURRENT)
{
pP2PCtrl->P2pCapability[1] |= GRPCAP_CROSS_CONNECT;
pP2PCtrl->P2pCapability[0] |= DEVCAP_CLIENT_CONCURRENT;
}
if (IS_INTRA_BSS_ON(pAd))
{
pP2PCtrl->P2pCapability[1] |= GRPCAP_INTRA_BSS;
}
{
pP2PCtrl->ConfigMethod = 0x188;
pAd->StaCfg.WscControl.RegData.SelfInfo.ConfigMethods = 0x188;
pAd->StaCfg.WscControl.RegData.SelfInfo.DevPwdId = 0x188;
}
pP2PCtrl->ConfigTimeout[0] = 4;
pP2PCtrl->ConfigTimeout[1] = 30;
/* Construct AP RSN_IE. */
RTMPMakeRSNIE(pAd, Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption3Enabled, 0 /*apidx*/);
P2pStopNoA(pAd, NULL);
pAd->P2pCfg.CTWindows = 0;
P2pScanChannelDefault(pAd);
pP2PCtrl->P2PConnectState = P2P_CONNECT_IDLE;
P2pGotoIdle(pAd);
/*AsicSetBssid(pAd, pP2PCtrl->CurrentAddress); */
{
ULONG Addr4;
UINT32 regValue;
PUCHAR pP2PBssid = &pAd->CurrentAddress[0];
Addr4 = (ULONG)(pP2PBssid[0]) |
(ULONG)(pP2PBssid[1] << 8) |
(ULONG)(pP2PBssid[2] << 16) |
(ULONG)(pP2PBssid[3] << 24);
RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
#ifdef HDR_TRANS_SUPPORT
RTMP_IO_WRITE32(pAd, HT_MAC_BSSID_DW0, Addr4);
#endif /* HDR_TRANS_SUPPORT */
Addr4 = 0;
/* always one BSSID in STA mode */
Addr4 = (ULONG)(pP2PBssid[4]) | (ULONG)(pP2PBssid[5] << 8);
RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
RTMP_IO_READ32(pAd, MAC_BSSID_DW1, &regValue);
regValue &= 0x0000FFFF;
if ((pAd->CurrentAddress[5] % 2 != 0)
#ifdef P2P_ODD_MAC_ADJUST
&& FALSE
#endif /* P2P_ODD_MAC_ADJUST */
)
DBGPRINT(RT_DEBUG_ERROR, ("The 2-BSSID mode is enabled, the BSSID byte5 MUST be the multiple of 2\n"));
regValue |= (1 << 16);
/* set as 0/1 bit-21 of MAC_BSSID_DW1(offset: 0x1014)
to disable/enable the new MAC address assignment. */
if (pAd->chipCap.MBSSIDMode == MBSSID_MODE1)
regValue |= (1 << 21);
RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, regValue);
#ifdef HDR_TRANS_SUPPORT
/*
point WCID MAC table to 0x1800
This is for debug.
But HDR_TRANS doesn't work if you remove it.
Check after IC formal release.
*/
regValue |= 0x18000000;
RTMP_IO_WRITE32(pAd, HT_MAC_BSSID_DW1, regValue);
#endif /* HDR_TRANS_SUPPORT */
}
DBGPRINT(RT_DEBUG_ERROR, ("!4 OpStatusFlags = %lx. CentralChannel = %d. Channel = %d. !!! \n", pAd->CommonCfg.OpStatusFlags,pAd->CommonCfg.CentralChannel,pAd->CommonCfg.Channel));
}
/*
==========================================================================
Description:
Modify P2P's listen channel when in Concurrent Operation to get better performance.
Can be called from LinkUp and LinkDown;
Parameters:
Note:
==========================================================================
*/
VOID P2pScanChannelDefault(
IN PRTMP_ADAPTER pAd)
{
/* Default listen channel is based on spec, using Social channels 1, 6, 11. */
pAd->P2pCfg.P2pProprietary.ListenChanel[0] = 1;
pAd->P2pCfg.P2pProprietary.ListenChanel[1] = 6;
pAd->P2pCfg.P2pProprietary.ListenChanel[2] = 11;
pAd->P2pCfg.P2pProprietary.ListenChanelIndex = 0;
pAd->P2pCfg.P2pProprietary.ListenChanelCount = 3;
DBGPRINT(RT_DEBUG_ERROR, ("%s <=== count = %d, Channels are %d, %d,%d separately \n",
__FUNCTION__, pAd->P2pCfg.P2pProprietary.ListenChanelCount, pAd->P2pCfg.P2pProprietary.ListenChanel[0], pAd->P2pCfg.P2pProprietary.ListenChanel[1], pAd->P2pCfg.P2pProprietary.ListenChanel[2]));
}
/*
========================================================================
Routine Description:
If.
Arguments:
- NIC Adapter pointer
Return Value:
FALSE - None of channel in ChannelList Match any channel in pAd->ChannelList[] array
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
BOOLEAN P2pCheckChannelList(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pChannelList)
{
UCHAR i, k;
UCHAR NumOfDismatch = 0;
/* Check if new (control) channel is in our channellist which we currently agree to operate in. */
for (k = 0;k < MAX_NUM_OF_CHANNELS;k++)
{
if (*(pChannelList + k) == 0)
break;
for (i = 0;i < pAd->ChannelListNum;i++)
{
if (pAd->ChannelList[i].Channel == *(pChannelList + k))
{
break;
}
}
if ( i == pAd->ChannelListNum)
NumOfDismatch++;
}
if ((NumOfDismatch == k) && (k != 0))
{
DBGPRINT(RT_DEBUG_TRACE, (" P2P - no common channel = %d...\n", *pChannelList));
return FALSE;
}
return TRUE;
}
/*
==========================================================================
Description:
The routine check whether we need to check this frame's transmission result. Success ? or Retry fail?.
If found retry fail, we may need to resend this frame again.
Parameters:
Note:
==========================================================================
*/
VOID P2pAckRequiredCheck(
IN PRTMP_ADAPTER pAd,
IN PP2P_PUBLIC_FRAME pFrame,
OUT UCHAR *TempPid)
{
UCHAR EAPHEAD[8] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};
PUCHAR pDest;
PFRAME_P2P_ACTION pP2pActFrame;
PUCHAR pP2pOUI = (PUCHAR) pFrame;
pP2pOUI += (sizeof(HEADER_802_11) + 2);
pP2pActFrame = (PFRAME_P2P_ACTION)pFrame;
/* check Go Neg Confirm Frame. */
if ((pFrame->Subtype == GO_NEGOCIATION_CONFIRM) &&
(NdisEqualMemory(pP2pOUI, P2POUIBYTE, 4)) &&
(pFrame->Action == ACTION_WIFI_DIRECT) &&
(pFrame->Category == CATEGORY_PUBLIC))
{
DBGPRINT(RT_DEBUG_TRACE,("P2pAckRequiredCheck --> This is a Confirm Frame. Pid = RequireACK !!!\n"));
*TempPid = 0x7; /* PID_REQUIRE_ACK */
return;
}
/* check Intivation Response. */
if ((pFrame->Subtype == P2P_INVITE_RSP) &&
(NdisEqualMemory(pP2pOUI, P2POUIBYTE, 4)) &&
(pFrame->Action == ACTION_WIFI_DIRECT) &&
(pFrame->Category == CATEGORY_PUBLIC))
{
DBGPRINT(RT_DEBUG_TRACE,("P2pAckRequiredCheck --> This is a Invite Rsp Frame. Pid = RequireACK !!!\n"));
*TempPid = 0x7; /* PID_REQUIRE_ACK */
return;
}
if ((pP2pActFrame->Category == 0x7F/*MT2_ACT_VENDOR*/)
&& (pP2pActFrame->OUISubType == P2PACT_GO_DISCOVER_REQ)
&& (pP2pActFrame->OUIType == 0x9))
{
DBGPRINT(RT_DEBUG_TRACE,("P2pAckRequiredCheck --> This is a GO Discoverbility. Pid = RequireACK !!!\n"));
*TempPid = 0x7; /* PID_REQUIRE_ACK */
return;
}
/* As Go, need to check EAP fail's ACK */
if ((IS_P2P_REGISTRA(pAd)) && (pFrame->p80211Header.FC.Type == BTYPE_DATA))
{
pDest = &pFrame->Category;
if (NdisEqualMemory(EAPHEAD, pDest, 8))
{
pDest += 8;
if ((*pDest == EAPOL_VER) && (*(pDest+1) == EAPPacket) && (*(pDest + 3) == EAP_CODE_FAIL))
{
DBGPRINT(RT_DEBUG_TRACE,("P2pAckRequiredCheck --> This is a EAP FailFrame. Pid = RequireACK!!!\n"));
*TempPid = 0x7; /* PID_REQUIRE_ACK */
}
}
}
}
BOOLEAN IsP2pFirstMacSmaller(
IN PUCHAR Firststaddr,
IN PUCHAR SecondAddr)
{
UCHAR i;
for (i=0 ; i< 6;i++)
{
if (*(Firststaddr+i) > *(SecondAddr+i))
return FALSE;
}
return TRUE;
}
/*
==========================================================================
Description:
Initial Listen interval for Listen Timer
Return:
VOID
NOTE:
==========================================================================
*/
VOID P2PInitListenTimer(
IN PRTMP_ADAPTER pAd,
UINT32 value)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
DBGPRINT(RT_DEBUG_TRACE, ("<---- %s\n", __FUNCTION__));
pP2PCtrl->P2pCounter.bListen = FALSE;
pP2PCtrl->P2pCounter.ListenInterval = 0;
}
/*
==========================================================================
Description:
Set Listen interval for Listen Timer
Return:
VOID
NOTE:
==========================================================================
*/
VOID P2PSetListenTimer(
IN PRTMP_ADAPTER pAd,
UINT32 value)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
DBGPRINT(RT_DEBUG_INFO, ("<---- %s\n", __FUNCTION__));
if ((pP2PCtrl->P2pCounter.bStartScan == TRUE) && (pP2PCtrl->P2pCounter.bListen == FALSE))
{
/* update Discovery State Machine state. */
if (pP2PCtrl->P2pCounter.bStartScan)
MlmeEnqueue(pAd, P2P_DISC_STATE_MACHINE, P2P_DISC_LISTEN_CMD_EVT, 0, NULL, 0);
}
}
/*
==========================================================================
Description:
Listen State Timer Handler
Return:
VOID
NOTE:
==========================================================================
*/
VOID P2PListenTimerExec(
IN PRTMP_ADAPTER pAd,
UINT32 value)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
DBGPRINT(RT_DEBUG_INFO, ("<---- %s\n", __FUNCTION__));
pP2PCtrl->P2pCounter.bListen = FALSE;
if (pP2PCtrl->P2pCounter.bStartScan == TRUE)
{
/* Listen interval has expired, go to Search state. */
MlmeEnqueue(pAd, P2P_DISC_STATE_MACHINE, P2P_DISC_SEARCH_CMD_EVT, 0, NULL, 0);
}
else
{
/* Listen interval has expired, go to IDLE state. */
MlmeEnqueue(pAd, P2P_DISC_STATE_MACHINE, P2P_DISC_CANL_CMD_EVT, 0, NULL, 0);
NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen);
pAd->MlmeAux.AutoReconnectSsidLen = (UCHAR)pAd->CommonCfg.SsidLen;
}
}
/*
==========================================================================
Description:
Initial Next Scan Round for Scan Timer
Return:
VOID
NOTE:
==========================================================================
*/
VOID P2PInitNextScanTimer(
IN PRTMP_ADAPTER pAd,
UINT32 value)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
DBGPRINT(RT_DEBUG_TRACE, ("<---- %s\n", __FUNCTION__));
pP2PCtrl->P2pCounter.bNextScan = FALSE;
pP2PCtrl->P2pCounter.NextScanRound = 0xffffffff;
}
/*
==========================================================================
Description:
Set Next Scan Round for Scan Timer
Return:
VOID
NOTE:
==========================================================================
*/
VOID P2PSetNextScanTimer(
IN PRTMP_ADAPTER pAd,
UINT32 value)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
DBGPRINT(RT_DEBUG_INFO, ("<---- %s\n", __FUNCTION__));
if ((pP2PCtrl->P2pCounter.bStartScan == TRUE) && (pP2PCtrl->P2pCounter.bNextScan == FALSE))
{
pP2PCtrl->P2pCounter.bNextScan = TRUE;
if (value)
pP2PCtrl->P2pCounter.NextScanRound = value;
else
pP2PCtrl->P2pCounter.NextScanRound = (RandomByte(pAd) % P2P_RANDOM_BASE) + P2P_RANDOM_BIAS;
}
DBGPRINT(RT_DEBUG_TRACE, ("%s: NextScanRound - %ld\n", __FUNCTION__, pP2PCtrl->P2pCounter.NextScanRound));
}
/*
==========================================================================
Description:
Next Scan Round Timer Handler
Return:
VOID
NOTE:
==========================================================================
*/
VOID P2PNextScanTimerExec(
IN PRTMP_ADAPTER pAd,
UINT32 value)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
DBGPRINT(RT_DEBUG_INFO, ("<---- %s\n", __FUNCTION__));
pP2PCtrl->P2pCounter.bNextScan = FALSE;
MlmeEnqueue(pAd, P2P_CTRL_STATE_MACHINE, P2P_CTRL_DISC_EVT, 0, NULL, 0);
}
VOID P2PInitDevDiscTimer(
IN PRTMP_ADAPTER pAd,
UINT32 value)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
DBGPRINT(RT_DEBUG_INFO, ("<---- %s\n", __FUNCTION__));
pP2PCtrl->P2pCounter.bStartScan = FALSE;
pP2PCtrl->P2pCounter.CounterAftrScanButton = 0xffffffff;
}
VOID P2PSetDevDiscTimer(
IN PRTMP_ADAPTER pAd,
UINT32 value)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
DBGPRINT(RT_DEBUG_INFO, ("<---- %s\n", __FUNCTION__));
if (pP2PCtrl->P2pCounter.bStartScan == FALSE)
{
pP2PCtrl->P2pCounter.bStartScan = TRUE;
pP2PCtrl->P2pCounter.CounterAftrScanButton = pP2PCtrl->DevDiscPeriod;
if (P2P_GO_ON(pAd) || P2P_CLI_ON(pAd))
pP2PCtrl->P2pCounter.CounterAftrScanButton = 200;
DBGPRINT(RT_DEBUG_ERROR, ("%s:: CounterAftrScanButton = %lu.\n", __FUNCTION__, pP2PCtrl->P2pCounter.CounterAftrScanButton));
}
}
VOID P2PDevDiscTimerExec(
IN PRTMP_ADAPTER pAd,
UINT32 value)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
DBGPRINT(RT_DEBUG_INFO, ("<---- %s\n", __FUNCTION__));
pP2PCtrl->P2pCounter.bStartScan = FALSE;
MlmeEnqueue(pAd, P2P_CTRL_STATE_MACHINE, P2P_CTRL_DISC_DONE_EVT, 0, NULL, 1);
}
VOID P2P_SetWscRule(
IN PRTMP_ADAPTER pAd,
UCHAR index,
PUSHORT PeerWscMethod)
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
PRT_P2P_CLIENT_ENTRY pP2pEntry = &pAd->P2pTable.Client[index];
DBGPRINT(RT_DEBUG_TRACE, ("%s:: Peer Dpid = %s. My Dpid = %s.\n", __FUNCTION__, decodeDpid(pP2pEntry->Dpid), decodeDpid(pP2PCtrl->Dpid)));
DBGPRINT(RT_DEBUG_TRACE, ("%s:: Peer Config Method = %s. My Config Method = %s.\n", __FUNCTION__, decodeConfigMethod(pP2pEntry->ConfigMethod), decodeConfigMethod(pP2PCtrl->ConfigMethod)));
if (pP2PCtrl->Dpid == DEV_PASS_ID_NOSPEC)
{
if ((pP2pEntry->ConfigMethod == WSC_CONFMET_KEYPAD) || (pP2pEntry->Dpid == DEV_PASS_ID_USER))
{
pP2PCtrl->WscMode = WSC_PIN_MODE;
pP2PCtrl->ConfigMethod = WSC_CONFMET_DISPLAY;
pP2PCtrl->Dpid = DEV_PASS_ID_REG;
*PeerWscMethod = WSC_CONFMET_KEYPAD;
}
else if ((pP2pEntry->ConfigMethod == WSC_CONFMET_DISPLAY) || (pP2pEntry->Dpid == DEV_PASS_ID_REG))
{
pP2PCtrl->WscMode = WSC_PIN_MODE;
pP2PCtrl->ConfigMethod = WSC_CONFMET_KEYPAD;
pP2PCtrl->Dpid = DEV_PASS_ID_USER;
*PeerWscMethod = WSC_CONFMET_DISPLAY;
}
#ifdef HE_BD_SUPPORT //select PBC, if config_method not only one case and PBC is one of the config_method
else if (((pP2pEntry->ConfigMethod & WSC_CONFMET_PBC) == WSC_CONFMET_PBC) || (pP2pEntry->Dpid == DEV_PASS_ID_PBC))
{
pP2PCtrl->WscMode = WSC_PBC_MODE;
pP2PCtrl->ConfigMethod = WSC_CONFMET_PBC;
pP2PCtrl->Dpid = DEV_PASS_ID_PBC;
*PeerWscMethod = WSC_CONFMET_PBC;
}
#else
else if ((pP2pEntry->ConfigMethod == WSC_CONFMET_PBC) || (pP2pEntry->Dpid == DEV_PASS_ID_PBC))
{
pP2PCtrl->WscMode = WSC_PBC_MODE;
pP2PCtrl->ConfigMethod = WSC_CONFMET_PBC;
pP2PCtrl->Dpid = DEV_PASS_ID_PBC;
*PeerWscMethod = WSC_CONFMET_PBC;
}
#endif
else
{
if ((pP2pEntry->Rule == P2P_IS_CLIENT) && (pP2PCtrl->Rule == P2P_IS_GO))
{
/* I'm Registrar and Enter PIN. */
pP2PCtrl->WscMode = WSC_PIN_MODE;
pP2PCtrl->ConfigMethod = WSC_CONFMET_KEYPAD;
pP2PCtrl->Dpid = DEV_PASS_ID_USER;
}
else
{
/* I'm Enrollee and Use Default Config Method. */
if (pP2PCtrl->DefaultConfigMethod == P2P_REG_CM_DISPLAY)
{
pP2PCtrl->WscMode = WSC_PIN_MODE;
pP2PCtrl->ConfigMethod = WSC_CONFMET_DISPLAY;
pP2PCtrl->Dpid = DEV_PASS_ID_REG;
*PeerWscMethod = WSC_CONFMET_KEYPAD;
}
else if (pP2PCtrl->DefaultConfigMethod == P2P_REG_CM_KEYPAD)
{
pP2PCtrl->WscMode = WSC_PIN_MODE;
pP2PCtrl->ConfigMethod = WSC_CONFMET_KEYPAD;
pP2PCtrl->Dpid = DEV_PASS_ID_USER;
*PeerWscMethod = WSC_CONFMET_DISPLAY;
}
else if (pP2PCtrl->DefaultConfigMethod == P2P_REG_CM_PBC)
{
pP2PCtrl->WscMode = WSC_PBC_MODE;
pP2PCtrl->ConfigMethod = WSC_CONFMET_PBC;
pP2PCtrl->Dpid = DEV_PASS_ID_PBC;
*PeerWscMethod = WSC_CONFMET_PBC;
}
}
}
}
DBGPRINT(RT_DEBUG_TRACE, ("My P2P Wsc Configuration:\n"));
DBGPRINT(RT_DEBUG_TRACE, ("WscMode = %d. WscConfigMethod = %s. WscDpid = %s.\n", pP2PCtrl->WscMode, decodeConfigMethod(pP2PCtrl->ConfigMethod), decodeDpid(pP2PCtrl->Dpid)));
if (pP2PCtrl->ConfigMethod == WSC_CONFMET_DISPLAY)
{
/*
Although driver uses different structure for P2P GO and P2P CLI but PIN shall be the same.
*/
pAd->ApCfg.MBSSID[0].WscControl.WscEnrolleePinCode = pAd->ApCfg.ApCliTab[0].WscControl.WscEnrolleePinCode;
pAd->ApCfg.MBSSID[0].WscControl.WscEnrolleePinCodeLen = pAd->ApCfg.ApCliTab[0].WscControl.WscEnrolleePinCodeLen;
/* Woody 1: Show PIN Code */
DBGPRINT(RT_DEBUG_TRACE, (" *************************************************\n"));
DBGPRINT(RT_DEBUG_TRACE, (" * *\n"));
DBGPRINT(RT_DEBUG_TRACE, (" * PIN Code = %08u *\n", pAd->ApCfg.ApCliTab[0].WscControl.WscEnrolleePinCode));
DBGPRINT(RT_DEBUG_TRACE, (" * *\n"));
DBGPRINT(RT_DEBUG_TRACE, (" *************************************************\n"));
{
/*
RtmpOSWrielessEventSendExt(pAd->net_dev, RT_WLAN_EVENT_SHOWPIN, -1, pP2pEntry->addr,
NULL, 0, 0);
*/
}
}
else if (pP2PCtrl->ConfigMethod == WSC_CONFMET_KEYPAD)
{
/* Woody 2: Enter PIN Code */
{
/*
RtmpOSWrielessEventSendExt(pAd->net_dev, RT_WLAN_EVENT_PIN, -1, pP2pEntry->addr,
NULL, 0, 0);
*/
}
}
DBGPRINT(RT_DEBUG_TRACE, ("Peer P2P Wsc Configuration:\n"));
DBGPRINT(RT_DEBUG_TRACE, ("WscMode = %d. WscConfigMethod = %s. WscDpid = %s.\n", pP2pEntry->WscMode, decodeConfigMethod(pP2pEntry->ConfigMethod), decodeDpid(pP2pEntry->Dpid)));
}
/*
==========================================================================
Description:
decode Dpid
Return:
State string
NOTE:
==========================================================================
*/
PSTRING decodeDpid (USHORT dpid)
{
PSTRING retval = " ";
switch (dpid)
{
case DEV_PASS_ID_PIN: retval = "DEV_PASS_ID_PIN "; break;
case DEV_PASS_ID_USER: retval = "DEV_PASS_ID_USER_SPECIFIED"; break;
case DEV_PASS_ID_REG: retval = "DEV_PASS_ID_REGISTRA_SPECIFIED"; break;
case DEV_PASS_ID_PBC: retval = "DEV_PASS_ID_PBC"; break;
default: retval = "***UNKNOWN dpid***";
}
return(retval);
}
/*
==========================================================================
Description:
decode ConfigMethod
Return:
State string
NOTE:
==========================================================================
*/
PSTRING ddecodeConfigMethod (USHORT ConfigMethos)
{
PSTRING retval = " ";
ULONG mm[4], i;
mm[0] = 0;
mm[1] = 0;
mm[2] = 0;
mm[3] = 0;
if ((ConfigMethos & WSC_CONFMET_LABEL) != 0)
mm[0] = 1;
if ((ConfigMethos & WSC_CONFMET_DISPLAY) != 0)
mm[1] = 1;
if ((ConfigMethos & WSC_CONFMET_KEYPAD) != 0)
mm[2] = 1;
if ((ConfigMethos & WSC_CONFMET_PBC) != 0)
mm[3] = 1;
for ( i = 0;i < 4;i++)
{
}
return (retval);
}
PSTRING decodeMyRule (USHORT Rule)
{
PSTRING retval = " ";
switch (Rule)
{
case P2P_IS_CLIENT: retval = "I am P2P Client"; break;
case P2P_IS_GO: retval = "I am P2P GO"; break;
case P2P_IS_DEVICE: retval = "I am P2P Device"; break;
case P2P_IS_CLIENT_IN_GROUP: retval = "I am P2P Client in Group"; break;
default: retval = "*** Unknown Rule ***";
}
return(retval);
}
PSTRING decodeConfigMethod (USHORT ConfigMethos)
{
PSTRING retval = " ";
switch (ConfigMethos)
{
case WSC_CONFMET_LABEL: retval = "LABEL LABEL "; break;
case WSC_CONFMET_DISPLAY: retval = "DISPLAY DISPLAY"; break;
case WSC_CONFMET_KEYPAD: retval = "KEYPAD KEYPAD"; break;
case WSC_CONFMET_PBC: retval = "PBC PBC"; break;
case WSC_CONFMET_DISPLAY | WSC_CONFMET_KEYPAD: retval = "DISPLAY KEYPAD"; break;
case WSC_CONFMET_DISPLAY | WSC_CONFMET_PBC: retval = "DISPLAY PBC"; break;
case WSC_CONFMET_KEYPAD | WSC_CONFMET_PBC: retval = "KEYPAD PBC"; break;
case WSC_CONFMET_DISPLAY | WSC_CONFMET_KEYPAD | WSC_CONFMET_PBC: retval = "DISPLAY KEYPAD PBC"; break;
default: retval = "***Multiple ConfigMethod***";
}
return(retval);
}
/*
==========================================================================
Description:
decode P2P state
Return:
State string
NOTE:
==========================================================================
*/
PSTRING decodeP2PState (UCHAR P2pState)
{
PSTRING retval = " ";
switch (P2pState) {
case P2P_CONNECT_IDLE: retval = "P2P_CONNECT_IDLE"; break;
case P2P_ANY_IN_FORMATION_AS_CLIENT: retval = "GroupForming as Client"; break;
case P2P_ANY_IN_FORMATION_AS_GO: retval = "P2P_ANY_IN_FORMATION_AS_GO"; break;
case P2P_DO_GO_NEG_DONE_CLIENT: retval = "P2P_DO_GO_NEG_DONE_CLIENT"; break;
case P2P_DO_GO_SCAN_BEGIN: retval = "P2P_DO_GO_SCAN_BEGIN"; break;
case P2P_DO_GO_SCAN_DONE: retval = "P2P_DO_GO_SCAN_DONE"; break;
case P2P_WPS_REGISTRA: retval = "P2P_WPS_REGISTRA"; break;
case P2P_DO_WPS_ENROLLEE: retval = "P2P_DO_WPS_ENROLLEE"; break;
default: retval = "***UNKNOWN state***";
}
return(retval);
}
/*
==========================================================================
Description:
decode P2P client state
Return:
State string
NOTE:
==========================================================================
*/
PSTRING decodeP2PClientState (P2P_CLIENT_STATE P2pClientState)
{
PSTRING retval = " ";
switch (P2pClientState) {
case P2PSTATE_NONE: retval = "P2PSTATE_NONE"; break;
case P2PSTATE_DISCOVERY: retval = "P2PSTATE_DISCOVERY"; break;
case P2PSTATE_DISCOVERY_CLIENT: retval = "P2PSTATE_DISCOVERY_CLIENT"; break;
case P2PSTATE_DISCOVERY_GO: retval = "P2PSTATE_DISCOVERY_GO"; break;
case P2PSTATE_CLIENT_DISCO_COMMAND: retval = "P2PSTATE_CLIENT_DISCO_COMMAND"; break;
case P2PSTATE_GO_DISCO_COMMAND: retval = "P2PSTATE_GO_DISCO_COMMAND"; break;
case P2PSTATE_PROVISION_COMMAND: retval = "P2PSTATE_PROVISION_COMMAND"; break;
case P2PSTATE_SERVICE_DISCOVER_INIT_COMMAND: retval = "P2PSTATE_SERVICE_DISCOVER_INIT_COMMAND"; break;
case P2PSTATE_SERVICE_COMEBACK_COMMAND: retval = "P2PSTATE_SERVICE_COMEBACK_COMMAND"; break;
case P2PSTATE_INVITE_COMMAND: retval = "P2PSTATE_INVITE_COMMAND"; break;
case P2PSTATE_CONNECT_COMMAND: retval = "P2PSTATE_CONNECT_COMMAND"; break;
case P2PSTATE_SENT_INVITE_REQ: retval = "P2PSTATE_SENT_INVITE_REQ"; break;
case P2PSTATE_SENT_GO_NEG_REQ: retval = "P2PSTATE_SENT_GO_NEG_REQ"; break;
case P2PSTATE_WAIT_GO_COMFIRM: retval = "P2PSTATE_WAIT_GO_COMFIRM"; break;
case P2PSTATE_WAIT_GO_COMFIRM_ACK: retval = "P2PSTATE_WAIT_GO_COMFIRM_ACK"; break;
case P2PSTATE_GO_COMFIRM_ACK_SUCCESS: retval = "P2PSTATE_GO_COMFIRM_ACK_SUCCESS"; break;
case P2PSTATE_WAIT_GO_DISCO_ACK: retval = "P2PSTATE_WAIT_GO_DISCO_ACK"; break;
case P2PSTATE_WAIT_GO_DISCO_ACK_SUCCESS: retval = "P2PSTATE_WAIT_GO_DISCO_ACK_SUCCESS"; break;
case P2PSTATE_GO_WPS: retval = "P2PSTATE_GO_WPS"; break;
case P2PSTATE_GO_AUTH: retval = "P2PSTATE_GO_AUTH"; break;
case P2PSTATE_GO_ASSOC: retval = "P2PSTATE_GO_ASSOC"; break;
case P2PSTATE_CLIENT_WPS: retval = "P2PSTATE_CLIENT_WPS"; break;
case P2PSTATE_CLIENT_WPS_DONE: retval = "P2PSTATE_CLIENT_WPS_DONE"; break;
case P2PSTATE_CLIENT_AUTH: retval = "P2PSTATE_CLIENT_AUTH"; break;
case P2PSTATE_CLIENT_ASSOC: retval = "P2PSTATE_CLIENT_ASSOC"; break;
case P2PSTATE_CLIENT_OPERATING: retval = "P2PSTATE_CLIENT_OPERATING"; break;
case P2PSTATE_CLIENT_ABSENCE: retval = "P2PSTATE_CLIENT_ABSENCE"; break;
case P2PSTATE_CLIENT_SCAN: retval = "P2PSTATE_CLIENT_SCAN"; break;
case P2PSTATE_CLIENT_FIND: retval = "P2PSTATE_CLIENT_FIND"; break;
case P2PSTATE_GO_OPERATING: retval = "P2PSTATE_GO_OPERATING"; break;
case P2PSTATE_GO_ABSENCE: retval = "P2PSTATE_GO_ABSENCE"; break;
case P2PSTATE_GO_SCAN: retval = "P2PSTATE_GO_SCAN"; break;
case P2PSTATE_GO_FIND: retval = "P2PSTATE_GO_FIND"; break;
case P2PSTATE_NONP2P_WPS: retval = "P2PSTATE_NONP2P_WPS"; break;
case P2PSTATE_NONP2P_PSK: retval = "P2PSTATE_NONP2P_PSK"; break;
default: retval = "***UNKNOWN state***";
}
return(retval);
}
PSTRING decodeCtrlState (UCHAR State)
{
PSTRING retval = " ";
switch (State)
{
case P2P_CTRL_IDLE: retval = "P2P_CTRL_IDLE"; break;
case P2P_CTRL_DISCOVERY: retval = "P2P_CTRL_DISCOVERY"; break;
case P2P_CTRL_GROUP_FORMATION: retval = "P2P_CTRL_GROUP_FORMATION"; break;
case P2P_CTRL_DONE: retval = "P2P_CTRL_DONE"; break;
default: retval = "***Unknown CTRL State***";
}
return(retval);
}
PSTRING decodeDiscoveryState (UCHAR State)
{
PSTRING retval = " ";
switch (State)
{
case P2P_DISC_IDLE: retval = "P2P_DISC_IDLE"; break;
case P2P_DISC_SCAN: retval = "P2P_DISC_SCAN"; break;
case P2P_DISC_LISTEN: retval = "P2P_DISC_LISTEN"; break;
case P2P_DISC_SEARCH: retval = "P2P_DISC_SEARCH"; break;
default: retval = "***Unknown Device Discovery State***";
}
return(retval);
}
PSTRING decodeGroupFormationState (UCHAR State)
{
PSTRING retval = " ";
switch (State)
{
case P2P_GO_FORM_IDLE: retval = "P2P_GO_FORM_IDLE"; break;
case P2P_WAIT_GO_FORM_RSP: retval = "P2P_WAIT_GO_FORM_RSP"; break;
case P2P_WAIT_GO_FORM_CONF: retval = "P2P_WAIT_GO_FORM_CONF"; break;
case P2P_GO_FORM_DONE: retval = "P2P_GO_FORM_DONE"; break;
case P2P_GO_FORM_PROV: retval = "P2P_GO_FORM_PROV"; break;
case P2P_GO_FORM_INVITE: retval = "P2P_GO_FORM_INVITE"; break;
case P2P_WAIT_GO_FORM_INVITE_RSP: retval = "P2P_WAIT_GO_FORM_INVITE_RSP"; break;
default: retval = "***Unknown Group Formation State***";
}
return(retval);
}
VOID decodeDeviceCap (UCHAR State)
{
DBGPRINT(RT_DEBUG_TRACE, (" DeviceCapability = %x.\n", State));
if (State & DEVCAP_SD)
DBGPRINT(RT_DEBUG_TRACE, (" [0] bServiceDiscovery\n"));
if (State & DEVCAP_CLIENT_DISCOVER)
DBGPRINT(RT_DEBUG_TRACE, (" [1] bP2PClientDiscoverability\n"));
if (State & DEVCAP_CLIENT_CONCURRENT)
DBGPRINT(RT_DEBUG_TRACE, (" [2] bConcurrentOperation\n"));
if (State & DEVCAP_INFRA_MANAGED)
DBGPRINT(RT_DEBUG_TRACE, (" [3] bP2PInfrastructureManaged\n"));
if (State & DEVCAP_DEVICE_LIMIT)
DBGPRINT(RT_DEBUG_TRACE, (" [4] bP2PDeviceLimit\n"));
if (State & DEVCAP_INVITE)
DBGPRINT(RT_DEBUG_TRACE, (" [5] bP2PInvitationProcedure\n"));
}
VOID decodeGroupCap (UCHAR State)
{
DBGPRINT(RT_DEBUG_TRACE, (" GroupCapability = %x.\n", State));
if (State & GRPCAP_OWNER)
DBGPRINT(RT_DEBUG_TRACE, (" [0] bP2PGroupOwner\n"));
if (State & GRPCAP_PERSISTENT)
DBGPRINT(RT_DEBUG_TRACE, (" [1] bPersistentP2PGroup\n"));
if (State & GRPCAP_LIMIT)
DBGPRINT(RT_DEBUG_TRACE, (" [2] bP2PGroupLimit\n"));
if (State & GRPCAP_INTRA_BSS)
DBGPRINT(RT_DEBUG_TRACE, (" [3] bIntra-BssDistribution\n"));
if (State & GRPCAP_CROSS_CONNECT)
DBGPRINT(RT_DEBUG_TRACE, (" [4] bCrossConnection\n"));
if (State & GRPCAP_PERSISTENT_RECONNECT)
DBGPRINT(RT_DEBUG_TRACE, (" [5] bPersistentReconnect\n"));
if (State & GRPCAP_GROUP_FORMING)
DBGPRINT(RT_DEBUG_TRACE, (" [6] bGroupFormation\n"));
}
/*
==========================================================================
Description:
debug print function for P2P.
Return:
NOTE:
==========================================================================
*/
VOID P2PPrintMac(
IN PRTMP_ADAPTER pAd,
IN UCHAR macindex)
{
MAC_TABLE_ENTRY *pEntry;
DBGPRINT(RT_DEBUG_TRACE, (" ====================================================>P2PPrintMac i = %d, \n", macindex));
pEntry = &pAd->MacTab.Content[macindex];
DBGPRINT(RT_DEBUG_TRACE, ("!! , HTMode = %x, WepStatus = %d, AuthMode = %d. \n", pEntry->HTPhyMode.word, pEntry->WepStatus, pEntry->AuthMode));
DBGPRINT(RT_DEBUG_TRACE, ("ValidAsCLI = %d. ClientStatusFlags = %lx, \n", IS_ENTRY_CLIENT(pEntry), pEntry->ClientStatusFlags));
#ifdef RELEASE_EXLCUDE
/* MAC_TABLE_ENTRY don't have P2pInfo, skip this. */
#endif /* RELEASE_EXCLUDE */
DBGPRINT(RT_DEBUG_TRACE, ("devaddr = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pEntry->Addr)));
#ifdef RELEASE_EXLCUDE
/* MAC_TABLE_ENTRY don't have P2pInfo, skip this. */
#endif /* RELEASE_EXCLUDE */
}
/*
==========================================================================
Description:
debug print function for P2P Table entry.
Return:
NOTE:
==========================================================================
*/
VOID P2PPrintP2PEntry(
IN PRTMP_ADAPTER pAd,
IN UCHAR p2pindex)
{
PRT_P2P_CLIENT_ENTRY pClient = NULL;
if (p2pindex >= MAX_P2P_GROUP_SIZE)
return;
DBGPRINT(RT_DEBUG_TRACE, ("%s:: p2p Entry idx = %d\n", __FUNCTION__, p2pindex));
DBGPRINT(RT_DEBUG_TRACE, ("====================================================>\n"));
pClient = &pAd->P2pTable.Client[p2pindex];
DBGPRINT(RT_DEBUG_TRACE, ("P2pClientState = %s \n", decodeP2PClientState(pClient->P2pClientState)));
DBGPRINT(RT_DEBUG_TRACE, ("ConfigMethod = %x. %s \n", pClient->ConfigMethod, decodeConfigMethod(pClient->ConfigMethod)));
DBGPRINT(RT_DEBUG_TRACE, ("Opchannel = %d. Listenchannel = %d.\n", pClient->OpChannel, pClient->ListenChannel));
DBGPRINT(RT_DEBUG_TRACE, ("MyGOIndex = %d. rule = %s.\n", pClient->MyGOIndex, decodeMyRule(pClient->Rule)));
DBGPRINT(RT_DEBUG_TRACE, ("addr = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pClient->addr)));
DBGPRINT(RT_DEBUG_TRACE, ("bssid = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pClient->bssid)));
DBGPRINT(RT_DEBUG_TRACE, ("interface addr = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pClient->InterfaceAddr)));
DBGPRINT(RT_DEBUG_TRACE, ("DeviceType = %02x %02x %02x %02x %02x %02x %02x %02x\n", pClient->PrimaryDevType[0], pClient->PrimaryDevType[1], pClient->PrimaryDevType[2],pClient->PrimaryDevType[3],pClient->PrimaryDevType[4],pClient->PrimaryDevType[5],pClient->PrimaryDevType[6],pClient->PrimaryDevType[7]));
DBGPRINT(RT_DEBUG_TRACE, ("NumSecondaryType = %x. RegClass = %x. ConfigTimeOut = %x. \n", pClient->NumSecondaryType, pClient->RegClass, pClient->ConfigTimeOut));
DBGPRINT(RT_DEBUG_TRACE, ("DeviceName[%ld] = %s\n", pClient->DeviceNameLen, pAd->P2pTable.Client[p2pindex].DeviceName));
decodeDeviceCap(pClient->DevCapability);
decodeGroupCap(pClient->GroupCapability);
#ifdef WFD_SUPPORT
DBGPRINT(RT_DEBUG_TRACE, ("WFD Device = %d.\n", pClient->WfdEntryInfo.bWfdClient));
if (pClient->WfdEntryInfo.bWfdClient)
{
DBGPRINT(RT_DEBUG_TRACE, ("DeviceType = %d. RTSP_Port = %d. MaxThroughput=%d.\n",
pClient->WfdEntryInfo.wfd_devive_type, pClient->WfdEntryInfo.rtsp_port, pClient->WfdEntryInfo.max_throughput));
DBGPRINT(RT_DEBUG_TRACE, ("SessionAvail = %d. PC = %d\n",
pClient->WfdEntryInfo.session_avail, pClient->WfdEntryInfo.wfd_PC));
}
#endif /* WFD_SUPPORT */
DBGPRINT(RT_DEBUG_TRACE, ("\n"));
DBGPRINT(RT_DEBUG_TRACE, ("<====================================================\n\n"));
}
/*
==========================================================================
Description:
debug print function for P2P Persistent Table entry.
Return:
NOTE:
==========================================================================
*/
VOID P2PPrintP2PPerstEntry(
IN PRTMP_ADAPTER pAd,
IN UCHAR p2pindex)
{
RT_P2P_PERSISTENT_ENTRY *pClient;
if (p2pindex >= MAX_P2P_TABLE_SIZE)
return;
DBGPRINT(RT_DEBUG_TRACE, (" P2PPrintP2PPerstEntry i = %d, \n", p2pindex));
pClient = &pAd->P2pTable.PerstEntry[p2pindex];
DBGPRINT(RT_DEBUG_TRACE, ("addr = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pClient->Addr)));
DBGPRINT(RT_DEBUG_TRACE, ("Key = %x %x %x %x %x %x %x %x\n", pClient->Profile.Key[0], pClient->Profile.Key[1], pClient->Profile.Key[2],pClient->Profile.Key[3],pClient->Profile.Key[4],pClient->Profile.Key[5],pClient->Profile.Key[6],pClient->Profile.Key[7]));
DBGPRINT(RT_DEBUG_TRACE, ("MacAddr = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pClient->Profile.MacAddr)));
DBGPRINT(RT_DEBUG_TRACE, ("Ssid %d = DIRECT-%c%c%c%c%c%c\n", pClient->Profile.SSID.SsidLength,pClient->Profile.SSID.Ssid[7], pClient->Profile.SSID.Ssid[8], pClient->Profile.SSID.Ssid[9],pClient->Profile.SSID.Ssid[10],pClient->Profile.SSID.Ssid[11],pClient->Profile.SSID.Ssid[12]));
DBGPRINT(RT_DEBUG_TRACE, ("MyRule = %x, bValid = %x, \n", pClient->MyRule, pClient->bValid));
}
/*
==========================================================================
Description:
debug print function for P2P.
Return:
NOTE:
==========================================================================
*/
VOID P2P_GoStartUp(
IN PRTMP_ADAPTER pAd,
IN INT bssidx)
{
UINT32 rx_filter_flag;
INT idx;
ULONG offset;
#ifdef INF_AMAZON_SE
ULONG i;
#endif /* INF_AMAZON_SE */
BOOLEAN bWmmCapable = FALSE;
BOOLEAN TxPreamble, SpectrumMgmt = FALSE;
UCHAR BBPR1 = 0, BBPR3 = 0;
UINT32 Value = 0;
#ifdef DOT1X_SUPPORT
/* BOOLEAN bDot1xReload = FALSE; */
#endif /* DOT1X_SUPPORT */
BOOLEAN Cancelled;
DBGPRINT(RT_DEBUG_TRACE, ("===> P2P_GoStartUp\n"));
/*RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); */
/*pAd->MlmeAux.Channel = 0; */
/*ScanNextChannel(pAd, OPMODE_STA); */
pAd->P2pCfg.P2pCapability[1] |= GRPCAP_OWNER;
pAd->StaCfg.bAutoReconnect = FALSE;
pAd->ApCfg.MBSSID[0].UapsdInfo.bAPSDCapable = TRUE;
pAd->P2pCfg.bSentProbeRSP = TRUE;
/*pAd->P2pCfg.DiscCurrentState = P2P_DISC_LISTEN;*/
/* Stop Scan. */
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
{
RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
pAd->MlmeAux.Channel = 0;
ScanNextChannel(pAd, OPMODE_STA);
}
rx_filter_flag = APNORMAL;
RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); /* enable RX of DMA block */
pAd->ApCfg.BssidNum = 1;
pAd->MacTab.MsduLifeTime = 20; /* default 5 seconds */
pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = TRUE;
pAd->ApCfg.MBSSID[MAIN_MBSSID].StationKeepAliveTime = 3;
/*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_P2P_GO); */
pAd->flg_p2p_OpStatusFlags |= P2P_GO_UP;
pAd->P2pCfg.GroupOpChannel = pAd->P2pCfg.GroupChannel;
if (!INFRA_ON(pAd))
pAd->CommonCfg.Channel = pAd->P2pCfg.GroupChannel;
pAd->P2pCfg.Rule = P2P_IS_GO;
#ifdef INF_AMAZON_SE
for (i = 0; i < NUM_OF_TX_RING; i++)
{
pAd->BulkOutDataSizeLimit[i]=24576;
}
#endif /* INF_AMAZON_SE */
AsicDisableSync(pAd);
if (WMODE_CAP_N(pAd->CommonCfg.PhyMode))
{
if (pAd->CommonCfg.Channel > 14)
pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = (WMODE_A | WMODE_AN);
else
pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = (WMODE_B | WMODE_G | WMODE_GN);
}
else
{
if (pAd->CommonCfg.Channel > 14)
pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = WMODE_A;
else
pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = (WMODE_B | WMODE_G);
}
TxPreamble = (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong ? 0 : 1);
{
PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID];
if ((pMbss->SsidLen <= 0) || (pMbss->SsidLen > MAX_LEN_OF_SSID))
{
NdisMoveMemory(pMbss->Ssid, "P2P_Linux_AP", 12);
pMbss->SsidLen = 12;
}
if (pMbss->bWmmCapable)
{
bWmmCapable = TRUE;
}
/* GO always use WPA2PSK / AES */
pMbss->AuthMode = Ndis802_11AuthModeWPA2PSK;
pMbss->WepStatus = Ndis802_11Encryption3Enabled;
pMbss->WscSecurityMode = WPA2PSKAES;
pMbss->GroupKeyWepStatus = pMbss->WepStatus;
pMbss->CapabilityInfo =
CAP_GENERATE(1, 0, (pMbss->WepStatus != Ndis802_11EncryptionDisabled), TxPreamble, pAd->CommonCfg.bUseShortSlotTime, SpectrumMgmt);
#ifdef UAPSD_SUPPORT
if (pAd->ApCfg.MBSSID[0].UapsdInfo.bAPSDCapable == TRUE)
{
/* QAPs set the APSD subfield to 1 within the Capability Information
field when the MIB attribute dot11APSDOptionImplemented is true
and set it to 0 otherwise. STAs always set this subfield to 0. */
pMbss->CapabilityInfo |= 0x0800;
} /* End of if */
#endif /* UAPSD_SUPPORT */
/* decide the mixed WPA cipher combination */
if (pMbss->WepStatus == Ndis802_11Encryption4Enabled)
{
switch ((UCHAR)pMbss->AuthMode)
{
/* WPA mode */
case Ndis802_11AuthModeWPA:
case Ndis802_11AuthModeWPAPSK:
pMbss->WpaMixPairCipher = WPA_TKIPAES_WPA2_NONE;
break;
/* WPA2 mode */
case Ndis802_11AuthModeWPA2:
case Ndis802_11AuthModeWPA2PSK:
pMbss->WpaMixPairCipher = WPA_NONE_WPA2_TKIPAES;
break;
/* WPA and WPA2 both mode */
case Ndis802_11AuthModeWPA1WPA2:
case Ndis802_11AuthModeWPA1PSKWPA2PSK:
/* In WPA-WPA2 and TKIP-AES mixed mode, it shall use the maximum */
/* cipher capability unless users assign the desired setting. */
if (pMbss->WpaMixPairCipher == MIX_CIPHER_NOTUSE ||
pMbss->WpaMixPairCipher == WPA_TKIPAES_WPA2_NONE ||
pMbss->WpaMixPairCipher == WPA_NONE_WPA2_TKIPAES)
pMbss->WpaMixPairCipher = WPA_TKIPAES_WPA2_TKIPAES;
break;
}
}
else
pMbss->WpaMixPairCipher = MIX_CIPHER_NOTUSE;
/* Generate the corresponding RSNIE */
RTMPMakeRSNIE(pAd, pMbss->AuthMode, pMbss->WepStatus, MAIN_MBSSID + MIN_NET_DEVICE_FOR_P2P_GO);
#ifdef WSC_V2_SUPPORT
if (pMbss->WscControl.WscV2Info.bEnableWpsV2)
{
/*
WPS V2 doesn't support WEP and WPA/WPAPSK-TKIP.
*/
if ((pMbss->WepStatus == Ndis802_11WEPEnabled) || (pMbss->WepStatus == Ndis802_11Encryption2Enabled))
WscOnOff(pAd, MAIN_MBSSID | MIN_NET_DEVICE_FOR_P2P_GO, TRUE);
else
WscOnOff(pAd, MAIN_MBSSID | MIN_NET_DEVICE_FOR_P2P_GO, FALSE);
}
#endif /* WSC_V2_SUPPORT */
}
if (INFRA_ON(pAd) && (pAd->StaActive.SupportedHtPhy.ChannelWidth == BW_40) &&
(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA != pAd->StaActive.SupportedHtPhy.ExtChanOffset))
pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = pAd->StaActive.SupportedHtPhy.ExtChanOffset;
N_ChannelCheck(pAd);
#ifdef DOT11_N_SUPPORT
RTMPSetPhyMode(pAd, pAd->CommonCfg.PhyMode);
P2P_GoSetCommonHT(pAd);
#endif /* DOT11_N_SUPPORT */
{
#ifdef DOT11_N_SUPPORT
if (WMODE_CAP_N(pAd->CommonCfg.PhyMode) && (pAd->Antenna.field.TxPath == 2))
rtmp_bbp_set_txdac(pAd, 2);
else
#endif /* DOT11_N_SUPPORT */
rtmp_bbp_set_txdac(pAd, 0);
}
/* Receiver Antenna selection, write to BBP R3(bit4:3) */
rtmp_bbp_set_rxpath(pAd, pAd->Antenna.field.RxPath);
if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
{
if (WMODE_CAP_N(pAd->CommonCfg.PhyMode) || bWmmCapable)
{
/* EDCA parameters used for AP's own transmission */
pAd->CommonCfg.APEdcaParm.bValid = TRUE;
pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
pAd->CommonCfg.APEdcaParm.Txop[2] = 94; /*96; */
pAd->CommonCfg.APEdcaParm.Txop[3] = 47; /*48; */
AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
/* EDCA parameters to be annouced in outgoing BEACON, used by WMM STA */
pAd->ApCfg.BssEdcaParm.bValid = TRUE;
pAd->ApCfg.BssEdcaParm.Aifsn[0] = 3;
pAd->ApCfg.BssEdcaParm.Aifsn[1] = 7;
pAd->ApCfg.BssEdcaParm.Aifsn[2] = 2;
pAd->ApCfg.BssEdcaParm.Aifsn[3] = 2;
pAd->ApCfg.BssEdcaParm.Cwmin[0] = 4;
pAd->ApCfg.BssEdcaParm.Cwmin[1] = 4;
pAd->ApCfg.BssEdcaParm.Cwmin[2] = 3;
pAd->ApCfg.BssEdcaParm.Cwmin[3] = 2;
pAd->ApCfg.BssEdcaParm.Cwmax[0] = 10;
pAd->ApCfg.BssEdcaParm.Cwmax[1] = 10;
pAd->ApCfg.BssEdcaParm.Cwmax[2] = 4;
pAd->ApCfg.BssEdcaParm.Cwmax[3] = 3;
pAd->ApCfg.BssEdcaParm.Txop[0] = 0;
pAd->ApCfg.BssEdcaParm.Txop[1] = 0;
pAd->ApCfg.BssEdcaParm.Txop[2] = 94; /*96; */
pAd->ApCfg.BssEdcaParm.Txop[3] = 47; /*48; */
}
else
AsicSetEdcaParm(pAd, NULL);
}
#ifdef DOT11_N_SUPPORT
if (!WMODE_CAP_N(pAd->CommonCfg.PhyMode))
{
/* Patch UI */
pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = BW_20;
}
/* init */
if (pAd->CommonCfg.bRdg)
{
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
AsicEnableRDG(pAd);
}
else
{
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
AsicDisableRDG(pAd);
}
#endif /* DOT11_N_SUPPORT */
AsicSetBssid(pAd, pAd->CurrentAddress);
AsicSetMcastWC(pAd);
/* In AP mode, First WCID Table in ASIC will never be used. To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here. */
/* p.s ASIC use all 0xff as termination of WCID table search. */
RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
RTMP_IO_WRITE32(pAd, MAC_WCID_BASE+4, 0x0);
/* reset WCID table */
for (idx=2; idx<255; idx++)
{
offset = MAC_WCID_BASE + (idx * HW_WCID_ENTRY_SIZE);
RTMP_IO_WRITE32(pAd, offset, 0x0);
RTMP_IO_WRITE32(pAd, offset+4, 0x0);
}
pAd->MacTab.Content[0].Addr[0] = 0x01;
pAd->MacTab.Content[0].HTPhyMode.field.MODE = MODE_OFDM;
pAd->MacTab.Content[0].HTPhyMode.field.MCS = 3;
/*pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;*/
pAd->P2PChannel = pAd->CommonCfg.Channel;
AsicBBPAdjust(pAd);
/* Clear BG-Protection flag */
OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
if (WMODE_CAP_N(pAd->CommonCfg.PhyMode) &&
pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
N_SetCenCh(pAd, pAd->CommonCfg.Channel);
AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
MlmeSetTxPreamble(pAd, (USHORT)pAd->CommonCfg.TxPreamble);
MlmeUpdateTxRates(pAd, FALSE, MIN_NET_DEVICE_FOR_P2P_GO);
#ifdef DOT11_N_SUPPORT
if (WMODE_CAP_N(pAd->CommonCfg.PhyMode))
MlmeUpdateHtTxRates(pAd, MIN_NET_DEVICE_FOR_P2P_GO);
#endif /* DOT11_N_SUPPORT */
/* Disable Protection first. */
if (!INFRA_ON(pAd))
AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
APUpdateCapabilityAndErpIe(pAd);
#ifdef DOT11_N_SUPPORT
APUpdateOperationMode(pAd);
#endif /* DOT11_N_SUPPORT */
#ifdef DOT11_N_SUPPORT
#endif /* DOT11_N_SUPPORT */
#ifdef LED_CONTROL_SUPPORT
/* Set LED */
RTMPSetLED(pAd, LED_LINK_UP);
#endif /* LED_CONTROL_SUPPORT */
/* Initialize security variable per entry,
1. pairwise key table, re-set all WCID entry as NO-security mode.
2. access control port status
*/
for (idx=2; idx<MAX_LEN_OF_MAC_TABLE; idx++)
{
pAd->MacTab.Content[idx].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
AsicRemovePairwiseKeyEntry(pAd, (UCHAR)idx);
}
{
USHORT Wcid = 0;
PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID];
pMbss->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
if (IS_WPA_CAPABILITY(pMbss->AuthMode))
{
pMbss->DefaultKeyId = 1;
}
/* Get a specific WCID to record this MBSS key attribute */
GET_GroupKey_WCID(pAd, Wcid, MAIN_MBSSID);
/* When WEP, TKIP or AES is enabled, set group key info to Asic */
if (pMbss->WepStatus == Ndis802_11WEPEnabled)
{
UCHAR CipherAlg;
UCHAR idx_len;
for (idx=0; idx < SHARE_KEY_NUM; idx++)
{
CipherAlg = pAd->SharedKey[MAIN_MBSSID + 1][idx].CipherAlg;
if (pAd->SharedKey[MAIN_MBSSID + 1][idx].KeyLen > 0)
{
/* Set key material to Asic */
AsicAddSharedKeyEntry(pAd, MAIN_MBSSID + 1, idx, &pAd->SharedKey[MAIN_MBSSID + 1][idx]);
if (idx == pMbss->DefaultKeyId)
{
/* Generate 3-bytes IV randomly for software encryption using */
for(idx_len = 0; idx_len < LEN_WEP_TSC; idx_len++)
pAd->SharedKey[MAIN_MBSSID + 1][idx].TxTsc[idx_len] = RandomByte(pAd);
/* Update WCID attribute table and IVEIV table */
RTMPSetWcidSecurityInfo(pAd,
MAIN_MBSSID + 1,
idx,
CipherAlg,
Wcid,
SHAREDKEYTABLE);
}
}
}
}
else if ((pMbss->WepStatus == Ndis802_11Encryption2Enabled) ||
(pMbss->WepStatus == Ndis802_11Encryption3Enabled) ||
(pMbss->WepStatus == Ndis802_11Encryption4Enabled))
{
/* Generate GMK and GNonce randomly per MBSS */
GenRandom(pAd, pMbss->Bssid, pMbss->GMK);
GenRandom(pAd, pMbss->Bssid, pMbss->GNonce);
/* Derive GTK per BSSID */
WpaDeriveGTK(pMbss->GMK,
(UCHAR*)pMbss->GNonce,
pMbss->Bssid,
pMbss->GTK,
LEN_TKIP_GTK);
/* Install Shared key */
WPAInstallSharedKey(pAd,
pMbss->GroupKeyWepStatus,
MAIN_MBSSID + 1,
pMbss->DefaultKeyId,
Wcid,
TRUE,
pMbss->GTK,
LEN_TKIP_GTK);
}
#ifdef WAPI_SUPPORT
else if (pMbss->WepStatus == Ndis802_11EncryptionSMS4Enabled)
{
INT cnt;
/* Initial the related variables */
pMbss->DefaultKeyId = 0;
NdisMoveMemory(pMbss->key_announce_flag, AE_BCAST_PN, LEN_WAPI_TSC);
if (IS_HW_WAPI_SUPPORT(pAd))
pMbss->sw_wpi_encrypt = FALSE;
else
pMbss->sw_wpi_encrypt = TRUE;
/* Generate NMK randomly */
for (cnt = 0; cnt < LEN_WAPI_NMK; cnt++)
pMbss->NMK[cnt] = RandomByte(pAd);
/* Count GTK for this BSSID */
RTMPDeriveWapiGTK(pMbss->NMK, pMbss->GTK);
/* Install Shared key */
WAPIInstallSharedKey(pAd,
pMbss->GroupKeyWepStatus,
MAIN_MBSSID + 1,
pMbss->DefaultKeyId,
Wcid,
pMbss->GTK);
}
#endif /* WAPI_SUPPORT */
#ifdef DOT1X_SUPPORT
/* Send singal to daemon to indicate driver had restarted */
if ((pMbss->AuthMode == Ndis802_11AuthModeWPA) || (pMbss->AuthMode == Ndis802_11AuthModeWPA2)
|| (pMbss->AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pMbss->IEEE8021X == TRUE))
{
;/*bDot1xReload = TRUE; */
}
#endif /* DOT1X_SUPPORT */
DBGPRINT(RT_DEBUG_TRACE, ("### BSS(%d) AuthMode(%d)=%s, WepStatus(%d)=%s , AccessControlList.Policy=%ld\n", MAIN_MBSSID + 1, pMbss->AuthMode, GetAuthMode(pMbss->AuthMode),
pMbss->WepStatus, GetEncryptType(pMbss->WepStatus), pMbss->AccessControlList.Policy));
#ifdef DOT1X_SUPPORT
/* Send internal command to DOT1X daemon for reloading configuration */
/*
if (bDot1xReload)
DOT1X_InternalCmdAction(pAd, NULL, DOT1X_RELOAD_CONFIG);
*/
#endif /* DOT1X_SUPPORT */
/* Disable Protection first. */
/*AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE); */
#ifdef PIGGYBACK_SUPPORT
RTMPSetPiggyBack(pAd, pAd->CommonCfg.bPiggyBackCapable);
#endif /* PIGGYBACK_SUPPORT */
ApLogEvent(pAd, pAd->CurrentAddress, EVENT_RESET_ACCESS_POINT);
#if defined(WSC_AP_SUPPORT) || defined(WSC_STA_SUPPORT)
{
PWSC_CTRL pWscControl;
UCHAR zeros16[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
pWscControl = &pAd->ApCfg.MBSSID[MAIN_MBSSID].WscControl;
DBGPRINT(RT_DEBUG_TRACE, ("Generate UUID for apidx(%d)\n", MAIN_MBSSID));
if (NdisEqualMemory(&pWscControl->Wsc_Uuid_E[0], zeros16, UUID_LEN_HEX))
WscGenerateUUID(pAd, &pWscControl->Wsc_Uuid_E[0], &pWscControl->Wsc_Uuid_Str[0], MIN_NET_DEVICE_FOR_P2P_GO, FALSE);
WscInit(pAd, FALSE, MIN_NET_DEVICE_FOR_P2P_GO);
}
#endif /* defined(WSC_AP_SUPPORT) || defined(WSC_STA_SUPPORT) */
}
OPSTATUS_SET_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED);
RTMP_IndicateMediaState(pAd, NdisMediaStateConnected);
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
#ifdef RTMP_MAC_USB
RTUSBBssBeaconInit(pAd);
#endif /* RTMP_MAC_USB */
/*pAd->Dot11_H.RDMode = RD_NORMAL_MODE;*/
/*AsicEnableP2PGoSync(pAd); */
/* start sending BEACON out */
APMakeAllBssBeacon(pAd);
APUpdateAllBeaconFrame(pAd);
/*AsicEnableP2PGoSync(pAd); */
{
pAd->Dot11_H.RDMode = RD_NORMAL_MODE;
AsicEnableP2PGoSync(pAd);
#ifdef CONFIG_AP_SUPPORT
#ifdef CARRIER_DETECTION_SUPPORT
#ifdef A_BAND_SUPPORT
if (pAd->CommonCfg.Channel > 14)
{
if ((pAd->CommonCfg.CarrierDetect.Enable == 0)
&& ((pAd->CommonCfg.RDDurRegion == JAP)
|| (pAd->CommonCfg.RDDurRegion == JAP_W53)
|| (pAd->CommonCfg.RDDurRegion == JAP_W56)))
{
pAd->CommonCfg.CarrierDetect.Enable = 1;
}
}
else
#endif /* A_BAND_SUPPORT */
{
if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)
{
if ((pAd->CommonCfg.CarrierDetect.Enable == 0)
&& ((pAd->CommonCfg.RDDurRegion == JAP)
|| (pAd->CommonCfg.RDDurRegion == JAP_W53)
|| (pAd->CommonCfg.RDDurRegion == JAP_W56)))
{
pAd->CommonCfg.CarrierDetect.Enable = 1;
}
}
}
if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
{
/* trun on Carrier-Detection.*/
CarrierDetectionStart(pAd);
}
#endif /* CARRIER_DETECTION_SUPPORT */
#endif /* CONFIG_AP_SUPPORT */
}
#ifdef WAPI_SUPPORT
RTMPStartWapiRekeyTimerAction(pAd, NULL);
#endif /* WAPI_SUPPORT */
/* Pre-tbtt interrupt setting. */
AsicSetPreTbttInt(pAd, TRUE);
/* Set group re-key timer if necessary.
It must be processed after clear flag "fRTMP_ADAPTER_HALT_IN_PROGRESS" */
WPA_APSetGroupRekeyAction(pAd);
#ifdef IDS_SUPPORT
/* Start IDS timer */
if (pAd->ApCfg.IdsEnable)
{
#ifdef SYSTEM_LOG_SUPPORT
if (pAd->CommonCfg.bWirelessEvent == FALSE)
DBGPRINT(RT_DEBUG_WARN, ("!!! WARNING !!! The WirelessEvent parameter doesn't be enabled \n"));
#endif /* SYSTEM_LOG_SUPPORT */
RTMPIdsStart(pAd);
}
#endif /* IDS_SUPPORT */
#ifdef RTMP_MAC_USB
/*
* Support multiple BulkIn IRP,
* the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
*/
{
UCHAR num_idx;
for(num_idx=0; num_idx < pAd->CommonCfg.NumOfBulkInIRP; num_idx++)
{
RTUSBBulkReceive(pAd);
DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
}
}
#endif /* RTMP_MAC_USB */
/* Start respons Auth Req. */
pAd->P2pCfg.bStopAuthRsp = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("<=== P2P_GoStartUp\n"));
}
VOID P2P_GoStop(
IN PRTMP_ADAPTER pAd)
{
BOOLEAN Cancelled;
UINT32 Value;
INT apidx;
DBGPRINT(RT_DEBUG_TRACE, ("===> P2P_GoStop\n"));
pAd->P2pCfg.P2pCapability[1] &= ~(GRPCAP_OWNER);
pAd->flg_p2p_OpStatusFlags &= P2P_FIXED_MODE;
pAd->P2pCfg.Rule = P2P_IS_DEVICE;
pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = FALSE;
APMakeAllBssBeacon(pAd);
APUpdateAllBeaconFrame(pAd);
#ifdef DFS_SUPPORT
NewRadarDetectionStop(pAd);
#endif /* DFS_SUPPORT */
P2PMacTableReset(pAd);
/* Disable pre-tbtt interrupt */
RTMP_IO_READ32(pAd, INT_TIMER_EN, &Value);
Value &=0xe;
RTMP_IO_WRITE32(pAd, INT_TIMER_EN, Value);
if (!INFRA_ON(pAd))
{
/* Disable piggyback */
RTMPSetPiggyBack(pAd, FALSE);
AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
}
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
{
/*RTMP_ASIC_INTERRUPT_DISABLE(pAd); */
AsicDisableSync(pAd);
#ifdef LED_CONTROL_SUPPORT
/* Set LED */
RTMPSetLED(pAd, LED_LINK_DOWN);
#endif /* LED_CONTROL_SUPPORT */
}
#ifdef RTMP_MAC_USB
/* For RT2870, we need to clear the beacon sync buffer. */
RTUSBBssBeaconExit(pAd);
#endif /* RTMP_MAC_USB */
for (apidx = 0; apidx < MAX_MBSSID_NUM(pAd); apidx++)
{
if (pAd->ApCfg.MBSSID[apidx].REKEYTimerRunning == TRUE)
{
RTMPCancelTimer(&pAd->ApCfg.MBSSID[apidx].REKEYTimer, &Cancelled);
pAd->ApCfg.MBSSID[apidx].REKEYTimerRunning = FALSE;
}
}
if (pAd->ApCfg.CMTimerRunning == TRUE)
{
RTMPCancelTimer(&pAd->ApCfg.CounterMeasureTimer, &Cancelled);
pAd->ApCfg.CMTimerRunning = FALSE;
}
#ifdef WAPI_SUPPORT
RTMPCancelWapiRekeyTimerAction(pAd, NULL);
#endif /* WAPI_SUPPORT */
/*
* Cancel the Timer, to make sure the timer was not queued.
*/
OPSTATUS_CLEAR_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED);
RTMP_IndicateMediaState(pAd, NdisMediaStateDisconnected);
#ifdef IDS_SUPPORT
/* if necessary, cancel IDS timer */
RTMPIdsStop(pAd);
#endif /* IDS_SUPPORT */
DBGPRINT(RT_DEBUG_TRACE, ("<=== P2P_GoStop\n"));
}
VOID P2P_CliStartUp(
IN PRTMP_ADAPTER pAd)
{
UCHAR ifIndex;
PAPCLI_STRUCT pApCliEntry;
/* Reset is in progress, stop immediately */
if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
return;
/* sanity check whether the interface is initialized. */
if (pAd->flg_apcli_init != TRUE)
return;
pAd->P2pCfg.P2pCapability[1] &= ~(GRPCAP_OWNER);
pAd->flg_p2p_OpStatusFlags = P2P_CLI_UP;
pAd->P2pCfg.Rule = P2P_IS_CLIENT;
pAd->StaCfg.bAutoReconnect = FALSE;
AsicSetBssid(pAd, pAd->CurrentAddress);
AsicSetMcastWC(pAd);
for(ifIndex = 0; ifIndex < MAX_APCLI_NUM; ifIndex++)
{
pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
if (pAd->CommonCfg.Channel != 0)
pAd->P2PChannel = pAd->CommonCfg.Channel;
else
pAd->P2PChannel = FirstChannel(pAd);
if (APCLI_IF_UP_CHECK(pAd, ifIndex)
&& (pApCliEntry->Enable == TRUE)
&& (pApCliEntry->Valid == FALSE))
{
DBGPRINT(RT_DEBUG_TRACE, ("(%s) ApCli interface[%d] startup.\n", __FUNCTION__, ifIndex));
MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_JOIN_REQ, 0, NULL, ifIndex);
}
}
OPSTATUS_SET_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED);
return;
}
VOID P2P_CliStop(
IN PRTMP_ADAPTER pAd)
{
UCHAR ifIndex;
DBGPRINT(RT_DEBUG_TRACE, ("%s: ===>\n", __FUNCTION__));
/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_P2P_CLI); */
pAd->flg_p2p_OpStatusFlags = P2P_DISABLE;
pAd->P2pCfg.Rule = P2P_IS_DEVICE;
for (ifIndex = 0; ifIndex < MAX_APCLI_NUM; ifIndex++)
{
/* send disconnect-req to sta State Machine. */
if (pAd->ApCfg.ApCliTab[ifIndex].Enable)
{
MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, ifIndex);
RTMP_MLME_HANDLER(pAd);
DBGPRINT(RT_DEBUG_TRACE, ("(%s) ApCli interface[%d] startdown.\n", __FUNCTION__, ifIndex));
}
}
OPSTATUS_CLEAR_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED);
}
/*
==========================================================================
Description:
This routine is called by APMlmePeriodicExec() every second to check if
1. any associated client in PSM. If yes, then TX MCAST/BCAST should be
out in DTIM only
2. any client being idle for too long and should be aged-out from MAC table
3. garbage collect PSQ
==========================================================================
*/
VOID P2PMacTableMaintenance(
IN PRTMP_ADAPTER pAd)
{
int i, FirstWcid;
#ifdef DOT11_N_SUPPORT
ULONG MinimumAMPDUSize = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor; /*Default set minimum AMPDU Size to 2, i.e. 32K */
BOOLEAN bRdgActive;
#endif /* DOT11_N_SUPPORT */
UINT fAnyStationPortSecured[MAX_MBSSID_NUM(pAd)];
UINT bss_index;
MAC_TABLE *pMacTable;
FirstWcid = 2;
for (bss_index = BSS0; bss_index < MAX_MBSSID_NUM(pAd); bss_index++)
fAnyStationPortSecured[bss_index] = 0;
pMacTable = &pAd->MacTab;
pMacTable->fAnyStationInPsm = FALSE;
pMacTable->fAnyStationBadAtheros = FALSE;
pMacTable->fAnyTxOPForceDisable = FALSE;
pMacTable->fAllStationAsRalink = TRUE;
#ifdef DOT11_N_SUPPORT
pMacTable->fAnyStationNonGF = FALSE;
pMacTable->fAnyStation20Only = FALSE;
pMacTable->fAnyStationIsLegacy = FALSE;
pMacTable->fAnyStationMIMOPSDynamic = FALSE;
#ifdef GREENAP_SUPPORT
//Support Green AP
pMacTable->fAnyStationIsHT=FALSE;
#endif /* GREENAP_SUPPORT */
#ifdef DOT11N_DRAFT3
pMacTable->fAnyStaFortyIntolerant = FALSE;
#endif /* DOT11N_DRAFT3 */
#endif /* DOT11_N_SUPPORT */
#ifdef WAPI_SUPPORT
pMacTable->fAnyWapiStation = FALSE;
#endif /* WAPI_SUPPORT */
for (i = FirstWcid; i < MAX_LEN_OF_MAC_TABLE; i++)
{
MAC_TABLE_ENTRY *pEntry = &pMacTable->Content[i];
BOOLEAN bDisconnectSta = FALSE;
if (!IS_ENTRY_CLIENT(pEntry))
continue;
if (pEntry->NoDataIdleCount == 0)
pEntry->StationKeepAliveCount = 0;
pEntry->NoDataIdleCount ++;
pEntry->StaConnectTime ++;
/* 0. STA failed to complete association should be removed to save MAC table space. */
if ((pEntry->Sst != SST_ASSOC) && (pEntry->NoDataIdleCount >= pEntry->AssocDeadLine))
{
DBGPRINT(RT_DEBUG_TRACE, ("%02x:%02x:%02x:%02x:%02x:%02x fail to complete ASSOC in %d sec\n",
pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3],
pEntry->Addr[4],pEntry->Addr[5],MAC_TABLE_ASSOC_TIMEOUT));
MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
continue;
}
/* 1. check if there's any associated STA in power-save mode. this affects outgoing */
/* MCAST/BCAST frames should be stored in PSQ till DtimCount=0 */
if (pEntry->PsMode == PWR_SAVE)
pMacTable->fAnyStationInPsm = TRUE;
#ifdef DOT11_N_SUPPORT
if (pEntry->MmpsMode == MMPS_DYNAMIC)
{
pMacTable->fAnyStationMIMOPSDynamic = TRUE;
}
if (pEntry->MaxHTPhyMode.field.BW == BW_20)
pMacTable->fAnyStation20Only = TRUE;
if (pEntry->MaxHTPhyMode.field.MODE != MODE_HTGREENFIELD)
pMacTable->fAnyStationNonGF = TRUE;
if ((pEntry->MaxHTPhyMode.field.MODE == MODE_OFDM) || (pEntry->MaxHTPhyMode.field.MODE == MODE_CCK))
{
pMacTable->fAnyStationIsLegacy = TRUE;
}
#ifdef GREENAP_SUPPORT
else
{
pMacTable->fAnyStationIsHT=TRUE;
}
#endif /* GREENAP_SUPPORT */
#ifdef DOT11N_DRAFT3
if (pEntry->bForty_Mhz_Intolerant)
pMacTable->fAnyStaFortyIntolerant = TRUE;
#endif /* DOT11N_DRAFT3 */
/* Get minimum AMPDU size from STA */
if (MinimumAMPDUSize > pEntry->MaxRAmpduFactor)
{
MinimumAMPDUSize = pEntry->MaxRAmpduFactor;
}
#endif /* DOT11_N_SUPPORT */
if (pEntry->bIAmBadAtheros)
{
pMacTable->fAnyStationBadAtheros = TRUE;
if (!INFRA_ON(pAd))
{
#ifdef DOT11_N_SUPPORT
if (pAd->CommonCfg.IOTestParm.bRTSLongProtOn == FALSE)
AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, FALSE, pMacTable->fAnyStationNonGF);
#endif /* DOT11_N_SUPPORT */
#ifndef DOT11N_SS3_SUPPORT
if (pEntry->WepStatus != Ndis802_11EncryptionDisabled)
{
pMacTable->fAnyTxOPForceDisable = TRUE;
}
#endif /* DOT11N_SS3_SUPPORT */
}
}
/* detect the station alive status */
/* detect the station alive status */
pAd->ApCfg.MBSSID[pEntry->apidx].StationKeepAliveTime = 3;
if ((pAd->ApCfg.MBSSID[pEntry->apidx].StationKeepAliveTime > 0) &&
(pEntry->NoDataIdleCount >= pAd->ApCfg.MBSSID[pEntry->apidx].StationKeepAliveTime))
{
MULTISSID_STRUCT *pMbss = &pAd->ApCfg.MBSSID[pEntry->apidx];
/*
If no any data success between ap and the station for
StationKeepAliveTime, try to detect whether the station is
still alive.
Note: Just only keepalive station function, no disassociation
function if too many no response.
*/
/*
For example as below:
1. Station in ACTIVE mode,
......
sam> tx ok!
sam> count = 1! ==> 1 second after the Null Frame is acked
sam> count = 2! ==> 2 second after the Null Frame is acked
sam> count = 3!
sam> count = 4!
sam> count = 5!
sam> count = 6!
sam> count = 7!
sam> count = 8!
sam> count = 9!
sam> count = 10!
sam> count = 11!
sam> count = 12!
sam> count = 13!
sam> count = 14!
sam> count = 15! ==> 15 second after the Null Frame is acked
sam> tx ok! ==> (KeepAlive Mechanism) send a Null Frame to
detect the STA life status
sam> count = 1! ==> 1 second after the Null Frame is acked
sam> count = 2!
sam> count = 3!
sam> count = 4!
......
If the station acknowledges the QoS Null Frame,
the NoDataIdleCount will be reset to 0.
2. Station in legacy PS mode,
We will set TIM bit after 15 seconds, the station will send a
PS-Poll frame and we will send a QoS Null frame to it.
If the station acknowledges the QoS Null Frame, the
NoDataIdleCount will be reset to 0.
3. Station in legacy UAPSD mode,
Currently we dont support the keep alive mechanism.
So if your station is in UAPSD mode, the station will be
kicked out after 300 seconds.
Note: the rate of QoS Null frame can not be 1M of 2.4GHz or
6M of 5GHz, or no any statistics count will occur.
*/
if (pEntry->StationKeepAliveCount++ == 0)
{
#ifdef P2P_SUPPORT
/* Modify for P2P test plan 6.1.11 /6.1.12, enqueue null frame will influence the test item */
if (pAd->P2pCfg.bSigmaEnabled == FALSE)
{
#endif /* P2P_SUPPORT */
if (pEntry->PsMode == PWR_SAVE)
{
/* use TIM bit to detect the PS station */
WLAN_MR_TIM_BIT_SET(pAd, pEntry->apidx, pEntry->Aid);
}
else
{
/* use Null or QoS Null to detect the ACTIVE station */
BOOLEAN bQosNull = FALSE;
if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
bQosNull = TRUE;
ApEnqueueNullFrame(pAd, pEntry->Addr, pEntry->CurrTxRate,
pEntry->Aid, pEntry->apidx, bQosNull, TRUE, 0);
}
#ifdef P2P_SUPPORT
}
#endif /* P2P_SUPPORT */
}
else
{
if (pEntry->StationKeepAliveCount >= pMbss->StationKeepAliveTime)
pEntry->StationKeepAliveCount = 0;
}
}
/* 2. delete those MAC entry that has been idle for a long time */
if (pEntry->NoDataIdleCount >= pEntry->StaIdleTimeout)
{
bDisconnectSta = TRUE;
DBGPRINT(RT_DEBUG_WARN, ("ageout %02x:%02x:%02x:%02x:%02x:%02x after %d-sec silence\n",
pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3],
pEntry->Addr[4],pEntry->Addr[5],pEntry->StaIdleTimeout));
ApLogEvent(pAd, pEntry->Addr, EVENT_AGED_OUT);
}
else if (pEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck)
{
/*
AP have no way to know that the PwrSaving STA is leaving or not.
So do not disconnect for PwrSaving STA.
*/
if (pEntry->PsMode != PWR_SAVE)
{
bDisconnectSta = TRUE;
DBGPRINT(RT_DEBUG_WARN, ("STA-%02x:%02x:%02x:%02x:%02x:%02x had left\n",
pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3],
pEntry->Addr[4],pEntry->Addr[5]));
}
}
if (bDisconnectSta)
{
/* send wireless event - for ageout */
RTMPSendWirelessEvent(pAd, IW_AGEOUT_EVENT_FLAG, pEntry->Addr, 0, 0);
if (pEntry->Sst == SST_ASSOC)
{
PUCHAR pOutBuffer = NULL;
NDIS_STATUS NStatus;
ULONG FrameLen = 0;
HEADER_802_11 DeAuthHdr;
USHORT Reason;
/* send out a DISASSOC request frame */
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
if (NStatus != NDIS_STATUS_SUCCESS)
{
DBGPRINT(RT_DEBUG_TRACE, (" MlmeAllocateMemory fail ..\n"));
/*NdisReleaseSpinLock(&pAd->MacTabLock); */
continue;
}
Reason = REASON_DEAUTH_STA_LEAVING;
DBGPRINT(RT_DEBUG_WARN, ("Send DEAUTH - Reason = %d frame TO %02x:%02x:%02x:%02x:%02x:%02x. \n",Reason, PRINT_MAC(pEntry->Addr)));
MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0, pEntry->Addr,
#ifdef P2P_SUPPORT
pAd->ApCfg.MBSSID[pEntry->apidx].Bssid,
#endif /* P2P_SUPPORT */
pAd->ApCfg.MBSSID[pEntry->apidx].Bssid);
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(HEADER_802_11), &DeAuthHdr,
2, &Reason,
END_OF_ARGS);
MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer);
}
MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
continue;
}
/* 3. garbage collect the PsQueue if the STA has being idle for a while */
if (pEntry->PsQueue.Head)
{
pEntry->PsQIdleCount ++;
if (pEntry->PsQIdleCount > 2)
{
NdisAcquireSpinLock(&pAd->irq_lock);
APCleanupPsQueue(pAd, &pEntry->PsQueue);
NdisReleaseSpinLock(&pAd->irq_lock);
pEntry->PsQIdleCount = 0;
WLAN_MR_TIM_BIT_CLEAR(pAd, pEntry->apidx, pEntry->Aid);
}
}
else
pEntry->PsQIdleCount = 0;
#ifdef UAPSD_SUPPORT
UAPSD_QueueMaintenance(pAd, pEntry);
#endif /* UAPSD_SUPPORT */
/* check if this STA is Ralink-chipset */
if (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET))
pMacTable->fAllStationAsRalink = FALSE;
/* Check if the port is secured */
if (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
fAnyStationPortSecured[pEntry->apidx]++;
#ifdef DOT11_N_SUPPORT
#ifdef DOT11N_DRAFT3
if ((pEntry->BSS2040CoexistenceMgmtSupport)
&& (pAd->CommonCfg.Bss2040CoexistFlag & BSS_2040_COEXIST_INFO_NOTIFY)
&& (pAd->CommonCfg.bBssCoexEnable == TRUE)
)
{
SendNotifyBWActionFrame(pAd, pEntry->Aid, pEntry->apidx);
}
#endif /* DOT11N_DRAFT3 */
#endif /* DOT11_N_SUPPORT */
#ifdef WAPI_SUPPORT
if (pEntry->WepStatus == Ndis802_11EncryptionSMS4Enabled)
pMacTable->fAnyWapiStation = TRUE;
#endif /* WAPI_SUPPORT */
}
/* Update the state of port per MBSS */
for (bss_index = BSS0; bss_index < MAX_MBSSID_NUM(pAd); bss_index++)
{
if (fAnyStationPortSecured[bss_index] > 0)
{
pAd->ApCfg.MBSSID[bss_index].PortSecured = WPA_802_1X_PORT_SECURED;
}
else
pAd->ApCfg.MBSSID[bss_index].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
}
#ifdef DOT11_N_SUPPORT
#ifdef DOT11N_DRAFT3
if (pAd->CommonCfg.Bss2040CoexistFlag & BSS_2040_COEXIST_INFO_NOTIFY)
pAd->CommonCfg.Bss2040CoexistFlag &= (~BSS_2040_COEXIST_INFO_NOTIFY);
#endif /* DOT11N_DRAFT3 */
/* If all associated STAs are Ralink-chipset, AP shall enable RDG. */
if (pAd->CommonCfg.bRdg && pMacTable->fAllStationAsRalink)
{
bRdgActive = TRUE;
}
else
{
bRdgActive = FALSE;
}
#ifdef DOT11_N_SUPPORT
#ifdef GREENAP_SUPPORT
if (WMODE_CAP_N(pAd->CommonCfg.PhyMode))
{
if(pAd->MacTab.fAnyStationIsHT==FALSE
&& pAd->ApCfg.bGreenAPEnable == TRUE)
{
if (pAd->ApCfg.GreenAPLevel!=GREENAP_ONLY_11BG_STAS)
{
RTMP_CHIP_ENABLE_AP_MIMOPS(pAd, FALSE);
pAd->ApCfg.GreenAPLevel=GREENAP_ONLY_11BG_STAS;
}
}
else
{
if (pAd->ApCfg.GreenAPLevel!=GREENAP_11BGN_STAS)
{
RTMP_CHIP_DISABLE_AP_MIMOPS(pAd);
pAd->ApCfg.GreenAPLevel=GREENAP_11BGN_STAS;
}
}
}
#endif /* GREENAP_SUPPORT */
if (bRdgActive != RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE))
{
if (bRdgActive)
{
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
AsicEnableRDG(pAd);
}
else
{
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
AsicDisableRDG(pAd);
}
}
#endif /* DOT11_N_SUPPORT */
if (!INFRA_ON(pAd))
{
if ((pMacTable->fAnyStationBadAtheros == FALSE) && (pAd->CommonCfg.IOTestParm.bRTSLongProtOn == TRUE))
{
AsicUpdateProtect(pAd, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, pMacTable->fAnyStationNonGF);
}
}
#endif /* DOT11_N_SUPPORT */
/*
* 4. garbage collect pAd->MacTab.McastPsQueue if backlogged MCAST/BCAST frames
* stale in queue. Since MCAST/BCAST frames always been sent out whenever
* DtimCount==0, the only case to let them stale is surprise removal of the NIC,
* so that ASIC-based Tbcn interrupt stops and DtimCount dead.
*/
if (pMacTable->McastPsQueue.Head)
{
UINT bss_index;
pMacTable->PsQIdleCount ++;
if (pMacTable->PsQIdleCount > 1)
{
/*NdisAcquireSpinLock(&pAd->MacTabLock); */
APCleanupPsQueue(pAd, &pMacTable->McastPsQueue);
/*NdisReleaseSpinLock(&pAd->MacTabLock); */
pMacTable->PsQIdleCount = 0;
/* sanity check */
if (pAd->ApCfg.BssidNum > MAX_MBSSID_NUM(pAd))
pAd->ApCfg.BssidNum = MAX_MBSSID_NUM(pAd);
/* End of if */
/* clear MCAST/BCAST backlog bit for all BSS */
for(bss_index=BSS0; bss_index<pAd->ApCfg.BssidNum; bss_index++)
WLAN_MR_TIM_BCMC_CLEAR(bss_index);
/* End of for */
}
}
else
pMacTable->PsQIdleCount = 0;
}
VOID AsicEnableP2PGoSync(
IN PRTMP_ADAPTER pAd)
{
BCN_TIME_CFG_STRUC csr;
RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
/* start sending BEACON */
csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU */
csr.field.bTsfTicking = 1;
csr.field.TsfSyncMode = 3; /* sync TSF in IBSS mode */
csr.field.bTBTTEnable = 1;
csr.field.bBeaconGen = 1;
RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
}
VOID MgtMacP2PHeaderInit(
IN PRTMP_ADAPTER pAd,
IN OUT PHEADER_802_11 pHdr80211,
IN UCHAR SubType,
IN UCHAR ToDs,
IN PUCHAR pDA,
IN PUCHAR pBssid)
{
NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
pHdr80211->FC.Type = BTYPE_MGMT;
pHdr80211->FC.SubType = SubType;
pHdr80211->FC.ToDs = ToDs;
COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
COPY_MAC_ADDR(pHdr80211->Addr2, pBssid);
COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
}
/*
==========================================================================
Description:
This routine reset the entire MAC table. All packets pending in
the power-saving queues are freed here.
==========================================================================
*/
VOID P2PMacTableReset(
IN PRTMP_ADAPTER pAd)
{
int i, FirstWcid;
BOOLEAN Cancelled;
#ifdef CONFIG_AP_SUPPORT
PUCHAR pOutBuffer = NULL;
NDIS_STATUS NStatus;
ULONG FrameLen = 0;
HEADER_802_11 DeAuthHdr;
USHORT Reason;
UCHAR apidx = MAIN_MBSSID;
#endif /* CONFIG_AP_SUPPORT */
MAC_TABLE_ENTRY *pEntry = NULL;
DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
/*NdisAcquireSpinLock(&pAd->MacTabLock); */
FirstWcid = 2;
for (i = FirstWcid; i < MAX_LEN_OF_MAC_TABLE; i++)
{
pEntry = &pAd->MacTab.Content[i];
if (IS_ENTRY_CLIENT(pEntry))
{
/* Delete a entry via WCID */
/*MacTableDeleteEntry(pAd, i, pAd->MacTab.Content[i].Addr); */
RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
#ifdef CONFIG_STA_SUPPORT
#ifdef ADHOC_WPA2PSK_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
RTMPCancelTimer(&pEntry->WPA_Authenticator.MsgRetryTimer, &Cancelled);
}
#endif /* ADHOC_WPA2PSK_SUPPORT */
#endif /* CONFIG_STA_SUPPORT */
pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
#ifdef CONFIG_AP_SUPPORT
if ((pAd->OpMode == OPMODE_AP) || IS_P2P_GO_ENTRY(pEntry))
{
/* Before reset MacTable, send disassociation packet to client. */
if (pEntry->Sst == SST_ASSOC)
{
/* send out a De-authentication request frame */
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
if (NStatus != NDIS_STATUS_SUCCESS)
{
DBGPRINT(RT_DEBUG_TRACE, (" MlmeAllocateMemory fail ..\n"));
/*NdisReleaseSpinLock(&pAd->MacTabLock); */
return;
}
Reason = REASON_NO_LONGER_VALID;
DBGPRINT(RT_DEBUG_WARN, ("Send DEAUTH - Reason = %d frame tO %02x:%02x:%02x:%02x:%02x:%02x \n",
Reason, PRINT_MAC(pAd->MacTab.Content[i].Addr)));
MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0, pEntry->HdrAddr1,
#ifdef P2P_SUPPORT
pEntry->HdrAddr2,
#endif /* P2P_SUPPORT */
pEntry->HdrAddr3);
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(HEADER_802_11), &DeAuthHdr,
2, &Reason,
END_OF_ARGS);
MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer);
RTMPusecDelay(5000);
}
}
#endif /* CONFIG_AP_SUPPORT */
/* Delete a entry via WCID */
MacTableDeleteEntry(pAd, i, pEntry->Addr);
}
NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
}
#ifdef CONFIG_AP_SUPPORT
{
for (apidx = MAIN_MBSSID; apidx < pAd->ApCfg.BssidNum; apidx++)
{
#ifdef WSC_AP_SUPPORT
PWSC_CTRL pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
BOOLEAN Cancelled;
RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
pWscControl->EapolTimerRunning = FALSE;
NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN);
pWscControl->EapMsgRunning = FALSE;
#endif /* WSC_AP_SUPPORT */
pAd->ApCfg.MBSSID[apidx].StaCount = 0;
}
DBGPRINT(RT_DEBUG_TRACE, ("McastPsQueue.Number %ld...\n",pAd->MacTab.McastPsQueue.Number));
if (pAd->MacTab.McastPsQueue.Number > 0)
APCleanupPsQueue(pAd, &pAd->MacTab.McastPsQueue);
DBGPRINT(RT_DEBUG_TRACE, ("2McastPsQueue.Number %ld...\n",pAd->MacTab.McastPsQueue.Number));
/*NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE)); */
InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
}
#endif /* CONFIG_AP_SUPPORT */
return;
}
VOID P2PChannelInit(
IN PRTMP_ADAPTER pAd,
IN UCHAR ifIndex)
{
if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
{
#ifdef DOT11_N_SUPPORT
ADD_HTINFO RootApHtInfo, HtInfo;
HtInfo = pAd->CommonCfg.AddHTInfo.AddHtInfo;
RootApHtInfo = pAd->ApCliMlmeAux.AddHtInfo.AddHtInfo;
if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
(RootApHtInfo.RecomWidth) &&
(RootApHtInfo.ExtChanOffset != HtInfo.ExtChanOffset))
{
if (RootApHtInfo.ExtChanOffset == EXTCHA_ABOVE)
Set_HtExtcha_Proc(pAd, "1");
else
Set_HtExtcha_Proc(pAd, "0");
}
N_ChannelCheck(pAd);
#endif /* DOT11_N_SUPPORT */
{
AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
AsicLockChannel(pAd, pAd->CommonCfg.Channel);
}
}
}
VOID P2PCfgInit(
IN PRTMP_ADAPTER pAd)
{
UCHAR apcliIdx, apidx = MAIN_MBSSID;
pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeOpen;
pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11EncryptionDisabled;
pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus = Ndis802_11EncryptionDisabled;
pAd->ApCfg.MBSSID[apidx].DefaultKeyId = 0;
pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher = MIX_CIPHER_NOTUSE;
#ifdef DOT1X_SUPPORT
pAd->ApCfg.MBSSID[apidx].IEEE8021X = FALSE;
pAd->ApCfg.MBSSID[apidx].PreAuth = FALSE;
/* PMK cache setting */
pAd->ApCfg.MBSSID[apidx].PMKCachePeriod = (10 * 60 * OS_HZ); /* unit : tick(default: 10 minute) */
NdisZeroMemory(&pAd->ApCfg.MBSSID[apidx].PMKIDCache, sizeof(NDIS_AP_802_11_PMKID));
/* dot1x related per BSS */
pAd->ApCfg.MBSSID[apidx].radius_srv_num = 0;
pAd->ApCfg.MBSSID[apidx].NasIdLen = 0;
#endif /* DOT1X_SUPPORT */
/* VLAN related */
pAd->ApCfg.MBSSID[apidx].VLAN_VID = 0;
/* Default MCS as AUTO */
pAd->ApCfg.MBSSID[apidx].bAutoTxRateSwitch = TRUE;
pAd->ApCfg.MBSSID[apidx].DesiredTransmitSetting.field.MCS = MCS_AUTO;
/* Default is zero. It means no limit. */
pAd->ApCfg.MBSSID[apidx].MaxStaNum = 0;
pAd->ApCfg.MBSSID[apidx].StaCount = 0;
#ifdef P2P_SUPPORT
#ifdef APCLI_SUPPORT
for(apcliIdx = 0; apcliIdx < MAX_APCLI_NUM; apcliIdx++)
{
pAd->ApCfg.ApCliTab[apcliIdx].AuthMode = Ndis802_11AuthModeOpen;
pAd->ApCfg.ApCliTab[apcliIdx].WepStatus = Ndis802_11WEPDisabled;
}
#endif /* APCLI_SUPPORT */
#endif /* P2P_SUPPORT */
for(apcliIdx = 0; apcliIdx < WLAN_MAX_NUM_OF_TIM; apcliIdx++)
pAd->ApCfg.MBSSID[apidx].TimBitmaps[apcliIdx] = 0;
P2pGotoIdle(pAd);
/* P2P CLI/GO also update ApCfg.RssiSample for AsicAdjustTxPower() caculation*/
pAd->ApCfg.RssiSample.AvgRssi0 = -127;
pAd->ApCfg.RssiSample.AvgRssi1 = -127;
pAd->ApCfg.RssiSample.AvgRssi2 = -127;
}
VOID P2PInitChannelRelatedValue(
IN PRTMP_ADAPTER pAd)
{
UINT32 Data = 0, macStatus;
UINT32 MTxCycle, MRxCycle;
UCHAR rf_channel, rf_bw;
INT ext_ch;
//Disable MAC Tx/Rx
RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Data);
Data &= (~0x0C);
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Data);
// Check MAC Tx/Rx idle
for (MTxCycle = 0; MTxCycle < 10000; MTxCycle++)
{
RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &macStatus);
if (macStatus & 0x3)
RTMPusecDelay(50);
else
break;
}
pAd->CommonCfg.CentralChannel = pAd->ApCliMlmeAux.CentralChannel;
pAd->CommonCfg.Channel = pAd->ApCliMlmeAux.Channel;
#ifdef DOT11_N_SUPPORT
/* Change to AP channel */
DBGPRINT(RT_DEBUG_TRACE, ("CentralChannel = %d, Channel %d, BW = %d\n",
pAd->CommonCfg.CentralChannel, pAd->CommonCfg.Channel,
pAd->ApCliMlmeAux.HtCapability.HtCapInfo.ChannelWidth));
if ( (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) &&
(pAd->ApCliMlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
{
rf_channel = pAd->CommonCfg.CentralChannel;
rf_bw = BW_40;
ext_ch = EXTCHA_ABOVE;
}
else if ( (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) &&
(pAd->ApCliMlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
{
rf_channel = pAd->CommonCfg.CentralChannel;
rf_bw = BW_40;
ext_ch = EXTCHA_BELOW;
}
else
#endif /* DOT11_N_SUPPORT */
{
rf_channel = pAd->CommonCfg.Channel;
rf_bw = BW_20;
ext_ch = EXTCHA_NONE;
}
AsicSetChannel(pAd, rf_channel, rf_bw, ext_ch, FALSE);
DBGPRINT(RT_DEBUG_TRACE, ("%s():BW_%s, CtrlChannel=%d, CentralChannel=%d \n",
__FUNCTION__, (rf_bw == BW_40 ? "40" : "20"),
pAd->CommonCfg.Channel,
pAd->CommonCfg.CentralChannel));
/* Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission */
rtmp_bbp_get_agc(pAd, &pAd->BbpTuning.R66CurrentValue, RX_CHAIN_0);
//Enable MAC Tx/Rx
RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Data);
Data |= 0x0C;
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Data);
}
/*
========================================================================
Routine Description:
Verify the support rate for different PHY type
Arguments:
pAd Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
========================================================================
*/
// TODO: shiang-6590, modify this cause it's really a duplication of "ApCliUpdateMlmeRate()" in ap/ap_apcli.c
VOID P2PUpdateMlmeRate(
IN PRTMP_ADAPTER pAd)
{
UCHAR MinimumRate;
UCHAR ProperMlmeRate; /*= RATE_54; */
UCHAR i, j, RateIdx = 12; /* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
BOOLEAN bMatch = FALSE;
switch (pAd->CommonCfg.PhyMode)
{
case WMODE_B:
ProperMlmeRate = RATE_11;
MinimumRate = RATE_1;
break;
case (WMODE_B | WMODE_G):
#ifdef DOT11_N_SUPPORT
case (WMODE_B | WMODE_A | WMODE_G | WMODE_GN | WMODE_AN):
case (WMODE_B | WMODE_G | WMODE_GN):
#endif /* DOT11_N_SUPPORT */
if ((pAd->ApCliMlmeAux.SupRateLen == 4) &&
(pAd->ApCliMlmeAux.ExtRateLen == 0))
/* B only AP */
ProperMlmeRate = RATE_11;
else
ProperMlmeRate = RATE_24;
if (pAd->ApCliMlmeAux.Channel <= 14)
MinimumRate = RATE_1;
else
MinimumRate = RATE_6;
break;
case (WMODE_A):
#ifdef DOT11_N_SUPPORT
case (WMODE_GN): /* rt2860 need to check mlmerate for 802.11n */
case (WMODE_G | WMODE_GN):
case (WMODE_A | WMODE_G | WMODE_AN | WMODE_GN):
case (WMODE_A | WMODE_AN):
case (WMODE_AN):
#endif /* DOT11_N_SUPPORT */
ProperMlmeRate = RATE_24;
MinimumRate = RATE_6;
break;
case (WMODE_A | WMODE_B | WMODE_G):
ProperMlmeRate = RATE_24;
if (pAd->ApCliMlmeAux.Channel <= 14)
MinimumRate = RATE_1;
else
MinimumRate = RATE_6;
break;
default: /* error */
ProperMlmeRate = RATE_1;
MinimumRate = RATE_1;
break;
}
for (i = 0; i < pAd->ApCliMlmeAux.SupRateLen; i++)
{
for (j = 0; j < RateIdx; j++)
{
if ((pAd->ApCliMlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
{
if (j == ProperMlmeRate)
{
bMatch = TRUE;
break;
}
}
}
if (bMatch)
break;
}
if (bMatch == FALSE)
{
for (i = 0; i < pAd->ApCliMlmeAux.ExtRateLen; i++)
{
for (j = 0; j < RateIdx; j++)
{
if ((pAd->ApCliMlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
{
if (j == ProperMlmeRate)
{
bMatch = TRUE;
break;
}
}
}
if (bMatch)
break;
}
}
if (bMatch == FALSE)
{
ProperMlmeRate = MinimumRate;
}
if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
{
pAd->CommonCfg.MlmeRate = MinimumRate;
pAd->CommonCfg.RtsRate = ProperMlmeRate;
if (pAd->CommonCfg.MlmeRate >= RATE_6)
{
pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
}
else
{
pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
}
}
DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n" , pAd->CommonCfg.MlmeTransmit.word));
}
/*
==========================================================================
Description:
Shutdown AP and free AP specific resources
==========================================================================
*/
VOID P2PAPShutdown(
IN PRTMP_ADAPTER pAd)
{
DBGPRINT(RT_DEBUG_TRACE, ("---> P2PAPShutdown\n"));
MlmeRadioOff(pAd);
#ifdef IGMP_SNOOP_SUPPORT
MultiCastFilterTableReset(&pAd->pMulticastFilterTable);
#endif /* IGMP_SNOOP_SUPPORT */
NdisFreeSpinLock(&pAd->MacTabLock);
DBGPRINT(RT_DEBUG_TRACE, ("<--- P2PAPShutdown\n"));
}
VOID P2PUserCfgInit(
IN PRTMP_ADAPTER pAd)
{
UINT i, j;
/* Set MBSS Default Configurations */
pAd->ApCfg.BssidNum = MAX_MBSSID_NUM(pAd);
for(j = BSS0; j < pAd->ApCfg.BssidNum; j++)
{
pAd->ApCfg.MBSSID[j].AuthMode = Ndis802_11AuthModeOpen;
pAd->ApCfg.MBSSID[j].WepStatus = Ndis802_11EncryptionDisabled;
pAd->ApCfg.MBSSID[j].GroupKeyWepStatus = Ndis802_11EncryptionDisabled;
pAd->ApCfg.MBSSID[j].DefaultKeyId = 0;
pAd->ApCfg.MBSSID[j].WpaMixPairCipher = MIX_CIPHER_NOTUSE;
#ifdef DOT1X_SUPPORT
pAd->ApCfg.MBSSID[j].IEEE8021X = FALSE;
pAd->ApCfg.MBSSID[j].PreAuth = FALSE;
/* PMK cache setting */
pAd->ApCfg.MBSSID[j].PMKCachePeriod = (10 * 60 * OS_HZ); /* unit : tick(default: 10 minute) */
NdisZeroMemory(&pAd->ApCfg.MBSSID[j].PMKIDCache, sizeof(NDIS_AP_802_11_PMKID));
/* dot1x related per BSS */
pAd->ApCfg.MBSSID[j].radius_srv_num = 0;
pAd->ApCfg.MBSSID[j].NasIdLen = 0;
#endif /* DOT1X_SUPPORT */
/* VLAN related */
pAd->ApCfg.MBSSID[j].VLAN_VID = 0;
/* Default MCS as AUTO */
pAd->ApCfg.MBSSID[j].bAutoTxRateSwitch = TRUE;
pAd->ApCfg.MBSSID[j].DesiredTransmitSetting.field.MCS = MCS_AUTO;
/* Default is zero. It means no limit. */
pAd->ApCfg.MBSSID[j].MaxStaNum = 0;
pAd->ApCfg.MBSSID[j].StaCount = 0;
#ifdef WSC_AP_SUPPORT
{
PWSC_CTRL pWscControl;
INT idx;
#ifdef WSC_V2_SUPPORT
PWSC_V2_INFO pWscV2Info;
#endif /* WSC_V2_SUPPORT */
/*
WscControl cannot be zero here, because WscControl timers are initial in MLME Initialize
and MLME Initialize is called before UserCfgInit.
*/
pWscControl = &pAd->ApCfg.MBSSID[j].WscControl;
NdisZeroMemory(&pWscControl->RegData, sizeof(WSC_REG_DATA));
NdisZeroMemory(&pAd->CommonCfg.WscStaPbcProbeInfo, sizeof(WSC_STA_PBC_PROBE_INFO));
pWscControl->WscMode = 1;
pWscControl->WscConfStatus = 1;
pWscControl->WscConfigMethods= 0x0184;
pWscControl->RegData.ReComputePke = 1;
pWscControl->lastId = 1;
/*pWscControl->EntryIfIdx = (MIN_NET_DEVICE_FOR_MBSSID | j); */
pWscControl->pAd = pAd;
pWscControl->WscRejectSamePinFromEnrollee = FALSE;
pAd->CommonCfg.WscPBCOverlap = FALSE;
pWscControl->WscConfMode = 0;
pWscControl->WscStatus = 0;
pWscControl->WscState = 0;
pWscControl->WscPinCode = 0;
pWscControl->WscLastPinFromEnrollee = 0;
pWscControl->WscEnrollee4digitPinCode = FALSE;
pWscControl->WscEnrolleePinCode = 0;
pWscControl->WscSelReg = 0;
pWscControl->WscUseUPnP = 0;
pWscControl->bWCNTest = FALSE;
pWscControl->WscKeyASCII = 0; /* default, 0 (64 Hex) */
/*
Enrollee 192 random bytes for DH key generation
*/
for (idx = 0; idx < 192; idx++)
pWscControl->RegData.EnrolleeRandom[idx] = RandomByte(pAd);
/* Enrollee Nonce, first generate and save to Wsc Control Block */
for (idx = 0; idx < 16; idx++)
{
pWscControl->RegData.SelfNonce[idx] = RandomByte(pAd);
}
NdisZeroMemory(&pWscControl->WscDefaultSsid, sizeof(NDIS_802_11_SSID));
NdisZeroMemory(&pWscControl->Wsc_Uuid_Str[0], UUID_LEN_STR);
NdisZeroMemory(&pWscControl->Wsc_Uuid_E[0], UUID_LEN_HEX);
pWscControl->bCheckMultiByte = FALSE;
#ifdef WSC_V2_SUPPORT
pWscV2Info = &pWscControl->WscV2Info;
pWscV2Info->bWpsEnable = TRUE;
pWscV2Info->ExtraTlv.TlvLen = 0;
pWscV2Info->ExtraTlv.TlvTag = 0;
pWscV2Info->ExtraTlv.pTlvData = NULL;
pWscV2Info->ExtraTlv.TlvType = TLV_ASCII;
pWscV2Info->bEnableWpsV2 = TRUE;
#endif /* WSC_V2_SUPPORT */
}
#endif /* WSC_AP_SUPPORT */
for(i = 0; i < WLAN_MAX_NUM_OF_TIM; i++)
pAd->ApCfg.MBSSID[j].TimBitmaps[i] = 0;
}
pAd->ApCfg.DtimCount = 0;
pAd->ApCfg.DtimPeriod = DEFAULT_DTIM_PERIOD;
pAd->ApCfg.ErpIeContent = 0;
pAd->ApCfg.StaIdleTimeout = MAC_TABLE_AGEOUT_TIME;
#ifdef IDS_SUPPORT
/* Default disable IDS threshold and reset all IDS counters */
pAd->ApCfg.IdsEnable = FALSE;
pAd->ApCfg.AuthFloodThreshold = 0;
pAd->ApCfg.AssocReqFloodThreshold = 0;
pAd->ApCfg.ReassocReqFloodThreshold = 0;
pAd->ApCfg.ProbeReqFloodThreshold = 0;
pAd->ApCfg.DisassocFloodThreshold = 0;
pAd->ApCfg.DeauthFloodThreshold = 0;
pAd->ApCfg.EapReqFloodThreshold = 0;
RTMPClearAllIdsCounter(pAd);
#endif /* IDS_SUPPORT */
#ifdef WSC_INCLUDED
pAd->WriteWscCfgToDatFile = 0xFF;
pAd->WriteWscCfgToAr9DatFile = FALSE;
#ifdef CONFIG_AP_SUPPORT
pAd->bWscDriverAutoUpdateCfg = TRUE;
#endif /* CONFIG_AP_SUPPORT */
#endif /* WSC_INCLUDED */
for(j = 0; j < MAX_APCLI_NUM; j++)
{
pAd->ApCfg.ApCliTab[j].AuthMode = Ndis802_11AuthModeOpen;
pAd->ApCfg.ApCliTab[j].WepStatus = Ndis802_11WEPDisabled;
pAd->ApCfg.ApCliTab[j].bAutoTxRateSwitch = TRUE;
pAd->ApCfg.ApCliTab[j].DesiredTransmitSetting.field.MCS = MCS_AUTO;
}
{
PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
pP2PCtrl->P2p_OpMode = P2P_CONCURRENT;
pP2PCtrl->bKeepSlient = FALSE;
pP2PCtrl->NoAIndex = MAX_P2P_GROUP_SIZE;
/* pP2PCtrl->PortNumber = 0; */
pP2PCtrl->ListenChannel = 1;
pP2PCtrl->GroupChannel = 11;
pP2PCtrl->GroupOpChannel = 11;
P2pSetListenIntBias(pAd, 3);
pP2PCtrl->DeviceNameLen = 10;
pP2PCtrl->DeviceName[0] = 'R';
pP2PCtrl->DeviceName[1] = 'a';
pP2PCtrl->DeviceName[2] = 'l';
pP2PCtrl->DeviceName[3] = 'i';
pP2PCtrl->DeviceName[4] = 'n';
pP2PCtrl->DeviceName[5] = 'k';
pP2PCtrl->DeviceName[6] = '-';
pP2PCtrl->DeviceName[7] = 'P';
pP2PCtrl->DeviceName[8] = 0x32;
pP2PCtrl->DeviceName[9] = 'P';
/* pP2PCtrl->P2PDiscoProvState = P2P_DISABLE; */
pP2PCtrl->P2PConnectState = P2P_CONNECT_IDLE;
/* Set Dpid to "not specified". it means, GUI doesn't set for connection yet. */
pP2PCtrl->Dpid = DEV_PASS_ID_NOSPEC;
pP2PCtrl->P2pManagedParm.APP2pManageability = 0xff;
pP2PCtrl->P2pManagedParm.ICSStatus = ICS_STATUS_DISABLED;
P2pGroupTabInit(pAd);
P2pCrednTabClean(pAd);
P2pScanChannelDefault(pAd);
RTMPMoveMemory(pAd->P2pCfg.SSID, WILDP2PSSID, WILDP2PSSIDLEN);
/* RTMPMoveMemory(pAd->P2pCfg.Bssid, pAd->P2pCfg.CurrentAddress, MAC_ADDR_LEN); */
pP2PCtrl->SSIDLen = WILDP2PSSIDLEN;
pP2PCtrl->GONoASchedule.bValid = FALSE;
pP2PCtrl->GONoASchedule.bInAwake = TRUE;
pP2PCtrl->GONoASchedule.bWMMPSInAbsent = FALSE; /* Set to FALSE if changes state to Awake */
pP2PCtrl->GONoASchedule.Token = 0;
pP2PCtrl->GoIntentIdx = 0;
pP2PCtrl->Rule = P2P_IS_DEVICE;
pP2PCtrl->WscMode = WSC_PIN_MODE;
pP2PCtrl->DefaultConfigMethod = P2P_REG_CM_DISPLAY;
pP2PCtrl->bExtListen = FALSE;
pP2PCtrl->bIntraBss = FALSE;
pP2PCtrl->ExtListenInterval = P2P_EXT_LISTEN_INTERVAL;
pP2PCtrl->ExtListenPeriod = P2P_EXT_LISTEN_PERIOD;
pP2PCtrl->GONoASchedule.Count = 0;
pP2PCtrl->GONoASchedule.Duration = 0;
pP2PCtrl->GONoASchedule.Interval = 0;
}
}
VOID P2pInit(
IN PRTMP_ADAPTER pAd,
IN RTMP_OS_NETDEV_OP_HOOK *pNetDevOps)
{
PNET_DEV new_dev_p;
APCLI_STRUCT *pApCliEntry;
/* sanity check to avoid redundant virtual interfaces are created */
if (pAd->flg_p2p_init != FALSE)
return;
/* End of if */
DBGPRINT(RT_DEBUG_TRACE, ("%s --->\n", __FUNCTION__));
/* init */
pAd->ApCfg.MBSSID[MAIN_MBSSID].MSSIDDev = NULL;
pAd->ApCfg.ApCliTab[MAIN_MBSSID].dev = NULL;
pApCliEntry = &pAd->ApCfg.ApCliTab[MAIN_MBSSID];
/* create virtual network interface */
{
UINT32 MC_RowID = 0, IoctlIF = 0;
new_dev_p = RtmpOSNetDevCreate(MC_RowID, &IoctlIF, INT_P2P, MAIN_MBSSID, sizeof(PRTMP_ADAPTER), INF_P2P_DEV_NAME);
if (new_dev_p == NULL)
{
/* allocation fail, exit */
DBGPRINT(RT_DEBUG_ERROR, ("Allocate network device fail (MBSS)...\n"));
return;
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("Register P2P IF (%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(new_dev_p)));
}
RTMP_OS_NETDEV_SET_PRIV(new_dev_p, pAd);
pNetDevOps->priv_flags = INT_P2P; /* We are virtual interface */
pNetDevOps->needProtcted = TRUE;
/* Init MAC address of virtual network interface */
COPY_MAC_ADDR(pAd->P2PCurrentAddress, pAd->CurrentAddress);
/*
Refer to HW definition -
Bit1 of MAC address Byte0 is local administration bit
and should be set to 1 in extended multiple BSSIDs'
Bit3~ of MAC address Byte0 is extended multiple BSSID index.
*/
if (pAd->chipCap.MBSSIDMode == MBSSID_MODE1)
pAd->P2PCurrentAddress[0] += 2;
else
{
#ifdef P2P_ODD_MAC_ADJUST
if (pAd->P2PCurrentAddress[5] & 0x01 == 0x01)
pAd->P2PCurrentAddress[5] -= 1;
else
#endif /* P2P_ODD_MAC_ADJUST */
pAd->P2PCurrentAddress[5] += FIRST_MBSSID;
}
NdisMoveMemory(&pNetDevOps->devAddr[0], &pAd->P2PCurrentAddress[0], MAC_ADDR_LEN);
/* backup our virtual network interface */
pAd->ApCfg.MBSSID[MAIN_MBSSID].MSSIDDev = new_dev_p;
COPY_MAC_ADDR(pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid, pAd->P2PCurrentAddress);
pApCliEntry->dev = new_dev_p;
COPY_MAC_ADDR(pApCliEntry->CurrentAddress, pAd->P2PCurrentAddress);
COPY_MAC_ADDR(pAd->P2pCfg.CurrentAddress, pAd->P2PCurrentAddress);
pAd->p2p_dev = new_dev_p;
/* register this device to OS */
RtmpOSNetDevAttach(pAd->OpMode, new_dev_p, pNetDevOps);
}
pAd->CommonCfg.BeaconPeriod = 100;
pAd->ApCfg.DtimPeriod = 1;
pAd->CommonCfg.DisableOLBCDetect = 0;
P2pGetRandomSSID(pAd, pAd->ApCfg.MBSSID[MAIN_MBSSID].Ssid, &(pAd->ApCfg.MBSSID[MAIN_MBSSID].SsidLen));
pAd->ApCfg.MBSSID[MAIN_MBSSID].AuthMode = Ndis802_11AuthModeOpen;
pAd->ApCfg.MBSSID[MAIN_MBSSID].WepStatus = Ndis802_11EncryptionDisabled;
pAd->ApCfg.MBSSID[MAIN_MBSSID].DesiredTransmitSetting.field.MCS = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
if ((pAd->CommonCfg.bWmmCapable) || WMODE_CAP_N(pAd->CommonCfg.PhyMode))
pAd->ApCfg.MBSSID[MAIN_MBSSID].bWmmCapable = TRUE;
/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_P2P_GO); */
/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_P2P_CLI); */
pAd->flg_p2p_init = TRUE;
pAd->ApCfg.ApCliTab[MAIN_MBSSID].AuthMode = Ndis802_11AuthModeOpen;
pAd->ApCfg.ApCliTab[MAIN_MBSSID].WepStatus = Ndis802_11WEPDisabled;
pAd->ApCfg.ApCliTab[MAIN_MBSSID].DesiredTransmitSetting.field.MCS = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
RTMPSetIndividualHT(pAd, MIN_NET_DEVICE_FOR_APCLI);
pAd->flg_apcli_init = TRUE;
pAd->flg_p2p_OpStatusFlags = P2P_DISABLE;
WscGenerateUUID(pAd, &pAd->P2pCfg.Wsc_Uuid_E[0], &pAd->P2pCfg.Wsc_Uuid_Str[0], 0, FALSE);
NdisMoveMemory(&pAd->P2pCfg.DevInfo.Uuid[0], &pAd->P2pCfg.Wsc_Uuid_E[0], UUID_LEN_HEX);
}
INT P2P_OpenPre(
IN PNET_DEV pDev)
{
PRTMP_ADAPTER pAd;
pAd = RTMP_OS_NETDEV_GET_PRIV(pDev);
if (ADHOC_ON(pAd))
return -1;
pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = FALSE;
return 0;
}
INT P2P_OpenPost(
IN PNET_DEV pDev)
{
PRTMP_ADAPTER pAd;
PMULTISSID_STRUCT pMbss;
pAd = RTMP_OS_NETDEV_GET_PRIV(pDev);
if (ADHOC_ON(pAd))
return -1;
pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID];
/* re-copy the MAC to virtual interface to avoid these MAC = all zero,
when re-open the ra0,
i.e. ifconfig ra0 down, ifconfig ra0 up, ifconfig ra0 down, ifconfig up ... */
COPY_MAC_ADDR(pMbss->Bssid, pAd->CurrentAddress);
/*
Refer to HW definition -
Bit1 of MAC address Byte0 is local administration bit
and should be set to 1 in extended multiple BSSIDs'
Bit3~ of MAC address Byte0 is extended multiple BSSID index.
*/
if (pAd->chipCap.MBSSIDMode == MBSSID_MODE1)
pMbss->Bssid[MAIN_MBSSID] += 2;
else
{
#ifdef P2P_ODD_MAC_ADJUST
if ((pMbss->Bssid[5] & 0x01) == 0x01)
pMbss->Bssid[5] -= 1;
else
#endif /* P2P_ODD_MAC_ADJUST */
pMbss->Bssid[5] += FIRST_MBSSID;
}
if (pMbss->MSSIDDev != NULL)
{
NdisMoveMemory(RTMP_OS_NETDEV_GET_PHYADDR(pMbss->MSSIDDev),
pMbss->Bssid,
MAC_ADDR_LEN);
}
P2PCfgInit(pAd);
/*P2P_GoStartUp(pAd, MAIN_MBSSID); */
/*P2P_CliStartUp(pAd); */
/* P2P Enable */
P2pEnable(pAd);
NdisAllocateSpinLock(pAd, &pAd->P2pTableSemLock);
#ifdef RTMP_MAC_USB
RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
#endif /* RTMP_MAC_USB */
return 0;
}
INT P2P_Close(
IN PNET_DEV pDev)
{
PRTMP_ADAPTER pAd;
pAd = RTMP_OS_NETDEV_GET_PRIV(pDev);
if (P2P_CLI_ON(pAd))
P2P_CliStop(pAd);
else if (P2P_GO_ON(pAd))
P2P_GoStop(pAd);
P2pGroupTabDisconnect(pAd, FALSE);
{
UINT32 Value;
/* Disable pre-tbtt interrupt */
RTMP_IO_READ32(pAd, INT_TIMER_EN, &Value);
Value &=0xe;
RTMP_IO_WRITE32(pAd, INT_TIMER_EN, Value);
}
/*update beacon Sync */
/*if rausb0 is up => stop beacon */
/*if rausb0 is down => we will call AsicDisableSync() in usb_rtusb_close_device() */
if (INFRA_ON(pAd))
AsicEnableBssSync(pAd);
else if (ADHOC_ON(pAd))
AsicEnableIbssSync(pAd);
else
AsicDisableSync(pAd);
NdisFreeSpinLock(&pAd->P2pTableSemLock);
return 0;
}
VOID P2P_Remove(
IN PRTMP_ADAPTER pAd)
{
MULTISSID_STRUCT *pMbss;
RtmpOSNetDevProtect(1);
if (pAd->p2p_dev)
{
RtmpOSNetDevDetach(pAd->p2p_dev);
RtmpOSNetDevProtect(0);
RtmpOSNetDevFree(pAd->p2p_dev);
RtmpOSNetDevProtect(1);
/* clear it as NULL to prevent latter access error */
pAd->p2p_dev = NULL;
pAd->flg_p2p_init = FALSE;
pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID];
pMbss->MSSIDDev = NULL;
pAd->ApCfg.ApCliTab[MAIN_MBSSID].dev = NULL;
pAd->flg_apcli_init = FALSE;
}
RtmpOSNetDevProtect(0);
} /* End of P2P_Remove */
int P2P_PacketSend(
IN PNDIS_PACKET pPktSrc,
IN PNET_DEV pDev,
IN RTMP_NET_PACKET_TRANSMIT Func)
{
PRTMP_ADAPTER pAd;
PAPCLI_STRUCT pApCli;
pAd = RTMP_OS_NETDEV_GET_PRIV(pDev);
ASSERT(pAd);
#ifdef RALINK_ATE
if (ATE_ON(pAd))
{
RELEASE_NDIS_PACKET(pAd, pPktSrc, NDIS_STATUS_FAILURE);
return 0;
}
#endif /* RALINK_ATE */
if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
{
/* wlan is scanning/disabled/reset */
RELEASE_NDIS_PACKET(pAd, pPktSrc, NDIS_STATUS_FAILURE);
/*printk("1. P2P_VirtualIF_PacketSend @@@@@\n"); */
return 0;
}
if(!(RTMP_OS_NETDEV_STATE_RUNNING(pDev)))
{
/* the interface is down */
RELEASE_NDIS_PACKET(pAd, pPktSrc, NDIS_STATUS_FAILURE);
/*printk("2. P2P_VirtualIF_PacketSend @@@@@\n"); */
return 0;
}
if (P2P_CLI_ON(pAd))
{
pApCli = (PAPCLI_STRUCT)&pAd->ApCfg.ApCliTab;
if (pApCli[MAIN_MBSSID].Valid != TRUE)
{
RELEASE_NDIS_PACKET(pAd, pPktSrc, NDIS_STATUS_FAILURE);
/*printk("3. P2P_VirtualIF_PacketSend @@@@@\n"); */
return 0;
}
/* find the device in our ApCli list */
if (pApCli[MAIN_MBSSID].dev == pDev)
{
/* ya! find it */
pAd->RalinkCounters.PendingNdisPacketCount ++;
/*NdisZeroMemory((PUCHAR)&(RTPKT_TO_OSPKT(pPktSrc))->cb[CB_OFF], 15);*/
NdisZeroMemory((PUCHAR)(GET_OS_PKT_CB(pPktSrc) + CB_OFF), 15);
RTMP_SET_PACKET_SOURCE(pPktSrc, PKTSRC_NDIS);
RTMP_SET_PACKET_MOREDATA(pPktSrc, FALSE);
RTMP_SET_PACKET_NET_DEVICE_APCLI(pPktSrc, MAIN_MBSSID);
SET_OS_PKT_NETDEV(pPktSrc, pAd->net_dev);
RTMP_SET_PACKET_OPMODE(pPktSrc, OPMODE_AP);
/* transmit the packet */
/*return rt28xx_packet_xmit(RTPKT_TO_OSPKT(skb_p)); */
return Func(RTPKT_TO_OSPKT(pPktSrc));
}
}
else
{
/*printk("4. P2P_VirtualIF_PacketSend @@@@@\n"); */
/* find the device in our p2p list */
if (pAd->ApCfg.MBSSID[MAIN_MBSSID].MSSIDDev == pDev)
{
/* ya! find it */
pAd->RalinkCounters.PendingNdisPacketCount ++;
/*NdisZeroMemory((PUCHAR)&(RTPKT_TO_OSPKT(pPktSrc))->cb[CB_OFF], 15);*/
NdisZeroMemory((PUCHAR)(GET_OS_PKT_CB(pPktSrc) + CB_OFF), 15);
RTMP_SET_PACKET_SOURCE(pPktSrc, PKTSRC_NDIS);
RTMP_SET_PACKET_MOREDATA(pPktSrc, FALSE);
RTMP_SET_PACKET_NET_DEVICE_P2P(pPktSrc, MAIN_MBSSID);
SET_OS_PKT_NETDEV(pPktSrc, pAd->net_dev);
RTMP_SET_PACKET_OPMODE(pPktSrc, OPMODE_AP);
/* transmit the packet */
/*return rt28xx_packet_xmit(RTPKT_TO_OSPKT(skb_p));*/
return Func(RTPKT_TO_OSPKT(pPktSrc));
}
}
RELEASE_NDIS_PACKET(pAd, pPktSrc, NDIS_STATUS_FAILURE);
return 0;
}
INT P2P_GoSetCommonHT(
IN PRTMP_ADAPTER pAd)
{
OID_SET_HT_PHYMODE SetHT;
if (!WMODE_CAP_N(pAd->CommonCfg.PhyMode))
{
/* Clear previous HT information */
RTMPDisableDesiredHtInfo(pAd);
return FALSE;
}
SetHT.PhyMode = (RT_802_11_PHY_MODE)pAd->CommonCfg.PhyMode;
SetHT.TransmitNo = ((UCHAR)pAd->Antenna.field.TxPath);
SetHT.HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
SetHT.ExtOffset = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
SetHT.MCS = MCS_AUTO;
SetHT.BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
SetHT.STBC = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC;
SetHT.SHORTGI = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
if (INFRA_ON(pAd))
{
if (pAd->StaActive.SupportedHtPhy.ChannelWidth == BW_40)
SetHT.ExtOffset = (UCHAR)pAd->StaActive.SupportedHtPhy.ExtChanOffset;
}
RTMPSetHT(pAd, &SetHT);
return TRUE;
}
INT P2PGetEntryCnt(
IN PRTMP_ADAPTER pAd)
{
if (P2P_CLI_ON(pAd))
{
return 1;
}
else if (P2P_GO_ON(pAd))
{
UINT32 i, p2pEntryCnt=0;
MAC_TABLE_ENTRY *pEntry;
UCHAR AllZero[MAC_ADDR_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
{
pEntry = &pAd->MacTab.Content[i];
if (IS_P2P_GO_ENTRY(pEntry))
{
if ( !NdisEqualMemory(AllZero, pEntry->Addr, MAC_ADDR_LEN)) {
DBGPRINT(RT_DEBUG_TRACE,("%02x:%02x:%02x:%02x:%02x:%02x.\n", PRINT_MAC(pEntry->Addr)));
p2pEntryCnt++;
}
}
}
return p2pEntryCnt;
}
}