/*----------------------------------------------------------------------------*/
static VOID
wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter,
			  IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler)
{
	P_MSDU_INFO_T prMsduInfo;
	P_BSS_INFO_T prBssInfo;
	P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME prTxFrame;
	UINT_16 u2PayloadLen;

	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
	ASSERT(prBssInfo);

	prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
						    MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);

	if (!prMsduInfo)
		return;

	prTxFrame = (P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME)
	    ((UINT_32) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);

	prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;

	COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr);
	COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
	COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);

	prTxFrame->ucCategory = CATEGORY_UNPROTECTED_WNM_ACTION;
	prTxFrame->ucAction = ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT;

	/* 3 Compose the frame body's frame. */
	prTxFrame->ucDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken;
	prTxFrame->ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken;
	prTxFrame->u4ToD = prStaRec->rWNMTimingMsmt.u4ToD;
	prTxFrame->u4ToA = prStaRec->rWNMTimingMsmt.u4ToA;
	prTxFrame->ucMaxToDErr = WNM_MAX_TOD_ERROR;
	prTxFrame->ucMaxToAErr = WNM_MAX_TOA_ERROR;

	u2PayloadLen = 2 + ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN;

	/* 4 Update information of MSDU_INFO_T */
	TX_SET_MMPDU(prAdapter,
		     prMsduInfo,
		     prStaRec->ucBssIndex,
		     prStaRec->ucIndex,
		     WLAN_MAC_MGMT_HEADER_LEN,
		     WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, pfTxDoneHandler, MSDU_RATE_MODE_AUTO);

	DBGLOG(WNM, TRACE,
	       ("wnmComposeTimingMeasFrame: ucDialogToken %d ucFollowUpDialogToken %d u4ToD %x u4ToA %x\n",
		prTxFrame->ucDialogToken, prTxFrame->ucFollowUpDialogToken, prTxFrame->u4ToD,
		prTxFrame->u4ToA));

	/* 4 Enqueue the frame to send this action frame. */
	nicTxEnqueueMsdu(prAdapter, prMsduInfo);

	return;

}				/* end of wnmComposeTimingMeasFrame() */
/*----------------------------------------------------------------------------*/
VOID
rlmObssScanExemptionRsp (
    P_ADAPTER_T         prAdapter,
    P_BSS_INFO_T        prBssInfo,
    P_SW_RFB_T          prSwRfb
    )
{
    P_MSDU_INFO_T                   prMsduInfo;
    P_ACTION_20_40_COEXIST_FRAME    prTxFrame;

    /* To do: need an algorithm to do judgement. Now always reject request */

    prMsduInfo = (P_MSDU_INFO_T)
                 cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
    if (prMsduInfo == NULL) {
        return;
    }

    DBGLOG(RLM, INFO, ("Send 20/40 coexistence rsp frame!\n"));

    prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) prMsduInfo->prPacket;

    prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
    COPY_MAC_ADDR(prTxFrame->aucDestAddr,
        ((P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader)->aucSrcAddr);
    COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
    COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);

    prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION;
    prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST;

    /* To do: find correct algorithm */
    prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
    prTxFrame->rBssCoexist.ucLength = 1;
    prTxFrame->rBssCoexist.ucData = 0;

    ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN);

    prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
    prMsduInfo->ucStaRecIndex =prSwRfb->ucStaRecIdx;
    prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
    prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
    prMsduInfo->fgIs802_1x = FALSE;
    prMsduInfo->fgIs802_11 = TRUE;
    prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_HTC_LEN + 5;
    prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
    prMsduInfo->pfTxDoneHandler = NULL;
    prMsduInfo->fgIsBasicRate = FALSE;

    /* Send them to HW queue */
    nicTxEnqueueMsdu(prAdapter, prMsduInfo);
}
/*----------------------------------------------------------------------------*/
VOID
rlmObssScanExemptionRsp (
    P_ADAPTER_T         prAdapter,
    P_BSS_INFO_T        prBssInfo,
    P_SW_RFB_T          prSwRfb
    )
{
    P_MSDU_INFO_T                   prMsduInfo;
    P_ACTION_20_40_COEXIST_FRAME    prTxFrame;

    /* To do: need an algorithm to do judgement. Now always reject request */

    prMsduInfo = (P_MSDU_INFO_T)
                 cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
    if (prMsduInfo == NULL) {
        return;
    }

    DBGLOG(RLM, INFO, ("Send 20/40 coexistence rsp frame!\n"));

    prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) prMsduInfo->prPacket;

    prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
    COPY_MAC_ADDR(prTxFrame->aucDestAddr,
        ((P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader)->aucSrcAddr);
    COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
    COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);

    prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION;
    prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST;

    /* To do: find correct algorithm */
    prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
    prTxFrame->rBssCoexist.ucLength = 1;
    prTxFrame->rBssCoexist.ucData = 0;

    ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN);

    TX_SET_MMPDU(
        prAdapter,
        prMsduInfo,
        prBssInfo->ucBssIndex,
        prSwRfb->ucStaRecIdx,
        WLAN_MAC_MGMT_HEADER_LEN,
        WLAN_MAC_MGMT_HEADER_HTC_LEN + 5,
        NULL,
        MSDU_RATE_MODE_AUTO
        );  

    /* Send them to HW queue */
    nicTxEnqueueMsdu(prAdapter, prMsduInfo);
}
/*----------------------------------------------------------------------------*/
WLAN_STATUS
authSendAuthFrame(IN P_ADAPTER_T prAdapter,
		  IN P_STA_RECORD_T prStaRec,
		  IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
		  IN P_SW_RFB_T prFalseAuthSwRfb,
		  IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode)
{
	PUINT_8 pucReceiveAddr;
	PUINT_8 pucTransmitAddr;
	P_MSDU_INFO_T prMsduInfo;
	P_BSS_INFO_T prBssInfo;
	/*get from input parameter */
	/* ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; */
	PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER) NULL;
	UINT_16 u2EstimatedFrameLen;
	UINT_16 u2EstimatedExtraIELen;
	UINT_16 u2PayloadLen;
	UINT_16 ucAuthAlgNum;
	UINT_32 i;


	DBGLOG(SAA, LOUD, ("Send Auth Frame %d, Status Code = %d\n",
			   u2TransactionSeqNum, u2StatusCode));

	/* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */
	/* Init with MGMT Header Length + Length of Fixed Fields */
	u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD +
			       WLAN_MAC_MGMT_HEADER_LEN +
			       AUTH_ALGORITHM_NUM_FIELD_LEN +
			       AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);

	/* + Extra IE Length */
	u2EstimatedExtraIELen = 0;

	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) {
		u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen;
	}

	u2EstimatedFrameLen += u2EstimatedExtraIELen;

	/* Allocate a MSDU_INFO_T */
	if ((prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == NULL) {
		DBGLOG(SAA, WARN, ("No PKT_INFO_T for sending Auth Frame.\n"));
		return WLAN_STATUS_RESOURCES;
	}
	/* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */
	if (prStaRec) {
		ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);

		prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);

		pucTransmitAddr = prBssInfo->aucOwnMacAddr;

		pucReceiveAddr = prStaRec->aucMacAddr;

		ucAuthAlgNum = prStaRec->ucAuthAlgNum;

		switch (u2TransactionSeqNum) {
		case AUTH_TRANSACTION_SEQ_1:
		case AUTH_TRANSACTION_SEQ_3:
			pfTxDoneHandler = saaFsmRunEventTxDone;
			break;

		case AUTH_TRANSACTION_SEQ_2:
		case AUTH_TRANSACTION_SEQ_4:
			pfTxDoneHandler = aaaFsmRunEventTxDone;
			break;
		}

	} else {		/* For Error Status Code */
		P_WLAN_AUTH_FRAME_T prFalseAuthFrame;


		ASSERT(prFalseAuthSwRfb);
		prFalseAuthFrame = (P_WLAN_AUTH_FRAME_T) prFalseAuthSwRfb->pvHeader;

		ASSERT(u2StatusCode != STATUS_CODE_SUCCESSFUL);

		pucTransmitAddr = prFalseAuthFrame->aucDestAddr;

		pucReceiveAddr = prFalseAuthFrame->aucSrcAddr;

		ucAuthAlgNum = prFalseAuthFrame->u2AuthAlgNum;

		u2TransactionSeqNum = (prFalseAuthFrame->u2AuthTransSeqNo + 1);
	}

	/* Compose Header and some Fixed Fields */
	authComposeAuthFrameHeaderAndFF((PUINT_8)
					((UINT_32) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
					pucReceiveAddr, pucTransmitAddr, ucAuthAlgNum,
					u2TransactionSeqNum, u2StatusCode);

	u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN +
			AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);

	/* 4 <3> Update information of MSDU_INFO_T */
	prMsduInfo->eSrc = TX_PACKET_MGMT;
	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
	if (prStaRec) {
		prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
	} else {
		prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND;	/* false Auth frame */
	}
	prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex;
	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
	prMsduInfo->fgIs802_1x = FALSE;
	prMsduInfo->fgIs802_11 = TRUE;
	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
	prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
	prMsduInfo->fgIsBasicRate = TRUE;

	/* 4 <4> Compose IEs in MSDU_INFO_T */
	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) {
		if (txAuthIETable[i].pfnAppendIE) {
			txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
		}
	}

	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */

	/* 4 <6> Inform TXM  to send this Authentication frame. */
	nicTxEnqueueMsdu(prAdapter, prMsduInfo);

	return WLAN_STATUS_SUCCESS;
}				/* end of authSendAuthFrame() */
/*----------------------------------------------------------------------------*/
WLAN_STATUS
authSendAuthFrame(IN P_ADAPTER_T prAdapter,
		  IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum)
{
	P_MSDU_INFO_T prMsduInfo;
	P_BSS_INFO_T prBssInfo;
	UINT_16 u2EstimatedFrameLen;
	UINT_16 u2EstimatedExtraIELen;
	UINT_16 u2PayloadLen;
	UINT_32 i;


	DBGLOG(SAA, LOUD, ("Send Auth Frame\n"));

	ASSERT(prStaRec);

	/* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */
	/* Init with MGMT Header Length + Length of Fixed Fields */
	u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD +
			       WLAN_MAC_MGMT_HEADER_LEN +
			       AUTH_ALGORITHM_NUM_FIELD_LEN +
			       AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);

	/* + Extra IE Length */
	u2EstimatedExtraIELen = 0;

	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) {
		u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen;
	}

	u2EstimatedFrameLen += u2EstimatedExtraIELen;

	/* Allocate a MSDU_INFO_T */
	if ((prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == NULL) {
		DBGLOG(SAA, WARN, ("No PKT_INFO_T for sending Auth Frame.\n"));
		return WLAN_STATUS_RESOURCES;
	}
	/* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */
	ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);

	/* Compose Header and some Fixed Fields */
	authComposeAuthFrameHeaderAndFF((PUINT_8)
					((UINT_32) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
					prStaRec->aucMacAddr, prBssInfo->aucOwnMacAddr,
					prStaRec->ucAuthAlgNum, u2TransactionSeqNum,
					STATUS_CODE_RESERVED);

	u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN +
			AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);

	/* 4 <3> Update information of MSDU_INFO_T */
	prMsduInfo->eSrc = TX_PACKET_MGMT;
	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
	prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
	prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
	prMsduInfo->fgIs802_1x = FALSE;
	prMsduInfo->fgIs802_11 = TRUE;
	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
	prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone;
	prMsduInfo->fgIsBasicRate = TRUE;

	/* 4 <4> Compose IEs in MSDU_INFO_T */
	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) {
		if (txAuthIETable[i].pfnAppendIE) {
			txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
		}
	}

	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */

	/* 4 <6> Inform TXM  to send this Authentication frame. */
	nicTxEnqueueMsdu(prAdapter, prMsduInfo);

	return WLAN_STATUS_SUCCESS;
}				/* end of authSendAuthFrame() */
/*----------------------------------------------------------------------------*/
VOID
rlmObssScanDone (
    P_ADAPTER_T prAdapter,
    P_MSG_HDR_T prMsgHdr
    )
{
    P_MSG_SCN_SCAN_DONE             prScanDoneMsg;
    P_BSS_INFO_T                    prBssInfo;
    P_MSDU_INFO_T                   prMsduInfo;
    P_ACTION_20_40_COEXIST_FRAME    prTxFrame;
    UINT_16                         i, u2PayloadLen;

    ASSERT(prMsgHdr);

    prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr;
    prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex];
    ASSERT(prBssInfo);

    DBGLOG(RLM, INFO, ("OBSS Scan Done (NetIdx=%d, Mode=%d)\n",
        prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode));

    cnmMemFree(prAdapter, prMsgHdr);

