/* *************************************************************************** * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, Taiwan, R.O.C. * (c) Copyright 2002, Ralink Technology, Inc. * * All rights reserved. Ralink's source code is an unpublished work and the * use of a copyright notice does not imply otherwise. This source code * contains confidential trade secret material of Ralink Tech. Any attemp * or participation in deciphering, decoding, reverse engineering or in any * way altering the source code is stricitly prohibited, unless the prior * written consent of Ralink Technology, Inc. is obtained. *************************************************************************** Module Name: sync.c Abstract: Revision History: Who When What -------- ---------- ---------------------------------------------- John Chang 2004-09-01 modified for rt2561/2661 Jan Lee 2006-08-01 modified for rt2860 for 802.11n */ #include "rt_config.h" #define ADHOC_ENTRY_BEACON_LOST_TIME (2*OS_HZ) /* 2 sec */ /* ========================================================================== Description: The sync state machine, Parameters: Sm - pointer to the state machine Note: the state machine looks like the following ========================================================================== */ VOID SyncStateMachineInit( IN PRTMP_ADAPTER pAd, IN STATE_MACHINE *Sm, OUT STATE_MACHINE_FUNC Trans[]) { StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE); /* column 1 */ StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction); StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_FORCE_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeForceScanReqAction); StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction); StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_FORCE_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeForceJoinReqAction); StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction); StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon); StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction); #ifdef P2P_SUPPORT StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction); #endif /* P2P_SUPPORT */ /* column 2 */ StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction); StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart); StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction); StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction); StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction); /* column 3 */ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction); StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart); StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction); StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction); StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction); /* StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_CNCL, (STATE_MACHINE_FUNC)ScanCnclAction); */ /* resume scanning for fast-roaming */ StateMachineSetAction(Sm, SCAN_PENDING, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction); StateMachineSetAction(Sm, SCAN_PENDING, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon); /* timer init */ RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE); RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE); } /* ========================================================================== Description: Beacon timeout handler, executed in timer thread IRQL = DISPATCH_LEVEL ========================================================================== */ VOID BeaconTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n")); /* Do nothing if the driver is starting halt state. This might happen when timer already been fired before cancel timer with mlmehalt */ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) return; #ifdef DOT11_N_SUPPORT if ((pAd->CommonCfg.BBPCurrentBW == BW_40) ) { rtmp_bbp_set_bw(pAd, BW_40); AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n", pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr)); } #endif /* DOT11_N_SUPPORT */ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL, 0); RTMP_MLME_HANDLER(pAd); } /* ========================================================================== Description: Scan timeout handler, executed in timer thread IRQL = DISPATCH_LEVEL ========================================================================== */ VOID ScanTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; /* Do nothing if the driver is starting halt state. This might happen when timer already been fired before cancel timer with mlmehalt */ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) return; if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL, 0)) { RTMP_MLME_HANDLER(pAd); } else { /* To prevent SyncMachine.CurrState is SCAN_LISTEN forever. */ pAd->MlmeAux.Channel = 0; ScanNextChannel(pAd, OPMODE_STA); RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, NULL, BSS0, 0); } } VOID MlmeForceJoinReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { BOOLEAN TimerCancelled; HEADER_802_11 Hdr80211; NDIS_STATUS NStatus; ULONG FrameLen = 0; PUCHAR pOutBuffer = NULL; PUCHAR pSupRate = NULL; UCHAR SupRateLen; PUCHAR pExtRate = NULL; UCHAR ExtRateLen; UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C}; UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR); MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg); #ifdef CONFIG_PM #ifdef USB_SUPPORT_SELECTIVE_SUSPEND POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; #endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ #endif /* CONFIG_PM */ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeForeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx)); #ifdef CONFIG_PM #ifdef USB_SUPPORT_SELECTIVE_SUSPEND if ( (RTMP_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == 1) { DBGPRINT(RT_DEBUG_TRACE, ("MlmeJoinReqAction: autopm_resume success\n")); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); } else if ((RTMP_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == (-1)) { DBGPRINT(RT_DEBUG_ERROR, ("MlmeJoinReqAction autopm_resume fail ------\n")); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); return; } else DBGPRINT(RT_DEBUG_TRACE, ("MlmeJoinReqAction: autopm_resume do nothing \n")); #endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ #endif /* CONFIG_PM */ #ifdef PCIE_PS_SUPPORT if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) && (IDLE_ON(pAd)) && (pAd->StaCfg.bRadio == TRUE) && (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) { RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); } #endif /* PCIE_PS_SUPPORT */ /* reset all the timers */ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); { RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->StaCfg.ConnectinfoSsid, pAd->StaCfg.ConnectinfoSsidLen); pAd->MlmeAux.SsidLen = pAd->StaCfg.ConnectinfoSsidLen; } pAd->MlmeAux.BssType = pAd->StaCfg.ConnectinfoBssType; pAd->MlmeAux.Channel = pAd->StaCfg.ConnectinfoChannel; /* Let BBP register at 20MHz to do scan */ AsicSetChannel(pAd, pAd->MlmeAux.Channel, BW_20, EXTCHA_NONE, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n")); RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT); do { /* send probe request */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus == NDIS_STATUS_SUCCESS) { if (pAd->MlmeAux.Channel <= 14) { pSupRate = pAd->CommonCfg.SupRate; SupRateLen = pAd->CommonCfg.SupRateLen; pExtRate = pAd->CommonCfg.ExtRate; ExtRateLen = pAd->CommonCfg.ExtRateLen; } else { /* Overwrite Support Rate, CCK rate are not allowed */ pSupRate = ASupRate; SupRateLen = ASupRateLen; ExtRateLen = 0; } if ((pAd->MlmeAux.BssType == BSS_INFRA) && (!MAC_ADDR_EQUAL(ZERO_MAC_ADDR, pAd->StaCfg.ConnectinfoBssid))) { COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAd->StaCfg.ConnectinfoBssid); MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, #ifdef P2P_SUPPORT pAd->CurrentAddress, #endif /* P2P_SUPPORT */ pAd->MlmeAux.Bssid); } else MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, #ifdef P2P_SUPPORT pAd->CurrentAddress, #endif /* P2P_SUPPORT */ BROADCAST_ADDR); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &Hdr80211, 1, &SsidIe, 1, &pAd->MlmeAux.SsidLen, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pSupRate, END_OF_ARGS); if (ExtRateLen) { ULONG Tmp; MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, 1, &ExtRateIe, 1, &ExtRateLen, ExtRateLen, pExtRate, END_OF_ARGS); FrameLen += Tmp; } #ifdef WPA_SUPPLICANT_SUPPORT if ((pAd->OpMode == OPMODE_STA) && (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && (pAd->StaCfg.WpsProbeReqIeLen != 0)) { ULONG WpsTmpLen = 0; MakeOutgoingFrame(pOutBuffer + FrameLen, &WpsTmpLen, pAd->StaCfg.WpsProbeReqIeLen, pAd->StaCfg.pWpsProbeReqIe, END_OF_ARGS); FrameLen += WpsTmpLen; } #endif /* WPA_SUPPLICANT_SUPPORT */ #ifdef WFD_SUPPORT #ifdef RT_CFG80211_SUPPORT if (pAd->StaCfg.WfdCfg.bSuppInsertWfdIe) { ULONG WfdIeLen, WfdIeBitmap; PUCHAR ptr; ptr = pOutBuffer + FrameLen; WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) | (0x1 << SUBID_WFD_COUPLED_SINK_INFO); WfdMakeWfdIE(pAd, WfdIeBitmap, ptr, &WfdIeLen); FrameLen += WfdIeLen; } #endif /* RT_CFG80211_SUPPORT */ #endif /* WFD_SUPPORT */ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } } while (FALSE); DBGPRINT(0, ("FORCE JOIN SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n", pAd->StaCfg.ConnectinfoChannel, PRINT_MAC(pAd->StaCfg.ConnectinfoBssid))); pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON; } VOID MlmeForceScanReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType; BOOLEAN TimerCancelled; ULONG Now; USHORT Status; #ifdef RTMP_MAC_USB if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) { if ( IS_MT7601(pAd) ) ASIC_RADIO_ON(pAd, DOT11_RADIO_ON); else RT28xxUsbAsicRadioOn(pAd); } #endif /* RTMP_MAC_USB */ /* Check the total scan tries for one single OID command If this is the CCX 2.0 Case, skip that! */ if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeForceScanReqAction before Startup\n")); return; } /* first check the parameter sanity */ if (MlmeScanReqSanity(pAd, Elem->Msg, Elem->MsgLen, &BssType, (PCHAR)Ssid, &SsidLen, &ScanType)) { /* Check for channel load and noise hist request Suspend MSDU only at scan request, not the last two mentioned Suspend MSDU transmission here */ RTMPSuspendMsduTransmission(pAd); /* To prevent data lost. Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. And should send an NULL data with turned PSM bit off to AP, when scan progress done */ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd))) { RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE), PWR_SAVE); DBGPRINT(RT_DEBUG_TRACE, ("MlmeForceScanReqAction -- Send PSM Data frame for off channel RM, SCAN_IN_PROGRESS=%d!\n", RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))); OS_WAIT(20); } RTMPSendWirelessEvent(pAd, IW_SCANNING_EVENT_FLAG, NULL, BSS0, 0); NdisGetSystemUpTime(&Now); pAd->StaCfg.LastScanTime = Now; /* reset all the timers */ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); /* record desired BSS parameters */ pAd->MlmeAux.BssType = BssType; pAd->MlmeAux.ScanType = ScanType; pAd->MlmeAux.SsidLen = SsidLen; NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); /* Scanning was pending (for fast scanning) */ if ((pAd->StaCfg.bImprovedScan) && (pAd->Mlme.SyncMachine.CurrState == SCAN_PENDING)) { pAd->MlmeAux.Channel = pAd->StaCfg.LastScanChannel; } else { if (pAd->StaCfg.bFastConnect && (pAd->CommonCfg.Channel != 0) && !pAd->StaCfg.bNotFirstScan) { pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; } else /* start from the first channel */ pAd->MlmeAux.Channel = FirstChannel(pAd); } /* Let BBP register at 20MHz to do scan */ rtmp_bbp_set_bw(pAd, BW_20); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n")); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* Before scan, reset trigger event table. */ TriEventInit(pAd); #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ ScanNextChannel(pAd, OPMODE_STA); if(pAd->StaCfg.ConnectinfoChannel != 0) pAd->MlmeAux.Channel = 0; pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_SCAN_FOR_CONNECT; } else { DBGPRINT_ERR(("SYNC - MlmeForceScanReqAction() sanity check fail\n")); pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0); } } /* ========================================================================== Description: MLME SCAN req state machine procedure ========================================================================== */ VOID MlmeScanReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType; BOOLEAN TimerCancelled; ULONG Now; USHORT Status; #ifdef RTMP_MAC_USB if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) { if ( IS_MT7601(pAd) ) ASIC_RADIO_ON(pAd, DOT11_RADIO_ON); else RT28xxUsbAsicRadioOn(pAd); } #endif /* RTMP_MAC_USB */ /* Check the total scan tries for one single OID command If this is the CCX 2.0 Case, skip that! */ if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n")); return; } #ifdef PCIE_PS_SUPPORT if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) && (IDLE_ON(pAd)) && (pAd->StaCfg.bRadio == TRUE) && (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) { if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) { AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02, FALSE); AsicCheckCommanOk(pAd, PowerWakeCID); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); DBGPRINT(RT_DEBUG_TRACE, ("PSM - Issue Wake up command \n")); } else { RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); } } #endif /* PCIE_PS_SUPPORT */ /* first check the parameter sanity */ if (MlmeScanReqSanity(pAd, Elem->Msg, Elem->MsgLen, &BssType, (PCHAR)Ssid, &SsidLen, &ScanType)) { /* Check for channel load and noise hist request Suspend MSDU only at scan request, not the last two mentioned Suspend MSDU transmission here */ RTMPSuspendMsduTransmission(pAd); /* To prevent data lost. Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. And should send an NULL data with turned PSM bit off to AP, when scan progress done */ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd))) { RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE), PWR_SAVE); DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM, SCAN_IN_PROGRESS=%d!\n", RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))); OS_WAIT(20); } RTMPSendWirelessEvent(pAd, IW_SCANNING_EVENT_FLAG, NULL, BSS0, 0); NdisGetSystemUpTime(&Now); pAd->StaCfg.LastScanTime = Now; /* reset all the timers */ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); /* record desired BSS parameters */ pAd->MlmeAux.BssType = BssType; pAd->MlmeAux.ScanType = ScanType; pAd->MlmeAux.SsidLen = SsidLen; NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); #ifdef CONFIG_MULTI_CHANNEL if (P2P_CLI_ON(pAd) && (pAd->Multi_Channel_Enable == TRUE)) { pAd->StaCfg.bImprovedScan = TRUE; pAd->StaCfg.ScanChannelCnt = 0; /* reset channel counter to 0 */ } #elif defined (WIFI_P2P_CONCURRENT_FAST_SCAN) /* If p2p is connected as GO||GC, then we need to perform Elegant scan */ if (P2P_GO_ON(pAd) || P2P_CLI_ON(pAd)) { pAd->StaCfg.bImprovedScan = TRUE; pAd->StaCfg.ScanChannelCnt = 0; /* reset channel counter to 0 */ } #endif /*CONFIG_MULTI_CHANNEL*/ /* Scanning was pending (for fast scanning) */ if ((pAd->StaCfg.bImprovedScan) && (pAd->Mlme.SyncMachine.CurrState == SCAN_PENDING)) { pAd->MlmeAux.Channel = pAd->StaCfg.LastScanChannel; } #ifdef P2P_SUPPORT else if (pAd->P2pCfg.CtrlCurrentState == P2P_CTRL_DISCOVERY) { pAd->MlmeAux.Channel = 1; } #endif /* P2P_SUPPORT */ else { if (pAd->StaCfg.bFastConnect && (pAd->CommonCfg.Channel != 0) && !pAd->StaCfg.bNotFirstScan) { pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; } else { { /* start from the first channel */ pAd->MlmeAux.Channel = FirstChannel(pAd); } } } /* Let BBP register at 20MHz to do scan */ rtmp_bbp_set_bw(pAd, BW_20); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n")); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* Before scan, reset trigger event table. */ TriEventInit(pAd); #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ ScanNextChannel(pAd, OPMODE_STA); } else { DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n")); pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0); } } /* ========================================================================== Description: MLME JOIN req state machine procedure ========================================================================== */ VOID MlmeJoinReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { BSS_ENTRY *pBss; BOOLEAN TimerCancelled; HEADER_802_11 Hdr80211; NDIS_STATUS NStatus; ULONG FrameLen = 0; PUCHAR pOutBuffer = NULL; PUCHAR pSupRate = NULL; UCHAR SupRateLen; PUCHAR pExtRate = NULL; UCHAR ExtRateLen; UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C}; UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR); MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg); #ifdef WSC_STA_SUPPORT BOOLEAN bHasWscIe = FALSE; #endif /* WSC_STA_SUPPORT */ #ifdef CONFIG_PM #ifdef USB_SUPPORT_SELECTIVE_SUSPEND POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; #endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ #endif /* CONFIG_PM */ BOOLEAN bChangeInitBW = FALSE; #ifdef P2P_SUPPORT PAPCLI_STRUCT pApCliEntry = NULL; #endif /* P2P_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx)); #ifdef CONFIG_PM #ifdef USB_SUPPORT_SELECTIVE_SUSPEND if ( (RTMP_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == 1) { DBGPRINT(RT_DEBUG_TRACE, ("MlmeJoinReqAction: autopm_resume success\n")); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); } else if ((RTMP_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == (-1)) { DBGPRINT(RT_DEBUG_ERROR, ("MlmeJoinReqAction autopm_resume fail ------\n")); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); return; } else DBGPRINT(RT_DEBUG_TRACE, ("MlmeJoinReqAction: autopm_resume do nothing \n")); #endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ #endif /* CONFIG_PM */ #ifdef PCIE_PS_SUPPORT if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) && (IDLE_ON(pAd)) && (pAd->StaCfg.bRadio == TRUE) && (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) { RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); } #endif /* PCIE_PS_SUPPORT */ /* reset all the timers */ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx]; /* record the desired SSID & BSSID we're waiting for */ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid); /* If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again. */ if (pBss->Hidden == 0) { RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen); pAd->MlmeAux.SsidLen = pBss->SsidLen; } pAd->MlmeAux.BssType = pBss->BssType; pAd->MlmeAux.Channel = pBss->Channel; pAd->MlmeAux.CentralChannel = pBss->CentralChannel; #ifdef EXT_BUILD_CHANNEL_LIST /* Country IE of the AP will be evaluated and will be used. */ if ((pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None) && (pBss->bHasCountryIE == TRUE)) { NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pBss->CountryString[0], 2); if (pBss->CountryString[2] == 'I') pAd->CommonCfg.Geography = IDOR; else if (pBss->CountryString[2] == 'O') pAd->CommonCfg.Geography = ODOR; else pAd->CommonCfg.Geography = BOTH; BuildChannelListEx(pAd); } #endif /* EXT_BUILD_CHANNEL_LIST */ #ifdef P2P_SUPPORT pApCliEntry = &pAd->ApCfg.ApCliTab[BSS0]; if (!P2P_GO_ON(pAd) && (pApCliEntry->Valid == FALSE)) #endif /* P2P_SUPPORT */ { bChangeInitBW = TRUE; } #ifdef P2P_SUPPORT if ((P2P_GO_ON(pAd) || (pApCliEntry->Valid == TRUE)) && (pAd->CommonCfg.Channel != pAd->MlmeAux.Channel)) { bChangeInitBW = TRUE; } #endif /* P2P_SUPPORT */ if (bChangeInitBW == TRUE) { /* Let BBP register at 20MHz to do scan */ rtmp_bbp_set_bw(pAd, BW_20); DBGPRINT(RT_DEBUG_TRACE, ("%s(): Set BBP BW=20MHz\n", __FUNCTION__)); /* switch channel and waiting for beacon timer */ AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE); AsicLockChannel(pAd, pAd->MlmeAux.Channel); } #ifdef WSC_STA_SUPPORT #ifdef WSC_LED_SUPPORT /* LED indication. */ if (pAd->MlmeAux.BssType == BSS_INFRA) { LEDConnectionStart(pAd); LEDConnectionCompletion(pAd, TRUE); } #endif /* WSC_LED_SUPPORT */ #endif /* WSC_STA_SUPPORT */ RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT); do { if (((pAd->CommonCfg.bIEEE80211H == 1) && (pAd->MlmeAux.Channel > 14) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel)) #ifdef CARRIER_DETECTION_SUPPORT /* Roger sync Carrier */ || (pAd->CommonCfg.CarrierDetect.Enable == TRUE) #endif /* CARRIER_DETECTION_SUPPORT */ ) { /* We can't send any Probe request frame to meet 802.11h. */ if (pBss->Hidden == 0) break; } /* send probe request */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus == NDIS_STATUS_SUCCESS) { if (pAd->MlmeAux.Channel <= 14) { pSupRate = pAd->CommonCfg.SupRate; SupRateLen = pAd->CommonCfg.SupRateLen; pExtRate = pAd->CommonCfg.ExtRate; ExtRateLen = pAd->CommonCfg.ExtRateLen; } else { /* Overwrite Support Rate, CCK rate are not allowed */ pSupRate = ASupRate; SupRateLen = ASupRateLen; ExtRateLen = 0; } if (pAd->MlmeAux.BssType == BSS_INFRA) MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, #ifdef P2P_SUPPORT pAd->CurrentAddress, #endif /* P2P_SUPPORT */ pAd->MlmeAux.Bssid); else MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, #ifdef P2P_SUPPORT pAd->CurrentAddress, #endif /* P2P_SUPPORT */ BROADCAST_ADDR); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &Hdr80211, 1, &SsidIe, 1, &pAd->MlmeAux.SsidLen, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pSupRate, END_OF_ARGS); if (ExtRateLen) { ULONG Tmp; MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, 1, &ExtRateIe, 1, &ExtRateLen, ExtRateLen, pExtRate, END_OF_ARGS); FrameLen += Tmp; } #ifdef WSC_STA_SUPPORT /* Append WSC information in probe request if WSC state is running */ if ((pAd->StaCfg.WscControl.WscEnProbeReqIE) && (pAd->StaCfg.WscControl.WscConfMode != WSC_DISABLE) && (pAd->StaCfg.WscControl.bWscTrigger )) bHasWscIe = TRUE; #ifdef WSC_V2_SUPPORT else if ((pAd->StaCfg.WscControl.WscEnProbeReqIE) && (pAd->StaCfg.WscControl.WscV2Info.bEnableWpsV2)) bHasWscIe = TRUE; #endif /* WSC_V2_SUPPORT */ if (bHasWscIe) { UCHAR WscIeLen = 0; UCHAR *WscBuf = NULL; ULONG WscTmpLen = 0; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&WscBuf, 256); if (WscBuf != NULL) { NdisZeroMemory(WscBuf, 256); WscBuildProbeReqIE(pAd, STA_MODE, WscBuf, &WscIeLen); MakeOutgoingFrame(pOutBuffer + FrameLen, &WscTmpLen, WscIeLen, WscBuf, END_OF_ARGS); FrameLen += WscTmpLen; os_free_mem(NULL, WscBuf); } else DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); } #endif /* WSC_STA_SUPPORT */ #ifdef WPA_SUPPLICANT_SUPPORT if ((pAd->OpMode == OPMODE_STA) && (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && (pAd->StaCfg.WpsProbeReqIeLen != 0)) { ULONG WpsTmpLen = 0; MakeOutgoingFrame(pOutBuffer + FrameLen, &WpsTmpLen, pAd->StaCfg.WpsProbeReqIeLen, pAd->StaCfg.pWpsProbeReqIe, END_OF_ARGS); FrameLen += WpsTmpLen; } #endif /* WPA_SUPPLICANT_SUPPORT */ #ifdef WFD_SUPPORT #ifdef RT_CFG80211_SUPPORT if (pAd->StaCfg.WfdCfg.bSuppInsertWfdIe) { ULONG WfdIeLen, WfdIeBitmap; PUCHAR ptr; ptr = pOutBuffer + FrameLen; WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) | (0x1 << SUBID_WFD_COUPLED_SINK_INFO); WfdMakeWfdIE(pAd, WfdIeBitmap, ptr, &WfdIeLen); FrameLen += WfdIeLen; } #endif /* RT_CFG80211_SUPPORT */ #endif /* WFD_SUPPORT */ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } } while (FALSE); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n", pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5])); pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON; } /* ========================================================================== Description: MLME START Request state machine procedure, starting an IBSS ========================================================================== */ VOID MlmeStartReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen; BOOLEAN TimerCancelled; UCHAR *VarIE = NULL; /* New for WPA security suites */ NDIS_802_11_VARIABLE_IEs *pVIE = NULL; LARGE_INTEGER TimeStamp; BOOLEAN Privacy; USHORT Status; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } /* Init Variable IE structure */ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; TimeStamp.u.LowPart = 0; TimeStamp.u.HighPart = 0; if ((MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, (PCHAR)Ssid, &SsidLen)) && (CHAN_PropertyCheck(pAd, pAd->MlmeAux.Channel, CHANNEL_NO_IBSS) == FALSE)) { /* reset all the timers */ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); /* Start a new IBSS. All IBSS parameters are decided now */ DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n")); pAd->MlmeAux.BssType = BSS_ADHOC; NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); pAd->MlmeAux.SsidLen = SsidLen; #ifdef IWSC_SUPPORT if (pAd->StaCfg.IWscInfo.bDoNotChangeBSSID) pAd->StaCfg.IWscInfo.bDoNotChangeBSSID = FALSE; else #endif /* IWSC_SUPPORT */ { /* generate a radom number as BSSID */ MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid); DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n")); } Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled); pAd->MlmeAux.CapabilityInfo = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0); pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod; pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin; pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel; pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen; NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES); RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen); pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen; NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES); RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen); #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(pAd->CommonCfg.PhyMode) && (pAd->StaCfg.bAdhocN == TRUE)) { RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo); pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE); /* Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here. */ DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n")); #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (pAd->MlmeAux.Channel > 14)) { build_vht_cap_ie(pAd, (UCHAR *)&pAd->MlmeAux.vht_cap); pAd->MlmeAux.vht_cap_len = sizeof(VHT_CAP_IE); } #endif /* DOT11_VHT_AC */ } else #endif /* DOT11_N_SUPPORT */ { pAd->MlmeAux.HtCapabilityLen = 0; pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16); } /* temporarily not support QOS in IBSS */ NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE); AsicLockChannel(pAd, pAd->MlmeAux.Channel); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n", pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen)); pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status, 0); } else { DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n")); pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status, 0); } if (VarIE != NULL) os_free_mem(NULL, VarIE); } //+++Add by shiang to check correctness of new sanity function VOID rtmp_dbg_sanity_diff(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) { /* Parameters used for old sanity function */ UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; UCHAR *Ssid = NULL; UCHAR SsidLen=0, DtimCount, DtimPeriod, BcastFlag, MessageToMe, NewChannel, Channel = 0, BssType; CF_PARM CfParm = {0}; USHORT BeaconPeriod, AtimWin, CapabilityInfo; LARGE_INTEGER TimeStamp; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR CkipFlag; EDCA_PARM EdcaParm = {0}; UCHAR AironetCellPowerLimit; UCHAR SupRateLen, ExtRateLen; QBSS_LOAD_PARM QbssLoad; QOS_CAPABILITY_PARM QosCapability = {0}; ULONG RalinkIe; UCHAR AddHtInfoLen; EXT_CAP_INFO_ELEMENT ExtCapInfo; HT_CAPABILITY_IE *pHtCapability = NULL; ADD_HT_INFO_IE *pAddHtInfo = NULL; /* AP might use this additional ht info IE */ UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0; UCHAR Erp; UCHAR NewExtChannelOffset = 0xff; USHORT LenVIE; UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; BCN_IE_LIST *ie_list = NULL; BOOLEAN sanity_new, sanity_old; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&Ssid, MAX_LEN_OF_SSID); if (Ssid == NULL) goto LabelErr; os_alloc_mem(NULL, (UCHAR **)&pHtCapability, sizeof(HT_CAPABILITY_IE)); if (pHtCapability == NULL) goto LabelErr; os_alloc_mem(NULL, (UCHAR **)&pAddHtInfo, sizeof(ADD_HT_INFO_IE)); if (pAddHtInfo == NULL) goto LabelErr; NdisZeroMemory(&QbssLoad, sizeof(QBSS_LOAD_PARM)); /* woody */ #ifdef DOT11_N_SUPPORT RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE)); RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE)); #endif /* DOT11_N_SUPPORT */ NdisZeroMemory(Ssid, MAX_LEN_OF_SSID); os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) goto LabelErr; NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); sanity_new = PeerBeaconAndProbeRspSanity(pAd, &Elem->Msg[0], Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE); sanity_old = PeerBeaconAndProbeRspSanity_Old(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, Addr2, Bssid, (PCHAR)Ssid, &SsidLen, &BssType, &BeaconPeriod, &Channel, &NewChannel, &TimeStamp, &CfParm, &AtimWin, &CapabilityInfo, &Erp, &DtimCount, &DtimPeriod, &BcastFlag, &MessageToMe, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &CkipFlag, &AironetCellPowerLimit, &EdcaParm, &QbssLoad, &QosCapability, &RalinkIe, &HtCapabilityLen, #ifdef CONFIG_STA_SUPPORT &PreNHtCapabilityLen, #endif /* CONFIG_STA_SUPPORT */ pHtCapability, &ExtCapInfo, &AddHtInfoLen, pAddHtInfo, &NewExtChannelOffset, &LenVIE, pVIE); if (sanity_old != sanity_new) { DBGPRINT(RT_DEBUG_ERROR, ("sanity mismatch, old=%d, new=%d\n", sanity_old, sanity_new)); } else { if (NdisCmpMemory(&ie_list->Addr2[0], &Addr2[0], MAC_ADDR_LEN) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("Add2 mismatch!Old=%02x:%02x:%02x:%02x:%02x:%02x!New=%02x:%02x:%02x:%02x:%02x:%02x!\n", PRINT_MAC(Addr2), PRINT_MAC(ie_list->Addr2))); } if (NdisCmpMemory(&ie_list->Bssid[0], &Bssid[0], MAC_ADDR_LEN) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("Bssid mismatch!Old=%02x:%02x:%02x:%02x:%02x:%02x!New=%02x:%02x:%02x:%02x:%02x:%02x!\n", PRINT_MAC(Bssid), PRINT_MAC(ie_list->Bssid))); } if (SsidLen != ie_list->SsidLen) { DBGPRINT(RT_DEBUG_ERROR, ("SsidLen mismatch!Old=%d, New=%d\n", SsidLen, ie_list->SsidLen)); } if (NdisCmpMemory(&ie_list->Ssid[0], &Ssid[0], SsidLen) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("Ssid mismatch!Old=%s, New=%s\n", Ssid, ie_list->Ssid)); } if (BssType != ie_list->BssType) { DBGPRINT(RT_DEBUG_ERROR, ("BssType mismatch!Old=%d, New=%d\n", BssType, ie_list->BssType)); } if (BeaconPeriod != ie_list->BeaconPeriod) { DBGPRINT(RT_DEBUG_ERROR, ("BeaconPeriod mismatch!Old=%d, New=%d\n", BeaconPeriod, ie_list->BeaconPeriod)); } if (Channel != ie_list->Channel) { DBGPRINT(RT_DEBUG_ERROR, ("Channel mismatch!Old=%d, New=%d\n", Channel, ie_list->Channel)); } if (NewChannel != ie_list->NewChannel) { DBGPRINT(RT_DEBUG_ERROR, ("NewChannel mismatch!Old=%d, New=%d\n", NewChannel, ie_list->NewChannel)); } if (NdisCmpMemory(&ie_list->TimeStamp, &TimeStamp, sizeof(LARGE_INTEGER)) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("TimeStamp mismatch!Old=%d - %d, New=%d - %d\n", TimeStamp.u.LowPart, TimeStamp.u.HighPart, ie_list->TimeStamp.u.LowPart, ie_list->TimeStamp.u.HighPart)); } if (NdisCmpMemory(&ie_list->CfParm, &CfParm, sizeof(CF_PARM)) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("CFParam mismatch!\n")); hex_dump("Old CFParam", (UCHAR *)&CfParm, sizeof(CF_PARM)); hex_dump("New CFParam", (UCHAR *)&ie_list->CfParm, sizeof(CF_PARM)); } if (AtimWin != ie_list->AtimWin) { DBGPRINT(RT_DEBUG_ERROR, ("AtimWin mismatch!Old=%d, New=%d\n", AtimWin, ie_list->AtimWin)); } if (CapabilityInfo != ie_list->CapabilityInfo) { DBGPRINT(RT_DEBUG_ERROR, ("CapabilityInfo mismatch!Old=%d, New=%d\n", CapabilityInfo, ie_list->CapabilityInfo)); } if (Erp != ie_list->Erp) { DBGPRINT(RT_DEBUG_ERROR, ("Erp mismatch!Old=%d, New=%d\n", Erp, ie_list->Erp)); } if (DtimCount != ie_list->DtimCount) { DBGPRINT(RT_DEBUG_ERROR, ("DtimCount mismatch!Old=%d, New=%d\n", DtimCount, ie_list->DtimCount)); } if (DtimPeriod != ie_list->DtimPeriod) { DBGPRINT(RT_DEBUG_ERROR, ("DtimPeriod mismatch!Old=%d, New=%d\n", DtimPeriod, ie_list->DtimPeriod)); } if (BcastFlag != ie_list->BcastFlag) { DBGPRINT(RT_DEBUG_ERROR, ("BcastFlag mismatch!Old=%d, New=%d\n", BcastFlag, ie_list->BcastFlag)); } if (MessageToMe != ie_list->MessageToMe) { DBGPRINT(RT_DEBUG_ERROR, ("MessageToMe mismatch!Old=%d, New=%d\n", MessageToMe, ie_list->MessageToMe)); } if (SupRateLen != ie_list->SupRateLen) { DBGPRINT(RT_DEBUG_ERROR, ("SupRateLen mismatch!Old=%d, New=%d\n", SupRateLen, ie_list->SupRateLen)); } if (NdisCmpMemory(&ie_list->SupRate[0], &SupRate, ie_list->SupRateLen) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("SupRate mismatch!\n")); hex_dump("Old SupRate", (UCHAR *)&SupRate, ie_list->SupRateLen); hex_dump("New SupRate", (UCHAR *)&ie_list->SupRate, ie_list->SupRateLen); } if (ExtRateLen != ie_list->ExtRateLen) { DBGPRINT(RT_DEBUG_ERROR, ("ExtRateLen mismatch!Old=%d, New=%d\n", ExtRateLen, ie_list->ExtRateLen)); } if (NdisCmpMemory(&ie_list->ExtRate[0], &ExtRate, ie_list->ExtRateLen) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("ExtRate mismatch!\n")); hex_dump("Old ExtRate", (UCHAR *)&ExtRate, ie_list->ExtRateLen); hex_dump("New ExtRate", (UCHAR *)&ie_list->ExtRate, ie_list->ExtRateLen); } if (CkipFlag != ie_list->CkipFlag) { DBGPRINT(RT_DEBUG_ERROR, ("CkipFlag mismatch!Old=%d, New=%d\n", CkipFlag, ie_list->CkipFlag)); } if (AironetCellPowerLimit != ie_list->AironetCellPowerLimit) { DBGPRINT(RT_DEBUG_ERROR, ("AironetCellPowerLimit mismatch!Old=%d, New=%d\n", AironetCellPowerLimit, ie_list->AironetCellPowerLimit)); } if (NdisCmpMemory(&ie_list->EdcaParm, &EdcaParm, sizeof(EDCA_PARM)) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("EdcaParm mismatch!\n")); hex_dump("Old EdcaParm", (UCHAR *)&EdcaParm, sizeof(EDCA_PARM)); hex_dump("New EdcaParm", (UCHAR *)&ie_list->EdcaParm, sizeof(EDCA_PARM)); } if (NdisCmpMemory(&ie_list->QbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("QbssLoad mismatch!\n")); hex_dump("Old QbssLoad", (UCHAR *)&QbssLoad, sizeof(QBSS_LOAD_PARM)); hex_dump("New QbssLoad", (UCHAR *)&ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM)); } if (NdisCmpMemory(&ie_list->QosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("QosCapability mismatch!\n")); hex_dump("Old QosCapability", (UCHAR *)&QosCapability, sizeof(QOS_CAPABILITY_PARM)); hex_dump("New QosCapability", (UCHAR *)&ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM)); } if (RalinkIe != ie_list->RalinkIe) { DBGPRINT(RT_DEBUG_ERROR, ("RalinkIe mismatch!Old=%lx, New=%lx\n", RalinkIe, ie_list->RalinkIe)); } if (HtCapabilityLen != ie_list->HtCapabilityLen) { DBGPRINT(RT_DEBUG_ERROR, ("HtCapabilityLen mismatch!Old=%d, New=%d\n", HtCapabilityLen, ie_list->HtCapabilityLen)); } #ifdef CONFIG_STA_SUPPORT if (PreNHtCapabilityLen != ie_list->PreNHtCapabilityLen) { DBGPRINT(RT_DEBUG_ERROR, ("PreNHtCapabilityLen mismatch!Old=%d, New=%d\n", PreNHtCapabilityLen, ie_list->PreNHtCapabilityLen)); } #endif /* CONFIG_STA_SUPPORT */ if (NdisCmpMemory(&ie_list->HtCapability, pHtCapability, sizeof(HT_CAPABILITY_IE)) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("pHtCapability mismatch!\n")); hex_dump("Old HtCapability", (UCHAR *)pHtCapability, sizeof(HT_CAPABILITY_IE)); hex_dump("New HtCapability", (UCHAR *)&ie_list->HtCapability, sizeof(HT_CAPABILITY_IE)); } if (NdisCmpMemory(&ie_list->ExtCapInfo, &ExtCapInfo, sizeof(EXT_CAP_INFO_ELEMENT)) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("ExtCapInfo mismatch!\n")); hex_dump("Old ExtCapInfo", (UCHAR *)&ExtCapInfo, sizeof(EXT_CAP_INFO_ELEMENT)); hex_dump("New ExtCapInfo", (UCHAR *)&ie_list->ExtCapInfo, sizeof(EXT_CAP_INFO_ELEMENT)); } if (AddHtInfoLen != ie_list->AddHtInfoLen) { DBGPRINT(RT_DEBUG_ERROR, ("AddHtInfoLen mismatch!Old=%d, New=%d\n", AddHtInfoLen, ie_list->AddHtInfoLen)); } if (NdisCmpMemory(&ie_list->AddHtInfo, pAddHtInfo, sizeof(ADD_HT_INFO_IE)) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("AddHtInfo mismatch!\n")); hex_dump("Old AddHtInfo", (UCHAR *)pAddHtInfo, sizeof(ADD_HT_INFO_IE)); hex_dump("New AddHtInfo", (UCHAR *)&ie_list->AddHtInfo, sizeof(ADD_HT_INFO_IE)); } if (NewExtChannelOffset != ie_list->NewExtChannelOffset) { DBGPRINT(RT_DEBUG_ERROR, ("AddHtInfoLen mismatch!Old=%d, New=%d\n", NewExtChannelOffset, ie_list->NewExtChannelOffset)); } } goto LabelOK; LabelErr: DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); LabelOK: if (Ssid != NULL) os_free_mem(NULL, Ssid); if (VarIE != NULL) os_free_mem(NULL, VarIE); if (pHtCapability != NULL) os_free_mem(NULL, pHtCapability); if (pAddHtInfo != NULL) os_free_mem(NULL, pAddHtInfo); if (ie_list != NULL) os_free_mem(NULL, ie_list); } //---Add by shiang to check correctness of new sanity function /* ========================================================================== Description: peer sends beacon back when scanning ========================================================================== */ VOID PeerBeaconAtScanAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PFRAME_802_11 pFrame; USHORT LenVIE; UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; BCN_IE_LIST *ie_list = NULL; #ifdef P2P_SUPPORT if (P2P_GO_ON(pAd)) return; #endif /* P2P_SUPPORT */ os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (!ie_list) { DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc ie_list failed!\n", __FUNCTION__)); return; } NdisZeroMemory((UCHAR *)ie_list, sizeof(BCN_IE_LIST)); /* Init Variable IE structure */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) goto LabelErr; pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; pFrame = (PFRAME_802_11) Elem->Msg; if (PeerBeaconAndProbeRspSanity(pAd, &Elem->Msg[0], Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { ULONG Idx = 0; CHAR Rssi = 0; Idx = BssTableSearch(&pAd->ScanTab, &ie_list->Bssid[0], ie_list->Channel); if (Idx != BSS_NOT_FOUND) Rssi = pAd->ScanTab.BssEntry[Idx].Rssi; Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20)); #ifdef P2P_SUPPORT MlmeEnqueue(pAd, P2P_DISC_STATE_MACHINE, P2P_DISC_PEER_PROB_RSP, Elem->MsgLen, Elem->Msg, ie_list->Channel); #endif /* P2P_SUPPORT */ #ifdef DOT11_N_SUPPORT if ((ie_list->HtCapabilityLen > 0) || (ie_list->PreNHtCapabilityLen > 0)) ie_list->HtCapabilityLen = SIZE_HT_CAP_IE; #endif /* DOT11_N_SUPPORT */ Idx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, Rssi, LenVIE, pVIE); #ifdef DOT11_N_SUPPORT /* TODO: Check for things need to do when enable "DOT11V_WNM_SUPPORT" */ #ifdef DOT11N_DRAFT3 /* Check if this scan channel is the effeced channel */ if (INFRA_ON(pAd) && (pAd->CommonCfg.bBssCoexEnable == TRUE) && ((ie_list->Channel > 0) && (ie_list->Channel <= 14))) { int chListIdx; /* find the channel list idx by the channel number */ for (chListIdx = 0; chListIdx < pAd->ChannelListNum; chListIdx++) { if (ie_list->Channel == pAd->ChannelList[chListIdx].Channel) break; } if (chListIdx < pAd->ChannelListNum) { /* If this channel is effected channel for the 20/40 coex operation. Check the related IEs. */ if (pAd->ChannelList[chListIdx].bEffectedChannel == TRUE) { UCHAR RegClass; OVERLAP_BSS_SCAN_IE BssScan; /* Read Beacon's Reg Class IE if any. */ PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &BssScan, &RegClass); TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, &ie_list->Bssid[0], &ie_list->HtCapability, ie_list->HtCapabilityLen, RegClass, ie_list->Channel); } } } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ if (Idx != BSS_NOT_FOUND) { PBSS_ENTRY pBssEntry = &pAd->ScanTab.BssEntry[Idx]; NdisMoveMemory(pBssEntry->PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pBssEntry->TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pBssEntry->TTSF[4], &Elem->TimeStamp.u.LowPart, 4); pBssEntry->MinSNR = Elem->Signal % 10; if (pBssEntry->MinSNR == 0) pBssEntry->MinSNR = -5; NdisMoveMemory(pBssEntry->MacAddr, &ie_list->Addr2[0], MAC_ADDR_LEN); if ((pFrame->Hdr.FC.SubType == SUBTYPE_PROBE_RSP) && (LenVIE != 0)) { pBssEntry->VarIeFromProbeRspLen = 0; if (pBssEntry->pVarIeFromProbRsp) { pBssEntry->VarIeFromProbeRspLen = LenVIE; RTMPZeroMemory(pBssEntry->pVarIeFromProbRsp, MAX_VIE_LEN); RTMPMoveMemory(pBssEntry->pVarIeFromProbRsp, pVIE, LenVIE); } } } #ifdef LINUX #ifdef RT_CFG80211_SUPPORT RT_CFG80211_SCANNING_INFORM(pAd, Idx, Elem->Channel, (UCHAR *)pFrame, Elem->MsgLen, Rssi); #endif /* RT_CFG80211_SUPPORT */ #endif /* LINUX */ } /* sanity check fail, ignored */ goto LabelOK; LabelErr: DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); LabelOK: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (ie_list != NULL) os_free_mem(NULL, ie_list); return; } /* ========================================================================== Description: When waiting joining the (I)BSS, beacon received from external ========================================================================== */ VOID PeerBeaconAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { BOOLEAN TimerCancelled; USHORT LenVIE; USHORT Status; UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; ULONG Idx = 0; CHAR Rssi = 0; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; BOOLEAN bAllowNrate = FALSE; #endif /* DOT11_N_SUPPORT */ BCN_IE_LIST *ie_list = NULL; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) goto LabelErr; NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) goto LabelErr; /* Init Variable IE structure */ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { /* Disqualify 11b only adhoc when we are in 11g only adhoc mode */ if ((ie_list->BssType == BSS_ADHOC) && WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_G) && ((ie_list->SupRateLen+ie_list->ExtRateLen)< 12)) goto LabelOK; #ifdef P2P_SUPPORT if (P2P_INF_ON(pAd)) { P2pPeerBeaconAtJoinAction(pAd, Elem, &ie_list->Bssid[0]); } #endif /* P2P_SUPPORT */ /* BEACON from desired BSS/IBSS found. We should be able to decide most BSS parameters here. Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? Do we need to receover back all parameters belonging to previous BSS? A. Should be not. There's no back-door recover to previous AP. It still need a new JOIN-AUTH-ASSOC sequence. */ if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, &ie_list->Bssid[0])) { DBGPRINT(RT_DEBUG_TRACE, ("%s():receive desired BEACON,Channel=%d\n", __FUNCTION__, ie_list->Channel)); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); #ifdef P2P_SUPPORT if (IS_P2P_ENROLLEE(pAd)) { int p2pIdx; DBGPRINT(RT_DEBUG_ERROR, ("Recv desired Beacon, update SSID[%d][%s]\n", ie_list->SsidLen, &ie_list->Ssid[0])); pAd->MlmeAux.SsidLen = ie_list->SsidLen; NdisMoveMemory(pAd->MlmeAux.Ssid, ie_list->Ssid, pAd->MlmeAux.SsidLen); p2pIdx = P2pGroupTabSearch(pAd, ie_list->Addr2); if (p2pIdx < MAX_P2P_GROUP_SIZE) { pAd->P2pTable.Client[p2pIdx].SsidLen = ie_list->SsidLen; NdisMoveMemory(pAd->P2pTable.Client[p2pIdx].Ssid, ie_list->Ssid, pAd->P2pTable.Client[p2pIdx].SsidLen); } } #endif /* P2P_SUPPORT */ /* Update RSSI to prevent No signal display when cards first initialized */ pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20); pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20); pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20); pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0; pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3; pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1; pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3; pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2; pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3; /* We need to check if SSID only set to any, then we can record the current SSID. Otherwise will cause hidden SSID association failed. */ if (pAd->MlmeAux.SsidLen == 0) { NdisMoveMemory(pAd->MlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen); pAd->MlmeAux.SsidLen = ie_list->SsidLen; } else { Idx = BssSsidTableSearch(&pAd->ScanTab, ie_list->Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, ie_list->Channel); if (Idx == BSS_NOT_FOUND) { Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20)); Idx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, Rssi, LenVIE, pVIE); if (Idx != BSS_NOT_FOUND) { NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); ie_list->CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; pAd->ScanTab.BssEntry[Idx].MinSNR = Elem->Signal % 10; if (pAd->ScanTab.BssEntry[Idx].MinSNR == 0) pAd->ScanTab.BssEntry[Idx].MinSNR = -5; NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].MacAddr, ie_list->Addr2, MAC_ADDR_LEN); } } else { #ifdef WPA_SUPPLICANT_SUPPORT if (pAd->StaCfg.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS) ; else #endif /* WPA_SUPPLICANT_SUPPORT */ #ifdef WSC_STA_SUPPORT if ((pAd->StaCfg.WscControl.WscState != WSC_STATE_OFF) ) ; else #endif /* WSC_STA_SUPPORT */ { /* Check if AP privacy is different Staion, if yes, start a new scan and ignore the frame (often happen during AP change privacy at short time) */ if ((((pAd->StaCfg.WepStatus != Ndis802_11WEPDisabled) << 4) ^ ie_list->CapabilityInfo) & 0x0010) { MLME_SCAN_REQ_STRUCT ScanReq; DBGPRINT(RT_DEBUG_TRACE, ("%s:AP privacy %d is differenct from STA privacy%d\n", __FUNCTION__, (ie_list->CapabilityInfo & 0x0010) >> 4 , pAd->StaCfg.WepStatus != Ndis802_11WEPDisabled)); ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE); MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq, 0); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime); goto LabelOK; } } /* Multiple SSID case, used correct CapabilityInfo */ ie_list->CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; } } pAd->MlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pAd->MlmeAux.BssType = ie_list->BssType; pAd->MlmeAux.BeaconPeriod = ie_list->BeaconPeriod; /* Some AP may carrys wrong beacon interval (ex. 0) in Beacon IE. We need to check here for preventing divided by 0 error. */ if (pAd->MlmeAux.BeaconPeriod == 0) pAd->MlmeAux.BeaconPeriod = 100; pAd->MlmeAux.Channel = ie_list->Channel; pAd->MlmeAux.AtimWin = ie_list->AtimWin; pAd->MlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod; pAd->MlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration; pAd->MlmeAux.APRalinkIe = ie_list->RalinkIe; /* Copy AP's supported rate to MlmeAux for creating assoication request Also filter out not supported rate */ pAd->MlmeAux.SupRateLen = ie_list->SupRateLen; NdisMoveMemory(pAd->MlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen); RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen); pAd->MlmeAux.ExtRateLen = ie_list->ExtRateLen; NdisMoveMemory(pAd->MlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen); RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen); NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16); /* Get the ext capability info element */ NdisMoveMemory(&pAd->MlmeAux.ExtCapInfo, &ie_list->ExtCapInfo,sizeof(ie_list->ExtCapInfo)); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAux.ExtCapInfo=%d\n", pAd->MlmeAux.ExtCapInfo.BssCoexistMgmtSupport)); if (pAd->CommonCfg.bBssCoexEnable == TRUE) pAd->CommonCfg.ExtCapIE.BssCoexistMgmtSupport = 1; #endif /* DOT11N_DRAFT3 */ if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) && (pAd->StaCfg.WepStatus != Ndis802_11Encryption2Enabled)) || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) { if ((pAd->StaCfg.BssType == BSS_INFRA) || ((pAd->StaCfg.BssType == BSS_ADHOC) && (pAd->StaCfg.bAdhocN == TRUE))) bAllowNrate = TRUE; } pAd->MlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset; pAd->MlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen; CentralChannel = ie_list->Channel; RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); /* filter out un-supported ht rates */ if (((ie_list->HtCapabilityLen > 0) || (ie_list->PreNHtCapabilityLen > 0)) && (pAd->StaCfg.DesiredHtPhyInfo.bHtEnable) && (WMODE_CAP_N(pAd->CommonCfg.PhyMode) && bAllowNrate)) { RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &ie_list->AddHtInfo, SIZE_ADD_HT_INFO_IE); /* StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability */ NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, ie_list->HtCapability.MCSSet, 16); pAd->MlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset; pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE; pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE; if (ie_list->PreNHtCapabilityLen > 0) pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE; RTMPCheckHt(pAd, BSSID_WCID, &ie_list->HtCapability, &ie_list->AddHtInfo); /* Copy AP Parameter to StaActive. This is also in LinkUp. */ DBGPRINT(RT_DEBUG_TRACE, ("%s():(MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n", __FUNCTION__, pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, ie_list->HtCapability.HtCapInfo.ChannelWidth)); if (ie_list->AddHtInfoLen > 0) { /* Check again the Bandwidth capability of this AP. */ CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo, &ie_list->HtCapability); DBGPRINT(RT_DEBUG_OFF, ("%s(): HT-CtrlChannel=%d, CentralChannel=>%d\n", __FUNCTION__, ie_list->AddHtInfo.ControlChan, CentralChannel)); } #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (pAd->MlmeAux.Channel > 14) && (ie_list->vht_cap_len)) { VHT_OP_INFO *vht_op = &ie_list->vht_op_ie.vht_op_info; NdisMoveMemory(&pAd->MlmeAux.vht_cap, &ie_list->vht_cap_ie, ie_list->vht_cap_len); pAd->MlmeAux.vht_cap_len = ie_list->vht_cap_len; pAd->StaActive.SupportedPhyInfo.bVhtEnable = TRUE; if (vht_op->ch_width > 0) { CentralChannel = vht_op->center_freq_1; pAd->StaActive.SupportedPhyInfo.vht_bw = VHT_BW_80; } DBGPRINT(RT_DEBUG_OFF, ("%s(): VHT->center_freq_1=%d, CentralChannel=>%d\n", __FUNCTION__, vht_op->center_freq_1, CentralChannel)); } #endif /* DOT11_VHT_AC */ } else #endif /* DOT11_N_SUPPORT */ { /* To prevent error, let legacy AP must have same CentralChannel and Channel. */ if ((ie_list->HtCapabilityLen == 0) && (ie_list->PreNHtCapabilityLen == 0)) pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel; pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; #ifdef DOT11_VHT_AC pAd->StaActive.SupportedPhyInfo.bVhtEnable = FALSE; pAd->StaActive.SupportedPhyInfo.vht_bw = VHT_BW_2040; #endif /* DOT11_VHT_AC */ pAd->MlmeAux.NewExtChannelOffset = 0xff; RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); pAd->MlmeAux.HtCapabilityLen = 0; RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); } pAd->MlmeAux.CentralChannel = CentralChannel; DBGPRINT(RT_DEBUG_OFF, ("%s(): Set CentralChannel=%d\n", __FUNCTION__, pAd->MlmeAux.CentralChannel)); RTMPUpdateMlmeRate(pAd); /* copy QOS related information */ if ((pAd->CommonCfg.bWmmCapable) #ifdef DOT11_N_SUPPORT || WMODE_CAP_N(pAd->CommonCfg.PhyMode) #endif /* DOT11_N_SUPPORT */ ) { NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else { NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("%s(): - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", __FUNCTION__, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen)); if (ie_list->AironetCellPowerLimit != 0xFF) { /* We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit); } else /* Used the default TX Power Percentage. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; if (pAd->StaCfg.BssType == BSS_INFRA) { BOOLEAN InfraAP_BW; UCHAR BwFallBack = 0; if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40) InfraAP_BW = TRUE; else InfraAP_BW = FALSE; AdjustChannelRelatedValue(pAd, &BwFallBack, BSS0, InfraAP_BW, pAd->MlmeAux.Channel, pAd->MlmeAux.CentralChannel #ifdef CONFIG_MULTI_CHANNEL ,0 #endif /*CONFIG_MULTI_CHANNEL*/ ); #ifdef P2P_SUPPORT if (BwFallBack == 1) { DBGPRINT(RT_DEBUG_TRACE, ("P2P STA connection to 40MHz GO, but Infra extra and P2P Group extra is different!!!\n")); pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = BW_20; pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel; pAd->MlmeAux.bBwFallBack = TRUE; } else { pAd->MlmeAux.bBwFallBack = FALSE; } pAd->MlmeAux.ConCurrentCentralChannel = pAd->CommonCfg.CentralChannel; #endif /* P2P_SUPPORT */ } pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status, 0); #ifdef LINUX #ifdef RT_CFG80211_SUPPORT RT_CFG80211_SCANNING_INFORM(pAd, Idx, Elem->Channel, Elem->Msg, Elem->MsgLen, Rssi); #endif /* RT_CFG80211_SUPPORT */ #endif /* LINUX */ } /* not to me BEACON, ignored */ } /* sanity check fail, ignore this frame */ goto LabelOK; LabelErr: DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); LabelOK: if (ie_list != NULL) os_free_mem(NULL, ie_list); if (VarIE != NULL) os_free_mem(NULL, VarIE); return; } /* ========================================================================== Description: receive BEACON from peer IRQL = DISPATCH_LEVEL ========================================================================== */ VOID PeerBeacon( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR index=0; USHORT TbttNumToNextWakeUp; USHORT LenVIE; UCHAR *VarIE = NULL; /* Total VIE length = MAX_VIE_LEN - -5 */ NDIS_802_11_VARIABLE_IEs *pVIE = NULL; BCN_IE_LIST *ie_list = NULL; #ifdef RALINK_ATE if (ATE_ON(pAd)) { return; } #endif /* RALINK_ATE */ if (!(INFRA_ON(pAd) || ADHOC_ON(pAd) #ifdef P2P_SUPPORT || P2P_GO_ON(pAd) || P2P_CLI_ON(pAd) #endif /* P2P_SUPPORT */ )) return; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) goto LabelErr; NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) goto LabelErr; /* Init Variable IE structure */ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { BOOLEAN is_my_bssid, is_my_ssid; ULONG Bssidx, Now; BSS_ENTRY *pBss; CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20)); is_my_bssid = MAC_ADDR_EQUAL(ie_list->Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE; is_my_ssid = SSID_EQUAL(ie_list->Ssid, ie_list->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE; /* ignore BEACON not for my SSID */ if ((!is_my_ssid) && (!is_my_bssid)) goto LabelOK; /* It means STA waits disassoc completely from this AP, ignores this beacon. */ if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC) goto LabelOK; #ifdef DOT11_N_SUPPORT /* Copy Control channel for this BSSID. */ if (ie_list->AddHtInfoLen != 0) ie_list->Channel = ie_list->AddHtInfo.ControlChan; if ((ie_list->HtCapabilityLen > 0) || (ie_list->PreNHtCapabilityLen > 0)) ie_list->HtCapabilityLen = SIZE_HT_CAP_IE; #endif /* DOT11_N_SUPPORT */ /* Housekeeping "SsidBssTab" table for later-on ROAMing usage. */ Bssidx = BssTableSearchWithSSID(&pAd->MlmeAux.SsidBssTab, ie_list->Bssid, ie_list->Ssid, ie_list->SsidLen, ie_list->Channel); if (Bssidx == BSS_NOT_FOUND) { /* discover new AP of this network, create BSS entry */ Bssidx = BssTableSetEntry(pAd, &pAd->MlmeAux.SsidBssTab, ie_list, RealRssi, LenVIE, pVIE); if (Bssidx == BSS_NOT_FOUND) ; else { PBSS_ENTRY pBssEntry = &pAd->MlmeAux.SsidBssTab.BssEntry[Bssidx]; NdisMoveMemory(&pBssEntry->PTSF[0], &Elem->Msg[24], 4); NdisMoveMemory(&pBssEntry->TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pBssEntry->TTSF[4], &Elem->TimeStamp.u.LowPart, 4); pBssEntry->Rssi = RealRssi; NdisMoveMemory(pBssEntry->MacAddr, ie_list->Addr2, MAC_ADDR_LEN); } } /* Update ScanTab */ Bssidx = BssTableSearch(&pAd->ScanTab, ie_list->Bssid, ie_list->Channel); if (Bssidx == BSS_NOT_FOUND) { /* discover new AP of this network, create BSS entry */ Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, RealRssi, LenVIE, pVIE); if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */ goto LabelOK; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); pAd->ScanTab.BssEntry[Bssidx].MinSNR = Elem->Signal % 10; if (pAd->ScanTab.BssEntry[Bssidx].MinSNR == 0) pAd->ScanTab.BssEntry[Bssidx].MinSNR = -5; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].MacAddr, ie_list->Addr2, MAC_ADDR_LEN); } /* if the ssid matched & bssid unmatched, we should select the bssid with large value. This might happened when two STA start at the same time */ if ((! is_my_bssid) && ADHOC_ON(pAd)) { INT i; #ifdef IWSC_SUPPORT if ((pAd->StaCfg.WscControl.WscConfMode != WSC_DISABLE) && (pAd->StaCfg.WscControl.bWscTrigger == TRUE)) { ; } else #endif /* IWSC_SUPPORT */ /* Add the safeguard against the mismatch of adhoc wep status */ if ((pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus) || (pAd->StaCfg.AuthMode != pAd->ScanTab.BssEntry[Bssidx].AuthMode)) { goto LabelOK; } /* collapse into the ADHOC network which has bigger BSSID value. */ for (i = 0; i < 6; i++) { if (ie_list->Bssid[i] > pAd->CommonCfg.Bssid[i]) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(ie_list->Bssid))); AsicDisableSync(pAd); COPY_MAC_ADDR(pAd->CommonCfg.Bssid, ie_list->Bssid); AsicSetBssid(pAd, pAd->CommonCfg.Bssid); MakeIbssBeacon(pAd); /* re-build BEACON frame */ AsicEnableIbssSync(pAd); /* copy BEACON frame to on-chip memory */ is_my_bssid = TRUE; break; } else if (ie_list->Bssid[i] < pAd->CommonCfg.Bssid[i]) break; } } NdisGetSystemUpTime(&Now); pBss = &pAd->ScanTab.BssEntry[Bssidx]; pBss->Rssi = RealRssi; /* lastest RSSI */ pBss->LastBeaconRxTime = Now; /* last RX timestamp */ /* BEACON from my BSSID - either IBSS or INFRA network */ if (is_my_bssid) { RXWI_STRUC RxWI; UINT8 RXWISize = pAd->chipCap.RXWISize; #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 OVERLAP_BSS_SCAN_IE BssScan; UCHAR RegClass; BOOLEAN brc; /* Read Beacon's Reg Class IE if any. */ brc = PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &BssScan, &RegClass); if (brc == TRUE) { UpdateBssScanParm(pAd, BssScan); pAd->StaCfg.RegClass = RegClass; } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ pAd->StaCfg.DtimCount = ie_list->DtimCount; pAd->StaCfg.DtimPeriod = ie_list->DtimPeriod; pAd->StaCfg.LastBeaconRxTime = Now; NdisZeroMemory(&RxWI, RXWISize); RxWI.RxWIRSSI0 = Elem->Rssi0; RxWI.RxWIRSSI1 = Elem->Rssi1; RxWI.RxWIRSSI2 = Elem->Rssi2; RxWI.RxWIPhyMode = 0; /* Prevent SNR calculate error. */ if (INFRA_ON(pAd)) { MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID]; if (pEntry) Update_Rssi_Sample(pAd, &pEntry->RssiSample, &RxWI); } Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI); if ((pAd->CommonCfg.bIEEE80211H == 1) && (ie_list->NewChannel != 0) && (ie_list->Channel != ie_list->NewChannel)) { /* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */ /* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */ AsicSwitchChannel(pAd, 1, FALSE); AsicLockChannel(pAd, 1); LinkDown(pAd, FALSE); MlmeQueueInit(pAd, &pAd->Mlme.Queue); BssTableInit(&pAd->ScanTab); RTMPusecDelay(1000000); /* use delay to prevent STA do reassoc */ /* channel sanity check */ for (index = 0 ; index < pAd->ChannelListNum; index++) { if (pAd->ChannelList[index].Channel == ie_list->NewChannel) { pAd->ScanTab.BssEntry[Bssidx].Channel = ie_list->NewChannel; pAd->CommonCfg.Channel = ie_list->NewChannel; AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", ie_list->NewChannel)); break; } } if (index >= pAd->ChannelListNum) { DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum)); } } #ifdef WPA_SUPPLICANT_SUPPORT if (pAd->StaCfg.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS) ; else #endif /* WPA_SUPPLICANT_SUPPORT */ #ifdef WSC_STA_SUPPORT if (pAd->StaCfg.WscControl.WscState == WSC_STATE_OFF) #endif /* WSC_STA_SUPPORT */ { if ((((pAd->StaCfg.WepStatus != Ndis802_11WEPDisabled) << 4) ^ ie_list->CapabilityInfo) & 0x0010) { /* To prevent STA connect to OPEN/WEP AP when STA is OPEN/NONE or STA connect to OPEN/NONE AP when STA is OPEN/WEP AP. */ DBGPRINT(RT_DEBUG_TRACE, ("%s:AP privacy:%x is differenct from STA privacy:%x\n", __FUNCTION__, (ie_list->CapabilityInfo & 0x0010) >> 4 , pAd->StaCfg.WepStatus != Ndis802_11WEPDisabled)); if (INFRA_ON(pAd)) { LinkDown(pAd,FALSE); BssTableInit(&pAd->ScanTab); } goto LabelOK; } } #ifdef LINUX #ifdef RT_CFG80211_SUPPORT /* CFG80211_BeaconCountryRegionParse(pAd, pVIE, LenVIE); */ #endif /* RT_CFG80211_SUPPORT */ #endif /* LINUX */ if (ie_list->AironetCellPowerLimit != 0xFF) { /* We get the Cisco (ccx) "TxPower Limit" required Changed to appropriate TxPower Limit for Ciso Compatible Extensions */ ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit); } else { /* AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist. Used the default TX Power Percentage, that set from UI. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; } if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(ie_list->CapabilityInfo))) { UCHAR MaxSupportedRateIn500Kbps = 0; UCHAR idx; MAC_TABLE_ENTRY *pEntry; #ifdef WSC_STA_SUPPORT PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; #endif /* WSC_STA_SUPPORT */ MaxSupportedRateIn500Kbps = dot11_max_sup_rate(ie_list->SupRateLen, &ie_list->SupRate[0], ie_list->ExtRateLen, &ie_list->ExtRate[0]); /* look up the existing table */ pEntry = MacTableLookup(pAd, ie_list->Addr2); /* Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon. To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station. */ if ((ADHOC_ON(pAd) && ((!pEntry) || (pEntry && IS_ENTRY_NONE(pEntry)))) || (pEntry && RTMP_TIME_AFTER(Now, pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME))) { if (pEntry == NULL) /* Another adhoc joining, add to our MAC table. */ pEntry = MacTableInsertEntry(pAd, ie_list->Addr2, BSS0, OPMODE_STA, FALSE); if (pEntry == NULL) goto LabelOK; #ifdef IWSC_SUPPORT hex_dump("Another adhoc joining - Addr2", ie_list->Addr2, 6); hex_dump("Another adhoc joining - WscPeerMAC", pAd->StaCfg.WscControl.WscPeerMAC, 6); if ((NdisEqualMemory(ie_list->Addr2, pAd->StaCfg.WscControl.WscPeerMAC, MAC_ADDR_LEN)) && (pAd->StaCfg.IWscInfo.bSendEapolStart == FALSE) && (pWpsCtrl->bWscTrigger == TRUE)) { pAd->StaCfg.IWscInfo.bSendEapolStart = TRUE; } #endif /* IWSC_SUPPORT */ #ifdef DOT11_VHT_AC { BOOLEAN result; IE_LISTS *ielist; os_alloc_mem(NULL, (UCHAR **)&ielist, sizeof(IE_LISTS)); if (!ielist) goto LabelOK; NdisZeroMemory((UCHAR *)ielist, sizeof(IE_LISTS)); if (ie_list->vht_cap_len && ie_list->vht_op_len) { NdisMoveMemory(&ielist->vht_cap, &ie_list->vht_cap_ie, sizeof(VHT_CAP_IE)); NdisMoveMemory(&ielist->vht_op, &ie_list->vht_op_ie, sizeof(VHT_OP_IE)); ielist->vht_cap_len = ie_list->vht_cap_len; ielist->vht_op_len = ie_list->vht_op_len; } result = StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &ie_list->HtCapability, ie_list->HtCapabilityLen, &ie_list->AddHtInfo, ie_list->AddHtInfoLen, ielist, ie_list->CapabilityInfo); os_free_mem(NULL, ielist); if ( result== FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n")); goto LabelOK; } #ifdef IWSC_SUPPORT else pEntry->bUpdateInfoFromPeerBeacon = TRUE; #endif /* IWSC_SUPPORT */ } #else if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &ie_list->HtCapability, ie_list->HtCapabilityLen, &ie_list->AddHtInfo, ie_list->AddHtInfoLen, ie_list, ie_list->CapabilityInfo) == FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n")); goto LabelOK; } #ifdef IWSC_SUPPORT else pEntry->bUpdateInfoFromPeerBeacon = TRUE; #endif /* IWSC_SUPPORT */ #endif /* DOT11_VHT_AC */ if (ADHOC_ON(pAd) && pEntry) { RTMPSetSupportMCS(pAd, OPMODE_STA, pEntry, ie_list->SupRate, ie_list->SupRateLen, ie_list->ExtRate, ie_list->ExtRateLen, #ifdef DOT11_VHT_AC ie_list->vht_cap_len, &ie_list->vht_cap_ie, #endif /* DOT11_VHT_AC */ &ie_list->HtCapability, ie_list->HtCapabilityLen); } pEntry->LastBeaconRxTime = 0; #ifdef ADHOC_WPA2PSK_SUPPORT /* Adhoc support WPA2PSK by Eddy */ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) && (pEntry->WPA_Authenticator.WpaState < AS_INITPSK) #ifdef IWSC_SUPPORT && ((pAd->StaCfg.WscControl.WscConfMode == WSC_DISABLE) || (pAd->StaCfg.WscControl.bWscTrigger == FALSE) || (NdisEqualMemory(pEntry->Addr, pAd->StaCfg.WscControl.WscPeerMAC, MAC_ADDR_LEN) == FALSE)) #ifdef IWSC_TEST_SUPPORT && (pAd->StaCfg.IWscInfo.bBlockConnection == FALSE) #endif /* IWSC_TEST_SUPPORT */ #endif // IWSC_SUPPORT // ) { INT len, i; PEID_STRUCT pEid; NDIS_802_11_VARIABLE_IEs *pVIE2 = NULL; BOOLEAN bHigherMAC = FALSE; pVIE2 = pVIE; len = LenVIE; while (len > 0) { pEid = (PEID_STRUCT) pVIE; if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) { NdisMoveMemory(pEntry->RSN_IE, pVIE, (pEid->Len + 2)); pEntry->RSNIE_Len = (pEid->Len + 2); } pVIE2 += (pEid->Len + 2); len -= (pEid->Len + 2); } pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; NdisZeroMemory(&pEntry->WPA_Supplicant.ReplayCounter, LEN_KEY_DESC_REPLAY); NdisZeroMemory(&pEntry->WPA_Authenticator.ReplayCounter, LEN_KEY_DESC_REPLAY); pEntry->WPA_Authenticator.WpaState = AS_INITPSK; pEntry->WPA_Supplicant.WpaState = AS_INITPSK; pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_PSK; for (i = 0; i < 6; i++) { if (ie_list->Addr2[i] > pAd->CurrentAddress[i]) { bHigherMAC = TRUE; break; } else if (ie_list->Addr2[i] < pAd->CurrentAddress[i]) break; } hex_dump("PeerBeacon:: Addr2", ie_list->Addr2, MAC_ADDR_LEN); hex_dump("PeerBeacon:: CurrentAddress", pAd->CurrentAddress, MAC_ADDR_LEN); pEntry->bPeerHigherMAC = bHigherMAC; if (pEntry->bPeerHigherMAC == FALSE) { /* My MAC address is higher than peer's MAC address. */ DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - EnqueueStartForPSKTimer.\n")); RTMPSetTimer(&pEntry->EnqueueStartForPSKTimer, ENQUEUE_EAPOL_START_TIMER); } } else { pEntry->PortSecured = WPA_802_1X_PORT_SECURED; } #endif /* ADHOC_WPA2PSK_SUPPORT */ if (pEntry && (Elem->Wcid == RESERVED_WCID)) { idx = pAd->StaCfg.DefaultKeyId; RTMP_SET_WCID_SEC_INFO(pAd, BSS0, idx, pAd->SharedKey[BSS0][idx].CipherAlg, pEntry->Aid, SHAREDKEYTABLE); } } if (pEntry && IS_ENTRY_CLIENT(pEntry)) { pEntry->LastBeaconRxTime = Now; #ifdef IWSC_SUPPORT if (pEntry->bUpdateInfoFromPeerBeacon == FALSE) { if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &ie_list->HtCapability, ie_list->HtCapabilityLen, &ie_list->AddHtInfo, ie_list->AddHtInfoLen, ie_list, ie_list->CapabilityInfo) == FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("ADHOC 2 - Add Entry failed.\n")); return; } if (ADHOC_ON(pAd) && pEntry) { RTMPSetSupportMCS(pAd, OPMODE_STA, pEntry, ie_list->SupRate, ie_list->SupRateLen, ie_list->ExtRate, ie_list->ExtRateLen, #ifdef DOT11_VHT_AC ie_list->vht_cap_len, &ie_list->vht_cap_ie, #endif /* DOT11_VHT_AC */ &ie_list->HtCapability, ie_list->HtCapabilityLen); } pEntry->bUpdateInfoFromPeerBeacon = TRUE; } #endif /* IWSC_SUPPORT */ } /* At least another peer in this IBSS, declare MediaState as CONNECTED */ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); RTMP_IndicateMediaState(pAd, NdisMediaStateConnected); pAd->ExtraInfo = GENERAL_LINK_UP; DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n")); } #ifdef IWSC_SUPPORT if (pAd->StaCfg.IWscInfo.bSendEapolStart && (pAd->Mlme.IWscMachine.CurrState != IWSC_WAIT_PIN) && (pAd->StaCfg.WscControl.WscConfMode == WSC_ENROLLEE)) { pAd->StaCfg.IWscInfo.bSendEapolStart = FALSE; pWpsCtrl->WscState = WSC_STATE_LINK_UP; pWpsCtrl->WscStatus = STATUS_WSC_LINK_UP; NdisMoveMemory(pWpsCtrl->EntryAddr, pWpsCtrl->WscPeerMAC, MAC_ADDR_LEN); WscSendEapolStart(pAd, pWpsCtrl->WscPeerMAC, STA_MODE); } #endif // IWSC_SUPPORT } if (INFRA_ON(pAd)) { BOOLEAN bUseShortSlot, bUseBGProtection; /* decide to use/change to - 1. long slot (20 us) or short slot (9 us) time 2. turn on/off RTS/CTS and/or CTS-to-self protection 3. short preamble */ /* bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo); */ bUseShortSlot = CAP_IS_SHORT_SLOT(ie_list->CapabilityInfo); if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)) AsicSetSlotTime(pAd, bUseShortSlot); bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || /* always use */ ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(ie_list->Erp)); if (pAd->CommonCfg.Channel > 14) /* always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP */ bUseBGProtection = FALSE; if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) { if (bUseBGProtection) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT), FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)); } else { OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE, (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)); } DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection)); } #ifdef DOT11_N_SUPPORT /* check Ht protection mode. and adhere to the Non-GF device indication by AP. */ if ((ie_list->AddHtInfoLen != 0) && ((ie_list->AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) || (ie_list->AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent))) { pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = ie_list->AddHtInfo.AddHtInfo2.NonGfPresent; pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = ie_list->AddHtInfo.AddHtInfo2.OperaionMode; if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) { AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE); } else AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode)); } #endif /* DOT11_N_SUPPORT */ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) && ERP_IS_USE_BARKER_PREAMBLE(ie_list->Erp)) { MlmeSetTxPreamble(pAd, Rt802_11PreambleLong); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n")); } if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && (ie_list->EdcaParm.bValid == TRUE) && (ie_list->EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount)) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n", pAd->CommonCfg.APEdcaParm.EdcaUpdateCount, ie_list->EdcaParm.EdcaUpdateCount)); AsicSetEdcaParm(pAd, &ie_list->EdcaParm); } /* copy QOS related information */ NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM)); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* 2009: PF#1: 20/40 Coexistence in 2.4 GHz Band When AP changes "STA Channel Width" and "Secondary Channel Offset" fields of HT Operation Element in the Beacon to 0 */ if ((ie_list->AddHtInfoLen != 0) && INFRA_ON(pAd) && pAd->CommonCfg.Channel <= 14) { BOOLEAN bChangeBW = FALSE; #ifdef P2P_SUPPORT PAPCLI_STRUCT pApCliEntry = NULL; pApCliEntry = &pAd->ApCfg.ApCliTab[BSS0]; #endif /* P2P_SUPPORT */ /* 1) HT Information 2) Secondary Channel Offset Element 40 -> 20 case */ if (pAd->CommonCfg.BBPCurrentBW == BW_40) { if (((ie_list->AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_NONE) && (ie_list->AddHtInfo.AddHtInfo.RecomWidth == 0)) ||(ie_list->NewExtChannelOffset==0x0) ) { pAd->StaActive.SupportedHtPhy.ChannelWidth = BW_20; pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW = 0; #ifdef P2P_SUPPORT if (!P2P_GO_ON(pAd) && (pApCliEntry->Valid == FALSE)) #endif /* P2P_SUPPORT */ { bChangeBW = TRUE; pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; DBGPRINT(RT_DEBUG_TRACE, ("FallBack from 40MHz to 20MHz(CtrlCh=%d, CentralCh=%d)\n", pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel)); CntlChannelWidth(pAd, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel, BW_20, 0); } } } /* 20 -> 40 case 1.) Supported Channel Width Set Field of the HT Capabilities element of both STAs is set to a non-zero 2.) Secondary Channel Offset field is SCA or SCB 3.) 40MHzRegulatoryClass is TRUE (not implement it) */ else if (((pAd->CommonCfg.BBPCurrentBW == BW_20) ||(ie_list->NewExtChannelOffset!=0x0)) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth != BW_20) ) { if ((ie_list->AddHtInfo.AddHtInfo.ExtChanOffset != EXTCHA_NONE) && (ie_list->AddHtInfo.AddHtInfo.RecomWidth == 1) && (ie_list->HtCapabilityLen>0) && (ie_list->HtCapability.HtCapInfo.ChannelWidth == 1) ) { #ifdef P2P_SUPPORT if (!P2P_GO_ON(pAd) && (pApCliEntry->Valid == FALSE)) #endif /* P2P_SUPPORT */ { pAd->CommonCfg.CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo, &ie_list->HtCapability); if (pAd->CommonCfg.CentralChannel != ie_list->AddHtInfo.ControlChan) bChangeBW = TRUE; if (bChangeBW) { pAd->CommonCfg.Channel = ie_list->AddHtInfo.ControlChan; pAd->StaActive.SupportedHtPhy.ChannelWidth = BW_40; DBGPRINT(RT_DEBUG_TRACE, ("FallBack from 20MHz to 40MHz(CtrlCh=%d, CentralCh=%d)\n", pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel)); CntlChannelWidth(pAd, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel, BW_40, ie_list->AddHtInfo.AddHtInfo.ExtChanOffset); pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW = 1; } } } } if (bChangeBW) { pAd->CommonCfg.BSSCoexist2040.word = 0; TriEventInit(pAd); BuildEffectedChannelList(pAd); } } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ } /* only INFRASTRUCTURE mode support power-saving feature */ if ((INFRA_ON(pAd) && (RtmpPktPmBitCheck(pAd) == TRUE)) || (pAd->CommonCfg.bAPSDForcePowerSave)) { UCHAR FreeNumber; /* 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE 5. otherwise, put PHY back to sleep to save battery. */ if (ie_list->MessageToMe) { #ifdef PCIE_PS_SUPPORT if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { /* Restore to correct BBP R3 value */ if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); /* Turn clk to 80Mhz. */ } #endif /* PCIE_PS_SUPPORT */ #ifdef UAPSD_SUPPORT if (pAd->StaCfg.UapsdInfo.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO) { pAd->CommonCfg.bNeedSendTriggerFrame = TRUE; #ifdef DOT11Z_TDLS_SUPPORT RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE, pAd->CommonCfg.bAPSDForcePowerSave ? PWR_SAVE : pAd->StaCfg.Psm); #endif /* DOT11Z_TDLS_SUPPORT */ } else #endif /* UAPSD_SUPPORT */ { if (pAd->StaCfg.WindowsBatteryPowerMode == Ndis802_11PowerModeFast_PSP) { /* wake up and send a NULL frame with PM = 0 to the AP */ RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE); RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE), PWR_ACTIVE); } else { /* use PS-Poll to get any buffered packet */ RTMP_PS_POLL_ENQUEUE(pAd); } } } else if (ie_list->BcastFlag && (ie_list->DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM)) { #ifdef PCIE_PS_SUPPORT if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } #endif /* PCIE_PS_SUPPORT */ } else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) || (pAd->TxSwQueue[QID_AC_BE].Number != 0) || (pAd->TxSwQueue[QID_AC_VI].Number != 0) || (pAd->TxSwQueue[QID_AC_VO].Number != 0) || (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)) { /* TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme */ /* can we cheat here (i.e. just check MGMT & AC_BE) for better performance? */ #ifdef PCIE_PS_SUPPORT if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } #endif /* PCIE_PS_SUPPORT */ } else { if ((pAd->CommonCfg.bACMAPSDTr[QID_AC_VO]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_VI]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_BK]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_BE]) #ifdef DOT11Z_TDLS_SUPPORT || (pAd->StaCfg.FlgPsmCanNotSleep == TRUE)|| (RtmpPktPmBitCheck(pAd) == FALSE) #endif /* DOT11Z_TDLS_SUPPORT */ ) { } else { USHORT NextDtim = ie_list->DtimCount; if (NextDtim == 0) NextDtim = ie_list->DtimPeriod; TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount; if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim)) TbttNumToNextWakeUp = NextDtim; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { /* Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode. */ pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp; AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp); } } } } } /* not my BSSID, ignore it */ } /* sanity check fail, ignore this frame */ goto LabelOK; LabelErr: DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); LabelOK: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (ie_list != NULL) os_free_mem(NULL, ie_list); return; } /* ========================================================================== Description: Receive PROBE REQ from remote peer when operating in IBSS mode ========================================================================== */ VOID PeerProbeReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Addr2[MAC_ADDR_LEN]; CHAR Ssid[MAX_LEN_OF_SSID]; UCHAR SsidLen; #ifdef DOT11_N_SUPPORT UCHAR HtLen, AddHtLen, NewExtLen; #endif /* DOT11_N_SUPPORT */ HEADER_802_11 ProbeRspHdr; NDIS_STATUS NStatus; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; LARGE_INTEGER FakeTimestamp; UCHAR DsLen = 1, IbssLen = 2; UCHAR LocalErpIe[3] = {IE_ERP, 1, 0}; BOOLEAN Privacy; USHORT CapabilityInfo; #ifdef P2P_SUPPORT /* P2P device and Listen State could response Probe Req. */ /* if ((pAd->P2pCfg.DiscCurrentState == P2P_DISC_LISTEN) && !(P2P_CLI_ON(pAd)))*/ if(P2P_INF_ON(pAd)) MlmeEnqueue(pAd, P2P_DISC_STATE_MACHINE, P2P_DISC_PEER_PROB_REQ, Elem->MsgLen, Elem->Msg, Elem->Channel); #endif /* P2P_SUPPORT */ if (! ADHOC_ON(pAd)) return; if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen, NULL)) { if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)) { /* allocate and send out ProbeRsp frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) return; MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, Addr2, #ifdef P2P_SUPPORT pAd->CurrentAddress, #endif /* P2P_SUPPORT */ pAd->CommonCfg.Bssid); Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled); CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &ProbeRspHdr, TIMESTAMP_LEN, &FakeTimestamp, 2, &pAd->CommonCfg.BeaconPeriod, 2, &CapabilityInfo, 1, &SsidIe, 1, &pAd->CommonCfg.SsidLen, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid, 1, &SupRateIe, 1, &pAd->StaActive.SupRateLen, pAd->StaActive.SupRateLen, pAd->StaActive.SupRate, 1, &DsIe, 1, &DsLen, 1, &pAd->CommonCfg.Channel, 1, &IbssIe, 1, &IbssLen, 2, &pAd->StaActive.AtimWin, END_OF_ARGS); if (pAd->StaActive.ExtRateLen) { ULONG tmp; MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 3, LocalErpIe, 1, &ExtRateIe, 1, &pAd->StaActive.ExtRateLen, pAd->StaActive.ExtRateLen, &pAd->StaActive.ExtRate, END_OF_ARGS); FrameLen += tmp; } /* Modify by Eddy, support WPA2PSK in Adhoc mode */ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) #ifdef ADHOC_WPA2PSK_SUPPORT || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) #endif /* ADHOC_WPA2PSK_SUPPORT */ ) { ULONG tmp; UCHAR RSNIe = IE_WPA; #ifdef ADHOC_WPA2PSK_SUPPORT RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0); if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) RSNIe = IE_RSN; #endif /* ADHOC_WPA2PSK_SUPPORT */ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &RSNIe, 1, &pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE, END_OF_ARGS); FrameLen += tmp; } #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ULONG TmpLen; USHORT epigram_ie_len; UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33}; HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); NewExtLen = 1; /* New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */ if (pAd->bBroadComHT == TRUE) { epigram_ie_len = pAd->MlmeAux.HtCapabilityLen + 4; MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM[0], pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability, END_OF_ARGS); } else { MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability, 1, &AddHtInfoIe, 1, &AddHtLen, sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); } FrameLen += TmpLen; } #endif /* DOT11_N_SUPPORT */ #ifdef WSC_STA_SUPPORT /* add Simple Config Information Element */ if (pAd->StaCfg.WpsIEProbeResp.ValueLen != 0) { ULONG WscTmpLen = 0; MakeOutgoingFrame(pOutBuffer + FrameLen, &WscTmpLen, pAd->StaCfg.WpsIEProbeResp.ValueLen, pAd->StaCfg.WpsIEProbeResp.Value, END_OF_ARGS); FrameLen += WscTmpLen; } #endif /* WSC_STA_SUPPORT */ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } } } VOID BeaconTimeoutAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT Status; DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n")); pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_REJ_TIMEOUT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status, 0); } /* ========================================================================== Description: Scan timeout procedure. basically add channel index by 1 and rescan ========================================================================== */ VOID ScanTimeoutAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { #ifdef RTMP_MAC_USB /* To prevent data lost. Send an NULL data with turned PSM bit on to current associated AP when SCAN in the channel where associated AP located. */ if ((pAd->CommonCfg.Channel == pAd->MlmeAux.Channel) && (pAd->MlmeAux.ScanType == SCAN_ACTIVE) && (INFRA_ON(pAd)) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) ) { RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE), PWR_SAVE); } #endif /* RTMP_MAC_USB */ if (pAd->StaCfg.bFastConnect && !pAd->StaCfg.bNotFirstScan) { pAd->MlmeAux.Channel = 0; pAd->StaCfg.bNotFirstScan = TRUE; } else { pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel); } /* Only one channel scanned for CISCO beacon request */ if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) || (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) || (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) || (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD)) pAd->MlmeAux.Channel = 0; /* this routine will stop if pAd->MlmeAux.Channel == 0 */ ScanNextChannel(pAd, OPMODE_STA); } /* ========================================================================== Description: ========================================================================== */ VOID InvalidStateWhenScan( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT Status; #ifdef P2P_SUPPORT UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType; #endif /* P2P_SUPPORT */ if (Elem->MsgType != MT2_MLME_SCAN_REQ) DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState)); else DBGPRINT(RT_DEBUG_TRACE, ("AYNC - Already in scanning, do nothing here.(state=%ld). \n", pAd->Mlme.SyncMachine.CurrState)); #ifdef P2P_SUPPORT if (MlmeScanReqSanity(pAd, Elem->Msg, Elem->MsgLen, &BssType, (PCHAR)Ssid, &SsidLen, &ScanType)) { /* reset Device Discovery State Machine. */ MlmeEnqueue(pAd, P2P_CTRL_STATE_MACHINE, P2P_CTRL_DISC_CANL_EVT, 0, NULL, 0); P2PSetNextScanTimer(pAd, 10); return; } #endif /* P2P_SUPPORT */ if (Elem->MsgType != MT2_MLME_SCAN_REQ) { pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_STATE_MACHINE_REJECT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0); } } /* ========================================================================== Description: ========================================================================== */ VOID InvalidStateWhenJoin( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT Status; DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld, msg=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState, Elem->MsgType)); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { RTMPResumeMsduTransmission(pAd); } pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_STATE_MACHINE_REJECT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status, 0); } /* ========================================================================== Description: ========================================================================== */ VOID InvalidStateWhenStart( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT Status; DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState)); pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_STATE_MACHINE_REJECT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status, 0); } /* ========================================================================== Description: IRQL = DISPATCH_LEVEL ========================================================================== */ VOID EnqueuePsPoll( IN PRTMP_ADAPTER pAd) { #ifdef RALINK_ATE if (ATE_ON(pAd)) { return; } #endif /* RALINK_ATE */ if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP) pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE; MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME)); #ifdef RTMP_MAC_USB /* Keep Waking up */ if (pAd->CountDowntoPsm == 0) pAd->CountDowntoPsm = 2; /* 100 ms; stay awake 200ms at most, average will be 1xx ms */ #endif /* RTMP_MAC_USB */ } /* ========================================================================== Description: ========================================================================== */ VOID EnqueueProbeRequest( IN PRTMP_ADAPTER pAd) { NDIS_STATUS NState; PUCHAR pOutBuffer; ULONG FrameLen = 0; HEADER_802_11 Hdr80211; DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n")); NState = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory */ if (NState == NDIS_STATUS_SUCCESS) { MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, #ifdef P2P_SUPPORT pAd->CurrentAddress, #endif /* P2P_SUPPORT */ BROADCAST_ADDR); /* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &Hdr80211, 1, &SsidIe, 1, &pAd->CommonCfg.SsidLen, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid, 1, &SupRateIe, 1, &pAd->StaActive.SupRateLen, pAd->StaActive.SupRateLen, pAd->StaActive.SupRate, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } } #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 VOID BuildEffectedChannelList( IN PRTMP_ADAPTER pAd) { UCHAR EChannel[11]; UCHAR i, j, k; UCHAR UpperChannel = 0, LowerChannel = 0; RTMPZeroMemory(EChannel, 11); DBGPRINT(RT_DEBUG_TRACE, ("BuildEffectedChannelList:CtrlCh=%d,CentCh=%d,AuxCtrlCh=%d,AuxExtCh=%d\n", pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel, pAd->MlmeAux.AddHtInfo.ControlChan, pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset)); /* 802.11n D4 11.14.3.3: If no secondary channel has been selected, all channels in the frequency band shall be scanned. */ { for (k = 0;k < pAd->ChannelListNum;k++) { if (pAd->ChannelList[k].Channel <=14 ) pAd->ChannelList[k].bEffectedChannel = TRUE; } return; } i = 0; /* Find upper and lower channel according to 40MHz current operation. */ if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) { UpperChannel = pAd->CommonCfg.Channel; LowerChannel = pAd->CommonCfg.CentralChannel-2; } else if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) { UpperChannel = pAd->CommonCfg.CentralChannel+2; LowerChannel = pAd->CommonCfg.Channel; } else { DBGPRINT(RT_DEBUG_TRACE, ("LinkUP 20MHz . No Effected Channel \n")); /* Now operating in 20MHz, doesn't find 40MHz effected channels */ return; } DeleteEffectedChannelList(pAd); DBGPRINT(RT_DEBUG_TRACE, ("BuildEffectedChannelList!LowerChannel ~ UpperChannel; %d ~ %d \n", LowerChannel, UpperChannel)); /* Find all channels that are below lower channel.. */ if (LowerChannel > 1) { EChannel[0] = LowerChannel - 1; i = 1; if (LowerChannel > 2) { EChannel[1] = LowerChannel - 2; i = 2; if (LowerChannel > 3) { EChannel[2] = LowerChannel - 3; i = 3; } } } /* Find all channels that are between lower channel and upper channel. */ for (k = LowerChannel;k <= UpperChannel;k++) { EChannel[i] = k; i++; } /* Find all channels that are above upper channel.. */ if (UpperChannel < 14) { EChannel[i] = UpperChannel + 1; i++; if (UpperChannel < 13) { EChannel[i] = UpperChannel + 2; i++; if (UpperChannel < 12) { EChannel[i] = UpperChannel + 3; i++; } } } /* Total i channels are effected channels. Now find corresponding channel in ChannelList array. Then set its bEffectedChannel= TRUE */ for (j = 0;j < i;j++) { for (k = 0;k < pAd->ChannelListNum;k++) { if (pAd->ChannelList[k].Channel == EChannel[j]) { pAd->ChannelList[k].bEffectedChannel = TRUE; DBGPRINT(RT_DEBUG_TRACE,(" EffectedChannel[%d]( =%d)\n", k, EChannel[j])); break; } } } } VOID DeleteEffectedChannelList( IN PRTMP_ADAPTER pAd) { UCHAR i; /*Clear all bEffectedChannel in ChannelList array. */ for (i = 0; i < pAd->ChannelListNum; i++) { pAd->ChannelList[i].bEffectedChannel = FALSE; } } /* ======================================================================== Routine Description: Control Primary&Central Channel, ChannelWidth and Second Channel Offset Arguments: pAd Pointer to our adapter PrimaryChannel Primary Channel CentralChannel Central Channel ChannelWidth BW_20 or BW_40 SecondaryChannelOffset EXTCHA_NONE, EXTCHA_ABOVE and EXTCHA_BELOW Return Value: None Note: ======================================================================== */ VOID CntlChannelWidth( IN PRTMP_ADAPTER pAd, IN UCHAR prim_ch, IN UCHAR cent_ch, IN UCHAR ch_bw, IN UCHAR sec_ch_offset) { UCHAR rf_channel = 0, rf_bw; INT32 ext_ch; DBGPRINT(RT_DEBUG_TRACE, ("%s: PrimaryChannel[%d] \n",__FUNCTION__,prim_ch)); DBGPRINT(RT_DEBUG_TRACE, ("%s: CentralChannel[%d] \n",__FUNCTION__,cent_ch)); DBGPRINT(RT_DEBUG_TRACE, ("%s: ChannelWidth[%d] \n",__FUNCTION__,ch_bw)); DBGPRINT(RT_DEBUG_TRACE, ("%s: SecondaryChannelOffset[%d] \n",__FUNCTION__,sec_ch_offset)); #ifdef DOT11_N_SUPPORT /*Change to AP channel */ if (ch_bw == BW_40) { if(sec_ch_offset == EXTCHA_ABOVE) { rf_bw = BW_40; ext_ch = EXTCHA_ABOVE; rf_channel = cent_ch; } else if (sec_ch_offset == EXTCHA_BELOW) { rf_bw = BW_40; ext_ch = EXTCHA_BELOW; rf_channel = cent_ch; } } else #endif /* DOT11_N_SUPPORT */ { rf_bw = BW_20; ext_ch = EXTCHA_NONE; rf_channel = prim_ch; } if (rf_channel != 0) { rtmp_bbp_set_bw(pAd, rf_bw); /* Tx/ RX : control channel setting */ rtmp_bbp_set_ctrlch(pAd, ext_ch); rtmp_mac_set_ctrlch(pAd, ext_ch); AsicSwitchChannel(pAd, rf_channel, FALSE); AsicLockChannel(pAd, rf_channel); #ifdef RT28xx RT28xx_ch_tunning(pAd, rf_bw); #endif /* RT28xx */ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel )); rtmp_bbp_get_agc(pAd, &pAd->BbpTuning.R66CurrentValue, RX_CHAIN_0); } } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ /* ========================================================================== Description: MLME Cancel the SCAN req state machine procedure ========================================================================== */ VOID ScanCnclAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { BOOLEAN Cancelled; RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); pAd->MlmeAux.Channel = 0; ScanNextChannel(pAd, OPMODE_STA); return; }