示例#1
0
/*----------------------------------------------------------------------------*/
VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
{
	P_SEC_INFO_T prSecInfo;
	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
	ENUM_SEC_STATE_T eNextState;

	DBGLOG(RSN, TRACE, ("secFsmRunEventStart\n"));

	ASSERT(prSta);

	if (!prSta)
		return;

	if (!IS_STA_IN_AIS(prSta))
		return;

	DBGLOG(RSN, TRACE, ("secFsmRunEventStart for sta " MACSTR " bss %d\n",
			    MAC2STR(prSta->aucMacAddr), prSta->ucBssIndex));

	prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo;

	eNextState = prSecInfo->eCurrentState;

	secSetPortBlocked(prAdapter, prSta, TRUE);

	/* prSta->fgTransmitKeyExist = FALSE; */
	/* whsu:: nicPrivacySetStaDefaultWTIdx(prSta); */

#if 1				/* Since the 1x and key can set to firmware in order, always enter the check ok state */
	SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK);
#else
	if (IS_STA_IN_AIS(prSta->eStaType)) {
		if (secRsnKeyHandshakeEnabled(prAdapter) == TRUE
#if CFG_SUPPORT_WAPI
		    || (prAdapter->rWifiVar.rConnSettings.fgWapiMode)
#endif
		    ) {
			prSta->fgTransmitKeyExist = FALSE;
			/* nicPrivacyInitialize(prSta->ucNetTypeIndex); */
			SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED);
		} else {
			SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK);
		}
	}
#if CFG_ENABLE_WIFI_DIRECT || CFG_ENABLE_BT_OVER_WIFI
#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_BT_OVER_WIFI
	else if ((prSta->eStaType == STA_TYPE_BOW_CLIENT) || (prSta->eStaType == STA_TYPE_P2P_GC))
#elif CFG_ENABLE_WIFI_DIRECT
	else if (prSta->eStaType == STA_TYPE_P2P_GC)
#elif CFG_ENABLE_BT_OVER_WIFI
	else if (prSta->eStaType == STA_TYPE_BOW_CLIENT)
#endif
	{
		SEC_STATE_TRANSITION(prAdapter, prSta, INIT, RESPONDER_PORT_BLOCKED);
	}
#endif
	else {
		SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED);
	}
#endif
	if (prSecInfo->eCurrentState != eNextState) {
		secFsmSteps(prAdapter, prSta, eNextState);
	}

	return;
}				/* secFsmRunEventStart */
示例#2
0
/*----------------------------------------------------------------------------*/
VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
{
	P_SEC_INFO_T prSecInfo;
	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
	ENUM_SEC_STATE_T eNextState;

	DBGLOG(RSN, TRACE, "secFsmRunEventStart\n");

	ASSERT(prSta);

	if (!prSta)
		return;

	if (!IS_STA_IN_AIS(prSta))
		return;

	DBGLOG(RSN, TRACE, "secFsmRunEventStart for sta %pM network %d\n",
			    prSta->aucMacAddr, prSta->ucNetTypeIndex);

	prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo;

	eNextState = prSecInfo->eCurrentState;

	secSetPortBlocked(prAdapter, prSta, TRUE);

	/* prSta->fgTransmitKeyExist = FALSE; */
	/* whsu:: nicPrivacySetStaDefaultWTIdx(prSta); */

#if 1				/* Since the 1x and key can set to firmware in order, always enter the check ok state */
	SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK);
#else
	if (IS_STA_IN_AIS(prSta->eStaType)) {
		if (secRsnKeyHandshakeEnabled(prAdapter) == TRUE
#if CFG_SUPPORT_WAPI
		    || (prAdapter->rWifiVar.rConnSettings.fgWapiMode)
#endif
		    ) {
			prSta->fgTransmitKeyExist = FALSE;
			/* nicPrivacyInitialize(prSta->ucNetTypeIndex); */
			SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED);
		} else {
			SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK);
		}
	}
#if CFG_ENABLE_WIFI_DIRECT || CFG_ENABLE_BT_OVER_WIFI
#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_BT_OVER_WIFI
	else if ((prSta->eStaType == STA_TYPE_BOW_CLIENT) || (prSta->eStaType == STA_TYPE_P2P_GC)) {
#elif CFG_ENABLE_WIFI_DIRECT
	else if (prSta->eStaType == STA_TYPE_P2P_GC) {
#elif CFG_ENABLE_BT_OVER_WIFI
	else if (prSta->eStaType == STA_TYPE_BOW_CLIENT) {
#endif
		SEC_STATE_TRANSITION(prAdapter, prSta, INIT, RESPONDER_PORT_BLOCKED);
	}
#endif
	else
		SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED);
#endif
	if (prSecInfo->eCurrentState != eNextState)
		secFsmSteps(prAdapter, prSta, eNextState);

	return;
}				/* secFsmRunEventStart */

/*----------------------------------------------------------------------------*/
/*!
* \brief This function called by reset procedure to force the sec fsm enter
*        idle state
*
* \param[in] ucNetTypeIdx  The Specific Network type index
* \param[in] prSta         Pointer to the Sta record
*
* \return none
*/
/*----------------------------------------------------------------------------*/
VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
{
	P_SEC_INFO_T prSecInfo;

	DBGLOG(RSN, TRACE, "secFsmEventAbort for sta %pM network %d\n",
			    prSta->aucMacAddr, prSta->ucNetTypeIndex);

	ASSERT(prSta);

	if (!prSta)
		return;

	if (!IS_STA_IN_AIS(prSta))
		return;

	prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo;

	prSta->fgTransmitKeyExist = FALSE;

	secSetPortBlocked(prAdapter, prSta, TRUE);

	if (prSecInfo == NULL)
		return;

	if (IS_STA_IN_AIS(prSta)) {

		prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE;

		if (prSecInfo->eCurrentState == SEC_STATE_SEND_EAPOL) {
			if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone == FALSE) {
				DBGLOG(RSN, TRACE, "EAPOL STATE not match the flag\n");
				/* cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.
				 * rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); */
			}
		}
	}
	prSecInfo->eCurrentState = SEC_STATE_INIT;
}

/*----------------------------------------------------------------------------*/
/*!
* \brief This function will indicate an Event of "2nd EAPoL Tx is sending" to Sec FSM.
*
* \param[in] prSta            Pointer to the Sta record
*
* \return -
*/
/*----------------------------------------------------------------------------*/
VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
{
	P_SEC_INFO_T prSecInfo;
	ENUM_SEC_STATE_T eNextState;
	/* BOOLEAN                 fgIsTransition = (BOOLEAN)FALSE; */

	DEBUGFUNC("secFsmRunEvent2ndEapolTx");

	ASSERT(prSta);

	prSecInfo = &prSta->rSecInfo;
	eNextState = prSecInfo->eCurrentState;

#if DBG
	DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr,
			    apucDebugSecState[prSecInfo->eCurrentState]);
#else
	DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState);
#endif

	switch (prSecInfo->eCurrentState) {
	case SEC_STATE_INITIATOR_PORT_BLOCKED:
	case SEC_STATE_CHECK_OK:
		prSecInfo->fg2nd1xSend = TRUE;
		break;
	default:
#if DBG
		DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at %s\n", apucDebugSecState[prSecInfo->eCurrentState]);
#else
		DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at [%d]\n", prSecInfo->eCurrentState);
#endif
		break;
	}

	if (prSecInfo->eCurrentState != eNextState)
		secFsmSteps(prAdapter, prSta, eNextState);

	return;

}				/* secFsmRunEvent2ndEapolTx */
示例#3
0
/*----------------------------------------------------------------------------*/
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() */