mirror of
https://github.com/YikeStone/MT7601u.git
synced 2025-08-02 19:04:09 +05:30
5999 lines
188 KiB
C
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, ®Value);
|
|
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;
|
|
}
|
|
|
|
}
|
|
|