/*----------------------------------------------------------------------------*/ VOID nicProcessAtimWindowTimeoutInterrupt ( IN P_ADAPTER_T prAdapter ) { #if CFG_IBSS_POWER_SAVE ASSERT(prAdapter); if (!PM_IS_UNDER_IBSS_POWER_SAVE_MODE(prAdapter)) { return; } PM_SET_FLAG_OUTSIDE_ATIM_WINDOW(prAdapter); DBGLOG(LP, INFO, ("\n")); nicTxDisableTxQueueActiveState(prAdapter); /* flush AC4 for in-completed ATIM packets */ nicTxFlushStopQueues(prAdapter, TXQ_MGMT_MASK, TXQ_MGMT_MASK); /* Enable AC0~3, AC4 (for out-of-bound MGMT frame) */ nicTxStartQueues(prAdapter, TXQ_DATA_MASK | TXQ_MGMT_MASK); /* Trigger TX actions */ if (nicTxRetransmitOfStaWaitQue(prAdapter)) { pmDisableIbssPsTx(prAdapter); } #endif /* CFG_IBSS_POWER_SAVE */ return; }
/*----------------------------------------------------------------------------*/ WLAN_STATUS scanFsmRunEventScanAbort ( IN P_ADAPTER_T prAdapter ) { P_SCAN_INFO_T prScanInfo; ENUM_SCAN_STATE_T eNextState; WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; DEBUGFUNC("scanFsmRunEventScanAbort"); DBGLOG(SCAN, INFO, ("scanFsmRunEventScanAbort\n")); ASSERT(prAdapter); prScanInfo = &prAdapter->rScanInfo; eNextState = prScanInfo->eCurrentState; if (prScanInfo->eCurrentState != SCAN_STATE_IDLE) { //4 <1> Make state transition to SCAN_STATE_IDLE SCAN_STATE_TRANSITION1(prAdapter, ACTIVE, IDLE, ABORT); //4 <2> Cancel SCAN Timeout Timer. ARB_CANCEL_TIMER(prAdapter, prScanInfo->rScanCheckForHangTimer); //4 <3> Do call back function. if (prScanInfo->rScanConfig.pfScanDoneHandler) { prScanInfo->rScanConfig.pfScanDoneHandler(prAdapter, WLAN_STATUS_FAILURE); } #if CFG_WORKAROUND_HEC_5512 //4 <4> Recover from aborting from BG SSID scan state if (prScanInfo->eCurrentHwScanMode == ENUM_HW_SCAN_BG_SSID_SCAN) { #if 0 DBGLOG(SCAN, INFO, ("Recover from aborting from BG SSID scan state\n")); nicTxFlushStopQueues(prAdapter, TXQ_MGMT_MASK, 0x0 /*(UINT_8)NULL*/); nicTxStartQueues(prAdapter, TXQ_MGMT_MASK); scanSendProbeReqFrames(prAdapter, NULL, 0, 1, 0, FALSE); kalMdelay(10); #else nicLogicReset(prAdapter); #endif } #endif } NIC_RESET_INT_EVENT(prAdapter, INT_EVENT_SCAN_DONE); return rStatus; }
/*----------------------------------------------------------------------------*/ WLAN_STATUS scanFsmRunEventScanStop ( IN P_ADAPTER_T prAdapter ) { P_SCAN_INFO_T prScanInfo; ENUM_SCAN_STATE_T eNextState; WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; DEBUGFUNC("scanFsmRunEventScanStop"); ASSERT(prAdapter); DBGLOG(SCAN, INFO, ("scanFsmRunEventScanStop\n")); prScanInfo = &prAdapter->rScanInfo; eNextState = prScanInfo->eCurrentState; if (prScanInfo->eCurrentState != SCAN_STATE_IDLE) { //4 <1> Make state transition to SCAN_STATE_IDLE SCAN_STATE_TRANSITION1(prAdapter, ACTIVE, IDLE, ABORT); //4 <2> Cancel SCAN Timeout Timer. ARB_CANCEL_TIMER(prAdapter, prScanInfo->rScanCheckForHangTimer); //4 <3> Check SCAN Status for issuing Next Partial SCAN or completing the whole SCAN sequence. if (prScanInfo->eCurrentHwScanMode == ENUM_HW_SCAN_NORMAL_SCAN) { scanCheckScanStatus(prAdapter); } #if CFG_WORKAROUND_HEC_5512 //4 <4> Recover from aborting from BG SSID scan state if (prScanInfo->eCurrentHwScanMode == ENUM_HW_SCAN_BG_SSID_SCAN) { #if 0 DBGLOG(SCAN, INFO, ("Recover from stopping from BG SSID scan state\n")); nicTxFlushStopQueues(prAdapter, TXQ_MGMT_MASK, 0x0 /*(UINT_8)NULL*/); nicTxStartQueues(prAdapter, TXQ_MGMT_MASK); scanSendProbeReqFrames(prAdapter, NULL, 0, 1, 0, FALSE); kalMdelay(10); #else nicLogicReset(prAdapter); #endif } #endif } return rStatus; }
/*----------------------------------------------------------------------------*/ VOID scanFsmStep ( IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState ) { P_SCAN_INFO_T prScanInfo; P_SCAN_STATUS_T prScanStatus; DEBUGFUNC("scanFsmStep"); ASSERT(prAdapter); prScanInfo = &prAdapter->rScanInfo; prScanStatus = &prScanInfo->rScanStatus; DBGLOG(SCAN, STATE, ("TRANSITION: [%s] -> [%s]\n", apucDebugScanState[prScanInfo->eCurrentState], apucDebugScanState[eNextState])); prScanInfo->eCurrentState = eNextState; /* Do tasks of the State that we just entered */ switch (prScanInfo->eCurrentState) { case SCAN_STATE_IDLE: /* Enable beacon timeout counter, which is disabled during scan */ nicpmEnableTimeoutCounter(prAdapter); /* Set RX filter for not to receive beacon from different BSSID */ NIC_UNSET_RX_FILTER(prAdapter, RXFILTER_RXDIFFBSSIDBCN); /* Set RX filter for not to receive probe response from different BSSID */ NIC_UNSET_RX_FILTER(prAdapter, RXFILTER_RXDIFFBSSIDPRORESP); #if CFG_WORKAROUND_HEC_5269 /* Flush AC4 before set TX_DONE event */ nicTxFlushStopQueues(prAdapter, TXQ_MGMT_MASK, 0x0 /*(UINT_8)NULL*/); /* Set TX_DONE event */ NIC_SET_INT_EVENT(prAdapter, INT_EVENT_TX); #endif nicHwScanConfigRestore(prAdapter, &prScanInfo->rScanConfig, prScanInfo->eCurrentHwScanMode); if (prScanInfo->eCurrentHwScanMode == ENUM_HW_SCAN_NORMAL_SCAN) { DBGLOG(SCAN, INFO, (">>ucLastScanChnlIdx = %d, ucLastScanBandIdx = %d.\n", prScanStatus->ucLastScanChnlIdx, prScanStatus->ucLastScanBandIdx)); nicHwScanGetLastScannedChnlFreq( prAdapter, &prScanStatus->ucLastScanChnlIdx, &prScanStatus->ucLastScanBandIdx); DBGLOG(SCAN, INFO, ("<<ucLastScanChnlIdx = %d, ucLastScanBandIdx = %d.\n", prScanStatus->ucLastScanChnlIdx, prScanStatus->ucLastScanBandIdx)); DBGLOG(SCAN, INFO, ("ucNumOfScanChnl = %d\n", prScanInfo->rScanConfig.ucNumOfScanChnl)); } break; case SCAN_STATE_ACTIVE: break; default: ASSERT(0); /* Make sure we have handle all STATEs */ } return; }
/*----------------------------------------------------------------------------*/ VOID joinComplete(IN P_ADAPTER_T prAdapter) { P_JOIN_INFO_T prJoinInfo; P_BSS_DESC_T prBssDesc; P_PEER_BSS_INFO_T prPeerBssInfo; P_BSS_INFO_T prBssInfo; P_CONNECTION_SETTINGS_T prConnSettings; P_STA_RECORD_T prStaRec; P_TX_CTRL_T prTxCtrl; #if CFG_SUPPORT_802_11D P_IE_COUNTRY_T prIECountry; #endif DEBUGFUNC("joinComplete"); ASSERT(prAdapter); prJoinInfo = &prAdapter->rJoinInfo; prBssDesc = prJoinInfo->prBssDesc; prPeerBssInfo = &prAdapter->rPeerBssInfo; prBssInfo = &prAdapter->rBssInfo; prConnSettings = &prAdapter->rConnSettings; prTxCtrl = &prAdapter->rTxCtrl; /* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ /* Remove previous AP's Connection Flags if have */ scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID); prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ if (prBssDesc->fgIsHiddenSSID) { /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't * broadcast SSID on its Beacon Frame. */ COPY_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen); if (prBssDesc->ucSSIDLen) prBssDesc->fgIsHiddenSSID = FALSE; #if DBG else ASSERT(0); #endif /* DBG */ DBGLOG(JOIN, INFO, ("Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID)); } /* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ /* 4 <2.A> PHY Type */ prBssInfo->ePhyType = prBssDesc->ePhyType; /* 4 <2.B> BSS Type */ prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; /* 4 <2.C> BSSID */ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); DBGLOG(JOIN, INFO, ("JOIN to BSSID: [" MACSTR "]\n", MAC2STR(prBssDesc->aucBSSID))); /* 4 <2.D> SSID */ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); /* 4 <2.E> Channel / Band information. */ prBssInfo->eBand = prBssDesc->eBand; prBssInfo->ucChnl = prBssDesc->ucChannelNum; /* 4 <2.F> RSN/WPA information. */ secFsmRunEventStart(prAdapter); prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher; prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; if (secRsnKeyHandshakeEnabled()) prBssInfo->fgIsWPAorWPA2Enabled = TRUE; else prBssInfo->fgIsWPAorWPA2Enabled = FALSE; /* 4 <2.G> Beacon interval. */ prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; /* 4 <2.H> DTIM period. */ prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; /* 4 <2.I> ERP Information */ if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */ (prBssDesc->fgIsERPPresent)) { prBssInfo->fgIsERPPresent = TRUE; prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */ } else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */ prBssInfo->fgIsERPPresent = FALSE; prBssInfo->ucERP = 0; } #if CFG_SUPPORT_802_11D /* 4 <2.J> Country inforamtion of the associated AP */ if (prConnSettings->fgMultiDomainCapabilityEnabled) { DOMAIN_INFO_ENTRY rDomainInfo; if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { if (prBssDesc->prIECountry) { prIECountry = prBssDesc->prIECountry; domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo); /* use the domain get from the BSS info */ prBssInfo->fgIsCountryInfoPresent = TRUE; nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE); } else { /* use the domain get from the scan result */ prBssInfo->fgIsCountryInfoPresent = TRUE; nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE); } } } #endif /* 4 <2.K> Signal Power of the associated AP */ prBssInfo->rRcpi = prBssDesc->rRcpi; prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); /* 4 <2.L> Capability Field of the associated AP */ prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; DBGLOG(JOIN, INFO, ("prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi)); /* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ /* 4 <3.A> Association ID */ prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; /* 4 <3.B> WMM Infomation */ if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { prBssInfo->fgIsWmmAssoc = TRUE; prTxCtrl->rTxQForVoipAccess = TXQ_AC3; qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); } else { kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); } } else { prBssInfo->fgIsWmmAssoc = FALSE; prTxCtrl->rTxQForVoipAccess = TXQ_AC1; kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); } /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; /* 4 <3.D> Short Preamble */ if (prBssInfo->fgIsERPPresent) { /* NOTE(Kevin 2007/12/24): Truth Table. * Short Preamble Bit in * <AssocReq><AssocResp w/i ERP><BARKER(Long)>Final Driver Setting(Short) * TRUE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) * TRUE FALSE TRUE FALSE * FALSE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) * FALSE FALSE TRUE FALSE * TRUE TRUE FALSE TRUE(follow ERP) * TRUE TRUE TRUE FALSE(follow ERP) * FALSE TRUE FALSE FALSE(shouldn't have such case, and we should set to FALSE) * FALSE TRUE TRUE FALSE(we should set to FALSE) */ if ((prPeerBssInfo->fgIsShortPreambleAllowed) && ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && (prBssDesc-> u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { prBssInfo->fgIsShortPreambleAllowed = TRUE; if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) prBssInfo->fgUseShortPreamble = FALSE; else prBssInfo->fgUseShortPreamble = TRUE; } else { prBssInfo->fgIsShortPreambleAllowed = FALSE; prBssInfo->fgUseShortPreamble = FALSE; } } else { /* NOTE(Kevin 2007/12/24): Truth Table. * Short Preamble Bit in * <AssocReq> <AssocResp w/o ERP> Final Driver Setting(Short) * TRUE FALSE FALSE * FALSE FALSE FALSE * TRUE TRUE TRUE * FALSE TRUE(status success) TRUE * --> Honor the result of prPeerBssInfo. */ prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = prPeerBssInfo->fgIsShortPreambleAllowed; } DBGLOG(JOIN, INFO, ("prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble)); /* 4 <3.E> Short Slot Time */ prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ DBGLOG(JOIN, INFO, ("prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime)); nicSetSlotTime(prAdapter, prBssInfo->ePhyType, ((prConnSettings->fgIsShortSlotTimeOptionEnable && prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); /* 4 <3.F> Update Tx Rate for Control Frame */ bssUpdateTxRateForControlFrame(prAdapter); /* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */ /* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */ { if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; /* Set the stable time of the associated BSS. We won't do roaming decision * during the stable time. */ SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); } /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ #if CFG_TX_FRAGMENT txFragInfoUpdate(prAdapter); #endif /* CFG_TX_FRAGMENT */ /* 4 <4> Update STA_RECORD_T */ /* Get a Station Record if possible */ prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); if (prStaRec) { UINT_16 u2OperationalRateSet, u2DesiredRateSet; /* 4 <4.A> Desired Rate Set */ u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & prBssInfo->u2OperationalRateSet); u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); if (u2DesiredRateSet) { prStaRec->u2DesiredRateSet = u2DesiredRateSet; } else { /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ prStaRec->u2DesiredRateSet = u2OperationalRateSet; } /* Try to set the best initial rate for this entry */ if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) { ASSERT(0); } } DBGLOG(JOIN, INFO, ("prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index)); /* 4 <4.B> Preamble Mode */ prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble; /* 4 <4.C> QoS Flag */ prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; } #if DBG else ASSERT(0); #endif /* DBG */ /* 4 <5> Update NIC */ /* 4 <5.A> Update BSSID & Operation Mode */ nicSetupBSS(prAdapter, prBssInfo); /* 4 <5.B> Update WLAN Table. */ if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) ASSERT(FALSE); /* 4 <5.C> Update Desired Rate Set for BT. */ #if CFG_TX_FRAGMENT if (prConnSettings->fgIsEnableTxAutoFragmentForBT) txRateSetInitForBT(prAdapter, prStaRec); #endif /* CFG_TX_FRAGMENT */ /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ if (prBssInfo->fgIsWmmAssoc) { #if CFG_TX_AGGREGATE_HW_FIFO nicTxAggregateTXQ(prAdapter, FALSE); #endif /* CFG_TX_AGGREGATE_HW_FIFO */ qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); } else { #if CFG_TX_AGGREGATE_HW_FIFO nicTxAggregateTXQ(prAdapter, TRUE); #endif /* CFG_TX_AGGREGATE_HW_FIFO */ nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); } #if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN { prTxCtrl->fgBlockTxDuringJoin = FALSE; #if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL); #endif /* CFG_TX_AGGREGATE_HW_FIFO */ nicTxRetransmitOfSendWaitQue(prAdapter); if (prTxCtrl->fgIsPacketInOsSendQueue) nicTxRetransmitOfOsSendQue(prAdapter); #if CFG_SDIO_TX_ENHANCE halTxLeftClusteredMpdu(prAdapter); #endif /* CFG_SDIO_TX_ENHANCE */ } #endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ /* 4 <6> Setup CONNECTION flag. */ prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; if (prJoinInfo->fgIsReAssoc) prAdapter->fgBypassPortCtrlForRoaming = TRUE; else prAdapter->fgBypassPortCtrlForRoaming = FALSE; kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0); return; } /* end of joinComplete() */