#if CFG_ENABLE_WIFI_DIRECT
    /* AP mode */
    if ((prAdapter->fgIsP2PRegistered) &&
        (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) &&
        (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) {
        return;
    }
#endif

    /* STA mode */
    if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE ||
        !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) {
        DBGLOG(RLM, WARN, ("OBSS Scan Done (NetIdx=%d) -- Aborted!!\n",
            prBssInfo->ucNetTypeIndex));
        return;
    }

    /* To do: check 2.4G channel list to decide if obss mgmt should be
     *        sent to associated AP. Note: how to handle concurrent network?
     * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence
     *        management frame is needed.
     */
    if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 ||
         prBssInfo->auc2G_NonHtChnlList[0] > 0) &&
        (prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
                      MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN)) != NULL) {

        DBGLOG(RLM, INFO, ("Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n",
            prBssInfo->auc2G_20mReqChnlList[0],
            prBssInfo->auc2G_NonHtChnlList[0]));

        prTxFrame = (P_ACTION_20_40_COEXIST_FRAME)
            ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);

        prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
        COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
        COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
        COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);

        prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION;
        prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST;

        /* To do: find correct algorithm */
        prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
        prTxFrame->rBssCoexist.ucLength = 1;
        prTxFrame->rBssCoexist.ucData =
            (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0;

        u2PayloadLen = 2 + 3;

        if (prBssInfo->auc2G_NonHtChnlList[0] > 0) {
            ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);

            prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT;
            prTxFrame->rChnlReport.ucLength =
                prBssInfo->auc2G_NonHtChnlList[0] + 1;
            prTxFrame->rChnlReport.ucRegulatoryClass = 81; /* 2.4GHz, ch1~13 */
            for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] &&
                 i < CHNL_LIST_SZ_2G; i++) {
                prTxFrame->rChnlReport.aucChannelList[i] =
                    prBssInfo->auc2G_NonHtChnlList[i+1];
            }

            u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport);
        }
        ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN);

        /* Clear up channel lists in 2.4G band */
        prBssInfo->auc2G_20mReqChnlList[0] = 0;
        prBssInfo->auc2G_NonHtChnlList[0] = 0;


        //4 Update information of MSDU_INFO_T
        prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;   /* Management frame */
        prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
        prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
        prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
        prMsduInfo->fgIs802_1x = FALSE;
        prMsduInfo->fgIs802_11 = TRUE;
        prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
        prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
        prMsduInfo->pfTxDoneHandler = NULL;
        prMsduInfo->fgIsBasicRate = FALSE;

        //4 Enqueue the frame to send this action frame.
        nicTxEnqueueMsdu(prAdapter, prMsduInfo);
    } /* end of prMsduInfo != NULL */

    if (prBssInfo->u2ObssScanInterval > 0) {
        DBGLOG(RLM, INFO, ("Set OBSS timer (NetIdx=%d, %d sec)\n",
            prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval));

        cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer,
            prBssInfo->u2ObssScanInterval * MSEC_PER_SEC);
    }
}
/*----------------------------------------------------------------------------*/
VOID
wnmComposeTimingMeasFrame (
    IN P_ADAPTER_T         prAdapter,    
    IN P_STA_RECORD_T      prStaRec,
    IN PFN_TX_DONE_HANDLER pfTxDoneHandler
    )
{
    P_MSDU_INFO_T prMsduInfo;
	  P_BSS_INFO_T prBssInfo;
    P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME prTxFrame;
    UINT_16 u2PayloadLen;

    prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
    ASSERT(prBssInfo);

    prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
                      MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);

    if (!prMsduInfo)
        return;

    prTxFrame = (P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME)
        ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);

    prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
    
    COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr);
    COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
    COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);

    prTxFrame->ucCategory = CATEGORY_UNPROTECTED_WNM_ACTION;
    prTxFrame->ucAction = ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT;

    //3 Compose the frame body's frame.
    prTxFrame->ucDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken;
    prTxFrame->ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken;
    prTxFrame->u4ToD = prStaRec->rWNMTimingMsmt.u4ToD;
    prTxFrame->u4ToA = prStaRec->rWNMTimingMsmt.u4ToA;
    prTxFrame->ucMaxToDErr = WNM_MAX_TOD_ERROR;
    prTxFrame->ucMaxToAErr = WNM_MAX_TOA_ERROR;
    
    u2PayloadLen = 2 + ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN;

    //4 Update information of MSDU_INFO_T
    prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;   /* Management frame */
    prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
    prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
    prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
    prMsduInfo->fgIs802_1x = FALSE;
    prMsduInfo->fgIs802_11 = TRUE;
    prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
    prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
    prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
    prMsduInfo->fgIsBasicRate = FALSE;   

    DBGLOG(WNM, TRACE, ("wnmComposeTimingMeasFrame: ucDialogToken %d ucFollowUpDialogToken %d u4ToD %x u4ToA %x\n",
           prTxFrame->ucDialogToken, prTxFrame->ucFollowUpDialogToken,
           prTxFrame->u4ToD, prTxFrame->u4ToA));

    //4 Enqueue the frame to send this action frame.
    nicTxEnqueueMsdu(prAdapter, prMsduInfo);

    return;

} /* end of wnmComposeTimingMeasFrame() */
/*----------------------------------------------------------------------------*/
WLAN_STATUS
authSendAuthFrame(IN P_ADAPTER_T prAdapter,
		  IN P_STA_RECORD_T prStaRec,
		  IN UINT_8 ucBssIndex,
		  IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode)
{
	PUINT_8 pucReceiveAddr;
	PUINT_8 pucTransmitAddr;
	P_MSDU_INFO_T prMsduInfo;
	P_BSS_INFO_T prBssInfo;
	/*get from input parameter */
	/* ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; */
	PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER) NULL;
	UINT_16 u2EstimatedFrameLen;
	UINT_16 u2EstimatedExtraIELen;
	UINT_16 u2PayloadLen;
	UINT_16 ucAuthAlgNum;
	UINT_32 i;

	DBGLOG(SAA, LOUD, "Send Auth Frame %d, Status Code = %d\n", u2TransactionSeqNum, u2StatusCode);

	/* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */
	/* Init with MGMT Header Length + Length of Fixed Fields */
	u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD +
			       WLAN_MAC_MGMT_HEADER_LEN +
			       AUTH_ALGORITHM_NUM_FIELD_LEN +
			       AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);

	/* + Extra IE Length */
	u2EstimatedExtraIELen = 0;

	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++)
		u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen;

	u2EstimatedFrameLen += u2EstimatedExtraIELen;

	/* Allocate a MSDU_INFO_T */
	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
	if (prMsduInfo == NULL) {
		DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n");
		return WLAN_STATUS_RESOURCES;
	}
	/* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */
	if (prStaRec) {
		ASSERT(prStaRec->ucBssIndex <= MAX_BSS_INDEX);
		prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex);

		pucTransmitAddr = prBssInfo->aucOwnMacAddr;

		pucReceiveAddr = prStaRec->aucMacAddr;

		ucAuthAlgNum = prStaRec->ucAuthAlgNum;

		switch (u2TransactionSeqNum) {
		case AUTH_TRANSACTION_SEQ_1:
		case AUTH_TRANSACTION_SEQ_3:
			pfTxDoneHandler = saaFsmRunEventTxDone;
			break;

		case AUTH_TRANSACTION_SEQ_2:
		case AUTH_TRANSACTION_SEQ_4:
			pfTxDoneHandler = aaaFsmRunEventTxDone;
			break;
		}

	} else {		/* For Error Status Code */
		P_WLAN_AUTH_FRAME_T prFalseAuthFrame;

		ASSERT(prFalseAuthSwRfb);
		prFalseAuthFrame = (P_WLAN_AUTH_FRAME_T) prFalseAuthSwRfb->pvHeader;

		ASSERT(u2StatusCode != STATUS_CODE_SUCCESSFUL);

		pucTransmitAddr = prFalseAuthFrame->aucDestAddr;

		pucReceiveAddr = prFalseAuthFrame->aucSrcAddr;

		ucAuthAlgNum = prFalseAuthFrame->u2AuthAlgNum;

		u2TransactionSeqNum = (prFalseAuthFrame->u2AuthTransSeqNo + 1);
	}

	/* Compose Header and some Fixed Fields */
	authComposeAuthFrameHeaderAndFF((PUINT_8)
					((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
					pucReceiveAddr, pucTransmitAddr, ucAuthAlgNum,
					u2TransactionSeqNum, u2StatusCode);

	u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);

	/* 4 <3> Update information of MSDU_INFO_T */

	TX_SET_MMPDU(prAdapter,
		     prMsduInfo,
		     ucBssIndex,
		     (prStaRec != NULL) ? (prStaRec->ucIndex) : (STA_REC_INDEX_NOT_FOUND),
		     WLAN_MAC_MGMT_HEADER_LEN,
		     WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, pfTxDoneHandler, MSDU_RATE_MODE_AUTO);

	if ((ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3))
		nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);
	/* 4 <4> Compose IEs in MSDU_INFO_T */
	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) {
		if (txAuthIETable[i].pfnAppendIE)
			txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo);

	}

	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */

	nicTxConfigPktControlFlag(prMsduInfo, MSDU_CONTROL_FLAG_FORCE_TX, TRUE);

	/* 4 <6> Inform TXM  to send this Authentication frame. */
	nicTxEnqueueMsdu(prAdapter, prMsduInfo);

	return WLAN_STATUS_SUCCESS;
}				/* end of authSendAuthFrame() */
/*----------------------------------------------------------------------------*/
WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum)
{
	P_MSDU_INFO_T prMsduInfo;
	P_BSS_INFO_T prBssInfo;
	UINT_16 u2EstimatedFrameLen;
	UINT_16 u2EstimatedExtraIELen;
	UINT_16 u2PayloadLen;
	UINT_32 i;

	DBGLOG(SAA, LOUD, "Send Auth Frame\n");

	ASSERT(prStaRec);

	/* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */
	/* Init with MGMT Header Length + Length of Fixed Fields */
	u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD +
			       WLAN_MAC_MGMT_HEADER_LEN +
			       AUTH_ALGORITHM_NUM_FIELD_LEN +
			       AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);

	/* + Extra IE Length */
	u2EstimatedExtraIELen = 0;

	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++)
		u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen;

	u2EstimatedFrameLen += u2EstimatedExtraIELen;

	/* Allocate a MSDU_INFO_T */
	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
	if (prMsduInfo == NULL) {
		DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n");
		return WLAN_STATUS_RESOURCES;
	}
	/* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */
	ASSERT(prStaRec->ucBssIndex <= MAX_BSS_INDEX);
	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex)

	    /* Compose Header and some Fixed Fields */
	    authComposeAuthFrameHeaderAndFF((PUINT_8)
					    ((UINT_32) (prMsduInfo->prPacket) +
					     MAC_TX_RESERVED_FIELD), prStaRec->aucMacAddr,
					    prBssInfo->aucOwnMacAddr, prStaRec->ucAuthAlgNum,
					    u2TransactionSeqNum, STATUS_CODE_RESERVED);

	u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);

	/* 4 <3> Update information of MSDU_INFO_T */
	TX_SET_MMPDU(prAdapter,
		     prMsduInfo,
		     prStaRec->ucBssIndex,
		     prStaRec->ucIndex,
		     WLAN_MAC_MGMT_HEADER_LEN,
		     WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, saaFsmRunEventTxDone, MSDU_RATE_MODE_AUTO);

	/* 4 <4> Compose IEs in MSDU_INFO_T */
	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) {
		if (txAuthIETable[i].pfnAppendIE)
			txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo);

	}

	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */

	nicTxConfigPktControlFlag(prMsduInfo, MSDU_CONTROL_FLAG_FORCE_TX, TRUE);

	/* 4 <6> Inform TXM  to send this Authentication frame. */
	nicTxEnqueueMsdu(prAdapter, prMsduInfo);

	return WLAN_STATUS_SUCCESS;
}				/* end of authSendAuthFrame() */