📄 wlan_pmufsm.c
字号:
/**************************************************************************
Copyright (c) Paragon Wireless Co., LTD.
ALL RIGHTS RESERVED
File Name: wlan_pmufsm.c
Author: 崔忠涛
Version: paraphone1.0
Date: 5/21/05
-------------------------------------------------------------------------
模块描述:
WLAN PMU CONTROL FINITE STATE MACHINE
Revisions of wlan_pmufsm.c: (latest revision on top)
#.## Name Date Description
---- -------------- -------- -------------------------------------
0.01 崔忠涛 2005/5/21 初始版本 LINTED
函数列表:
**************************************************************************/
#include "wlan_pmufsm.h"
#include "exdat.h"
#include "Winsock2.h"
#include "ParaRoamingProc.h"
#include <tf_oal_ioctl.h>
#include <omap730_clkm.h>
//#define WLAN_PMU_DEBUG
/*
* WLAN PMU Control Block
*/
WlanPmuCB g_stWlanPmuCB;
/* 对外接口 */
void wlan_PMUInit (IN PMRVDRV_ADAPTER adapter);
void wlan_PMUSleepConfirmed (void);
int wlan_PMUWlanAppsSleep (void);
int wlan_PMUWlanAppsWakeup();
void wlan_PMUCancelEnterDSTimer();
void wlan_WaitExitFromSleepMode(int timeout);
NDIS_STATUS wlan_PMUAllocateTxQ(IN PMRVDRV_ADAPTER Adapter);
/* 状态机事件 */
static void pmu_FsmSleepConfirmed (WlanPmuCB *pCB);
static void pmu_FsmLinkStatusIndicator (WlanPmuCB *pCB, int status);
static void pmu_FsmGetSleepResp (WlanPmuCB *pCB);
static void pmu_FsmGetWakeupResp (WlanPmuCB *pCB);
static void pmu_FsmSleepAwake (WlanPmuCB *pCB);
static void pmu_FsmGetDeepSleepAwake (WlanPmuCB *f);
static void pmu_FsmPowerDown (WlanPmuCB *pCB);
static void pmu_FsmPowerUp (WlanPmuCB *pCB);
static void pmu_FsmHostSleepAwake (WlanPmuCB *pCB);
static void pmu_FsmHostSleepConfirmResp (WlanPmuCB *pCB);
static void pmu_FsmGetEnterDeepSleepResp (WlanPmuCB *pCB);
/* Callback函数 */
static int pmu_ResetCBInfo(WlanPmuCB *);
static int pmu_CardEnterSleep(WlanPmuCB *);
static int pmu_CardExitSleep(WlanPmuCB *);
static int pmu_CardEnterDeepSleep(WlanPmuCB *);
static int pmu_CardReEnterDeepSleep(WlanPmuCB *);
static int pmu_CardExitDeepSleep(WlanPmuCB *);
static DWORD pmu_CardEnterStandby(WlanPmuCB *pCB, int iRTCMode);
static int pmu_RebootCard (WlanPmuCB *pCB);
static int pmu_PowerDownCard (WlanPmuCB *pCB);
static int pmu_PowerUpCard (WlanPmuCB *pCB);
static int pmu_TurnOffCard(WlanPmuCB *pCB);
static int pmu_TurnOnCard(WlanPmuCB *pCB);
/* Utility Function */
BOOLEAN pmu_InitCompleted();
static int pmu_IpAddrCheck( BYTE *buf);
static int pmu_GetIpFromStr( BYTE *buf, DWORD *pIp );
static int pmu_GetSelectProcessID(PROCESSENTRY32 *info, DWORD dwForegroundProcessId);
static int pmu_GetMacAddrWithIpAddr(unsigned long dwIpAddr, unsigned char * pbyMacAddr, int len);
static void pmu_AppendCmdNode(WlanPmuCmdListNode *node);
static WlanPmuCmdListNode *pmu_RemoveCmdHead(void);
VOID pmu_AdapterCheck(WlanPmuCB *pCB);
void wlan_PMUTxCmdTimeout (
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3
);
/* 外部变量 */
extern BOOL g_bWLAN_FW_Downloaded;
extern unsigned char wlan_cal_data[];
/* 主任务入口函数 */
void wlan_TaskPMU(void);
/* 外部函数 */
extern void PSWakeup(IN PMRVDRV_ADAPTER adapter);
extern void PSSleep(IN PMRVDRV_ADAPTER adapter);
extern int ResetCmdBuffer(IN PMRVDRV_ADAPTER adapter);
extern int Pmu_ResetCmdBuffer(IN PMRVDRV_ADAPTER adapter);
extern VOID ReturnRxPacketDesc(PMRVDRV_ADAPTER Adapter, PNDIS_PACKET pPacket);
extern NDIS_STATUS Activate_Host_Sleep_Cfg(PMRVDRV_ADAPTER Adapter);
extern NDIS_STATUS Deactivate_Host_Sleep_Cfg(PMRVDRV_ADAPTER Adapter);
#define WLAN_PMU_WithRelatedAPs_DEEP_SLEEP_UNIT 20*1000
#define WLAN_PMU_NoRelatedAPs_DEEP_SLEEP_UNIT 30*1000
#define WLAN_PMU_WITH_RELATED_AP_DEEPSLEEP_INTERVAL 14 //unit is 30 seconds
#define WLAN_PMU_NO_RELATED_AP_DEEPSLEEP_INTERVAL 14 //unit is 30 seconds
#define WLAN_PMU_DEEP_SLEEP_RESET_DEF_INTERVAL (20*1000) //ms
/*
* uint is 20 seconds, if it's larger that 1minutes, it should the times of 1minute
*/
//const unsigned char g_acWithRelatedAPsDeepSleepInterval[] ={1,1,2,1,2,3};
const unsigned char g_acWithRelatedAPsDeepSleepInterval[] ={1,1,2,1};
/*
* uint is 30 seconds
*/
//const unsigned char g_acFirstTimeNoRelatedAPsDeepSleepInterval[] ={1,1,2,1,1,4};
const unsigned char g_acFirstTimeNoRelatedAPsDeepSleepInterval[] ={1,1,2,1};
#define WLAN_PMU_ROAMING_BUSY (0x01<<0)
#define WLAN_PMU_DHCP_BUSY (0x01<<1)
#define WLAN_PMU_VOIP_BUSY (0x01<<2)
#define WLAN_PMU_IPAPP_BUSY (0x01<<3)
#define WLAN_PMU_ARP_REQ_BUSY (0x01<<4)
#define WLAN_PMU_VPN_BUSY (0X01<<5)
#define WLAN_PMU_OTHER_INERFACE_BUSY (0x01<<6)
#ifdef CONFIG_WLAN_PMU_ARP_RESPONSE
#define WLAN_PMU_GW_MAC_GETED (0x01<<0)
#define WLAN_PMU_SIP_SVR_MAC_GETED (0x01<<1)
#endif
extern int g_iPacketUseEncrypt;
extern char g_acPacketEncryptKey[20];
static char g_acWlanPmuRcvUDPPayload[1500];
static char g_acWlanPmuTransmitUDPPayload[1500];
int g_iSipPacketRecved = 0;
int g_iSTUNServerPort = 3478;
struct PMUFsmCallbacks g_stWlanPmuCallbacks = {
pmu_ResetCBInfo,
pmu_CardEnterSleep,
pmu_CardExitSleep,
pmu_CardEnterDeepSleep,
pmu_CardReEnterDeepSleep,
pmu_CardExitDeepSleep,
pmu_CardEnterStandby,
pmu_RebootCard,
pmu_TurnOffCard,
pmu_TurnOnCard
};
static int pmu_PowerUpCard (WlanPmuCB *pCB)
{
PMRVDRV_ADAPTER adapter = pCB->adapter;
BOOLEAN bDoNotify = FALSE;
IF_FW_STATUS fwStatus;
DEBUGMSG(1,(L"PMU TRACE:" L"Do power process"));
EnterCriticalSection(&pCB->IntCriticalSection);
CleanUpTimers(pCB->adapter);
CleanUpSingleTxBuffer(pCB->adapter);
ResetRxPDQ(pCB->adapter);
Pmu_ResetCmdBuffer(pCB->adapter);
ResetAdapterObject(pCB->adapter);
LeaveCriticalSection(&pCB->IntCriticalSection);
powerOnWlanCard();
g_bWLAN_FW_Downloaded = FALSE;
g_spi_dummy_clk_reg = 0x05;
g_spi_dummy_clk_data = 0x0e;
dummy_clk_reg = 0x05;
dummy_clk_data = 0x0e;
fwStatus = If_FirmwareDownload_reboot(adapter);
if ( fwStatus != FW_STATUS_INITIALIZED )
{
DEBUGMSG(1,(L"PMU ERROR:" L"Failed to download the firmware"));
return 1;
}
g_bWLAN_FW_Downloaded = TRUE;
g_spi_dummy_clk_reg = 0x01;
g_spi_dummy_clk_data = 0x01;
dummy_clk_reg = 0x01;
dummy_clk_data = 0x01;
PrepareAndSendCommand(
adapter,
HostCmd_CMD_GSPI_BUS_CONFIG,
HostCmd_ACT_GEN_SET,
HostCmd_OPTION_USE_INT,
(NDIS_OID)0,
HostCmd_PENDING_ON_NONE,
0,
FALSE,
NULL,
NULL,
NULL,
NULL);
NdisMSleep(50); // Wait long enough
PrepareAndSendCommand(
adapter,
HostCmd_CMD_GET_HW_SPEC,
0,
HostCmd_OPTION_USE_INT,
(NDIS_OID)0,
HostCmd_PENDING_ON_NONE,
0,
FALSE,
NULL,
NULL,
NULL,
NULL);
#ifdef CONFIG_WLAN_PMU_CAL_TX_POWER
// Cal Tx Power
{
unsigned long BytesNeeded;
int Status = 0;
BytesNeeded = sizeof(wlan_cal_data);
memcpy(&wlan_cal_data[BytesNeeded-MRVDRV_ETH_ADDR_LEN], adapter->PermanentAddr,MRVDRV_ETH_ADDR_LEN);
Status=PrepareAndSendCommand(
adapter,
HostCmd_CMD_802_11_CAL_DATA_EXT,
HostCmd_ACT_GEN_SET,
HostCmd_OPTION_USE_INT,
0,
HostCmd_PENDING_ON_NONE,
0,
FALSE,
0,
0,
&BytesNeeded,
&wlan_cal_data[0]
);
if (Status == NDIS_STATUS_FAILURE || Status == NDIS_STATUS_RESOURCES)
{
DEBUGMSG(1,(L"PMU ERROR:" L"HostCmd_CMD_802_11_CAL_DATA_EXT failed."));
}
else
{
DEBUGMSG(1,(L"PMU TRACE:" L"HostCmd_CMD_802_11_CAL_DATA_EXT successfully."));
}
}
#endif
#ifdef CONFIG_WLAN_PMU_EXT_CLK
{
OID_MRVL_DS_SLEEP_PARAMS Sp;
unsigned long BytesNeeded;
BytesNeeded = sizeof(OID_MRVL_DS_SLEEP_PARAMS);
Sp.Error = 20;
Sp.Offset = 50;
Sp.StableTime = 4000;
Sp.CalControl = 1;
Sp.ExternalSleepClk = 2;
Sp.Reserved = 0;
PrepareAndSendCommand(
adapter,
HostCmd_CMD_802_11_SLEEP_PARAMS,
HostCmd_ACT_GEN_SET,
HostCmd_OPTION_USE_INT,
0,
HostCmd_PENDING_ON_NONE,
0,
FALSE,
0,
0,
&BytesNeeded,
&Sp
);
}
#endif
NdisMSleep(2500);
return 0;
}
static int pmu_RebootCard (WlanPmuCB *pCB)
{
BOOLEAN timerStatus;
DEBUGMSG(1,(L"PMU ERROR:" L"Reboot Card!!!!"));
// return 0;
/*
* reboot card, reinit the pmu status, it state is that wakeup for DS mode!
*/
EnterCriticalSection(&pCB->IntCriticalSection);
#ifdef DEBUG_PARA_ROAMING
priv.bRebootCardInProcess = TRUE;
#endif
NdisMCancelTimer(&pCB->stReassociateTimer, &timerStatus);
pCB->bSetReassociateTimer = FALSE;
pCB->iCurrentDeepSleepIntervalIndex = 0;
if(pCB->iState == WLAN_PMU_FSM_STATUS_CONNECTED)
pCB->iState = WLAN_PMU_FSM_STATUS_DISCONNECTED;
else
pCB->iState = WLAN_PMU_FSM_STATUS_DEEP_SLEEP;
pCB->iIsinSleepMode = 0; //stand for non in sleep mode
pCB->adapter->psState = PS_STATE_FULL_POWER;
pCB->adapter->PSMode = Ndis802_11PowerModeCAM;
pCB->adapter->bPSConfirm = FALSE;
pCB->iIsExitingDeepSleep = 0;
pCB->adapter->IsDeepSleep = FALSE;
pCB->adapter->IsDeepSleepRequired=FALSE;
pCB->iCurrentDeepSleepIntervalIndex=0;
pCB->iWlanAppStatusActive |= WLAN_PMU_ROAMING_BUSY; //init state of appstate
LeaveCriticalSection(&pCB->IntCriticalSection);
#ifdef DEBUG_PARA_ROAMING
FreeParaPrivAdapterObject();
#endif
pmu_PowerDownCard(pCB);
Sleep(500);
pmu_PowerUpCard(pCB);
#ifdef DEBUG_PARA_ROAMING
if((!priv.bAutoRoamingInProcess) && (!priv.bManualRoamingInProcess))
{
pCB->adapter->ulNumOfBSSIDs = 0;
pCB->adapter->ulPSNumOfBSSIDs = 0;
priv.bFastAutoRoaming = FALSE;
SetEvent(priv.hAutoRoamingEvent);
}
priv.bRebootCardInProcess = FALSE;
#endif
return 0;
}
/*.......................................................................
* Func Name: pmu_ReqARP
* Description: Get Gateway and SIP svr(same subnet).
* Input: CB point
* Output: 无
*/
static int pmu_ReqARP(WlanPmuCB *pCB)
{
unsigned long ipAddr;
unsigned long ipMask;
unsigned long Gateway;
unsigned long SipSvrIpAddr;
unsigned long len = MAX_ADAPTER_ADDRESS_LENGTH;
if(pCB->adapter->MediaConnectStatus == NdisMediaStateDisconnected)
{
return;
}
if(pCB->iGotIfNetPrep == 1)
{
pmu_GetIpFromStr(pCB->IPAddr.IpAddress.String, &ipAddr);
pmu_GetIpFromStr(pCB->IPAddr.IpMask.String, &ipMask);
pmu_GetIpFromStr(pCB->Gateway.IpAddress.String, &Gateway);
}
else
{
return 1;
}
// pCB->iWlanAppStatusActive |= WLAN_PMU_ARP_REQ_BUSY;
// wlan_PMUWlanAppsWakeup();
// wlan_WaitExitFromSleepMode(3000);
#ifdef CONFIG_WLAN_PMU_ARP_RESPONSE
if((pCB->iARPFieldGot & WLAN_PMU_GW_MAC_GETED) == 0)
#endif
{
if(SendARP(ntohl(Gateway), 0, pCB->abyGWMacAddr,&len) != NO_ERROR)
{
DEBUGMSG(1,(L"PMU ERROR:" L"Request gateway ARP failed."));
}
#ifdef CONFIG_WLAN_PMU_ARP_RESPONSE
else
{
if(len == 6)
{
pCB->iARPFieldGot |= WLAN_PMU_GW_MAC_GETED;
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -