| /****************************************************************************** |
| * |
| * This file is provided under a dual license. When you use or |
| * distribute this software, you may choose to be licensed under |
| * version 2 of the GNU General Public License ("GPLv2 License") |
| * or BSD License. |
| * |
| * GPLv2 License |
| * |
| * Copyright(C) 2016 MediaTek Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of version 2 of the GNU General Public License as |
| * published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| * See http://www.gnu.org/licenses/gpl-2.0.html for more details. |
| * |
| * BSD LICENSE |
| * |
| * Copyright(C) 2016 MediaTek Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of the copyright holder nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| *****************************************************************************/ |
| /* |
| ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan_fsm.c#2 |
| */ |
| |
| /*! \file "scan_fsm.c" |
| * \brief This file defines the state transition function for SCAN FSM. |
| * |
| * The SCAN FSM is part of SCAN MODULE and responsible for performing basic SCAN |
| * behavior as metioned in IEEE 802.11 2007 11.1.3.1 & 11.1.3.2 . |
| */ |
| |
| |
| /******************************************************************************* |
| * C O M P I L E R F L A G S |
| ******************************************************************************** |
| */ |
| |
| /******************************************************************************* |
| * E X T E R N A L R E F E R E N C E S |
| ******************************************************************************** |
| */ |
| #include "precomp.h" |
| |
| /******************************************************************************* |
| * C O N S T A N T S |
| ******************************************************************************** |
| */ |
| |
| /******************************************************************************* |
| * D A T A T Y P E S |
| ******************************************************************************** |
| */ |
| |
| /******************************************************************************* |
| * P U B L I C D A T A |
| ******************************************************************************** |
| */ |
| UINT_8 g_aucScanChannelNum[SCN_SCAN_DONE_PRINT_BUFFER_LENGTH]; |
| UINT_8 g_aucScanChannelIdleTime[SCN_SCAN_DONE_PRINT_BUFFER_LENGTH]; |
| UINT_8 g_aucScanChannelMDRDY[SCN_SCAN_DONE_PRINT_BUFFER_LENGTH]; |
| |
| /******************************************************************************* |
| * P R I V A T E D A T A |
| ******************************************************************************** |
| */ |
| static PUINT_8 apucDebugScanState[SCAN_STATE_NUM] = { |
| (PUINT_8) DISP_STRING("IDLE"), |
| (PUINT_8) DISP_STRING("SCANNING"), |
| }; |
| |
| /******************************************************************************* |
| * M A C R O S |
| ******************************************************************************** |
| */ |
| |
| /******************************************************************************* |
| * F U N C T I O N D E C L A R A T I O N S |
| ******************************************************************************** |
| */ |
| |
| /******************************************************************************* |
| * F U N C T I O N S |
| ******************************************************************************** |
| */ |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_SCAN_PARAM_T prScanParam; |
| P_MSG_HDR_T prMsgHdr; |
| |
| BOOLEAN fgIsTransition = (BOOLEAN) FALSE; |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prScanParam = &prScanInfo->rScanParam; |
| |
| do { |
| DBGLOG(SCN, STATE, "[SCAN]TRANSITION: [%s] -> [%s]\n", |
| apucDebugScanState[prScanInfo->eCurrentState], apucDebugScanState[eNextState]); |
| |
| /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ |
| prScanInfo->eCurrentState = eNextState; |
| |
| fgIsTransition = (BOOLEAN) FALSE; |
| |
| switch (prScanInfo->eCurrentState) { |
| case SCAN_STATE_IDLE: |
| /* check for pending scanning requests */ |
| if (!LINK_IS_EMPTY(&(prScanInfo->rPendingMsgList))) { |
| /* load next message from pending list as scan parameters */ |
| LINK_REMOVE_HEAD(&(prScanInfo->rPendingMsgList), prMsgHdr, P_MSG_HDR_T); |
| |
| if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ |
| || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ |
| || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ |
| || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { |
| scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); |
| |
| eNextState = SCAN_STATE_SCANNING; |
| fgIsTransition = TRUE; |
| } else if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 |
| || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 |
| || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 |
| || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { |
| scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); |
| |
| eNextState = SCAN_STATE_SCANNING; |
| fgIsTransition = TRUE; |
| } else { |
| /* should not happen */ |
| ASSERT(0); |
| } |
| |
| /* switch to next state */ |
| cnmMemFree(prAdapter, prMsgHdr); |
| } |
| break; |
| |
| case SCAN_STATE_SCANNING: |
| if (prScanParam->fgIsScanV2 == FALSE) |
| scnSendScanReq(prAdapter); |
| else |
| scnSendScanReqV2(prAdapter); |
| break; |
| |
| default: |
| ASSERT(0); |
| break; |
| |
| } |
| } while (fgIsTransition); |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Generate CMD_ID_SCAN_REQ command |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID scnSendScanReq(IN P_ADAPTER_T prAdapter) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_SCAN_PARAM_T prScanParam; |
| CMD_SCAN_REQ rCmdScanReq; |
| UINT_32 i; |
| |
| ASSERT(prAdapter); |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prScanParam = &prScanInfo->rScanParam; |
| |
| /* send command packet for scan */ |
| kalMemZero(&rCmdScanReq, sizeof(CMD_SCAN_REQ)); |
| |
| rCmdScanReq.ucSeqNum = prScanParam->ucSeqNum; |
| rCmdScanReq.ucBssIndex = prScanParam->ucBssIndex; |
| rCmdScanReq.ucScanType = (UINT_8) prScanParam->eScanType; |
| rCmdScanReq.ucSSIDType = prScanParam->ucSSIDType; |
| |
| if (prScanParam->ucSSIDNum == 1) { |
| COPY_SSID(rCmdScanReq.aucSSID, |
| rCmdScanReq.ucSSIDLength, |
| prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]); |
| } |
| |
| rCmdScanReq.ucChannelType = (UINT_8) prScanParam->eScanChannel; |
| |
| if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { |
| /* P2P would use: |
| * 1. Specified Listen Channel of passive scan for LISTEN state. |
| * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) |
| */ |
| rCmdScanReq.ucChannelListNum = prScanParam->ucChannelListNum; |
| |
| for (i = 0; i < rCmdScanReq.ucChannelListNum; i++) { |
| rCmdScanReq.arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; |
| |
| rCmdScanReq.arChannelList[i].ucChannelNum = |
| (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; |
| } |
| } |
| |
| rCmdScanReq.u2ChannelDwellTime = prScanParam->u2ChannelDwellTime; |
| rCmdScanReq.u2TimeoutValue = prScanParam->u2TimeoutValue; |
| |
| if (prScanParam->u2IELen <= MAX_IE_LENGTH) |
| rCmdScanReq.u2IELen = prScanParam->u2IELen; |
| else |
| rCmdScanReq.u2IELen = MAX_IE_LENGTH; |
| |
| if (prScanParam->u2IELen) |
| kalMemCopy(rCmdScanReq.aucIE, prScanParam->aucIE, sizeof(UINT_8) * rCmdScanReq.u2IELen); |
| |
| wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SCAN_REQ, |
| TRUE, |
| FALSE, |
| FALSE, |
| NULL, |
| NULL, |
| OFFSET_OF(CMD_SCAN_REQ, aucIE) + rCmdScanReq.u2IELen, (PUINT_8) &rCmdScanReq, NULL, 0); |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Generate CMD_ID_SCAN_REQ_V2 command |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_SCAN_PARAM_T prScanParam; |
| CMD_SCAN_REQ_V2 rCmdScanReq; |
| UINT_32 i; |
| |
| ASSERT(prAdapter); |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prScanParam = &prScanInfo->rScanParam; |
| |
| /* send command packet for scan */ |
| kalMemZero(&rCmdScanReq, sizeof(CMD_SCAN_REQ_V2)); |
| |
| rCmdScanReq.ucSeqNum = prScanParam->ucSeqNum; |
| rCmdScanReq.ucBssIndex = prScanParam->ucBssIndex; |
| rCmdScanReq.ucScanType = (UINT_8) prScanParam->eScanType; |
| rCmdScanReq.ucSSIDType = prScanParam->ucSSIDType; |
| |
| for (i = 0; i < prScanParam->ucSSIDNum; i++) { |
| COPY_SSID(rCmdScanReq.arSSID[i].aucSsid, |
| rCmdScanReq.arSSID[i].u4SsidLen, |
| prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]); |
| } |
| |
| rCmdScanReq.u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime; |
| rCmdScanReq.ucChannelType = (UINT_8) prScanParam->eScanChannel; |
| |
| if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { |
| /* P2P would use: |
| * 1. Specified Listen Channel of passive scan for LISTEN state. |
| * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) |
| */ |
| rCmdScanReq.ucChannelListNum = prScanParam->ucChannelListNum; |
| |
| for (i = 0; i < rCmdScanReq.ucChannelListNum; i++) { |
| rCmdScanReq.arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; |
| |
| rCmdScanReq.arChannelList[i].ucChannelNum = |
| (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; |
| } |
| } |
| |
| rCmdScanReq.u2ChannelDwellTime = prScanParam->u2ChannelDwellTime; |
| rCmdScanReq.u2TimeoutValue = prScanParam->u2TimeoutValue; |
| |
| if (prScanParam->u2IELen <= MAX_IE_LENGTH) |
| rCmdScanReq.u2IELen = prScanParam->u2IELen; |
| else |
| rCmdScanReq.u2IELen = MAX_IE_LENGTH; |
| |
| if (prScanParam->u2IELen) |
| kalMemCopy(rCmdScanReq.aucIE, prScanParam->aucIE, sizeof(UINT_8) * rCmdScanReq.u2IELen); |
| |
| wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SCAN_REQ_V2, |
| TRUE, |
| FALSE, |
| FALSE, |
| NULL, |
| NULL, |
| OFFSET_OF(CMD_SCAN_REQ_V2, aucIE) + rCmdScanReq.u2IELen, (PUINT_8) &rCmdScanReq, NULL, 0); |
| |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_SCAN_PARAM_T prScanParam; |
| |
| ASSERT(prMsgHdr); |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prScanParam = &prScanInfo->rScanParam; |
| |
| if (prScanInfo->eCurrentState == SCAN_STATE_IDLE) { |
| if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ |
| || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ |
| || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { |
| scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); |
| } else if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 |
| || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 |
| || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 |
| || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { |
| scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); |
| } else { |
| /* should not deliver to this function */ |
| ASSERT(0); |
| } |
| |
| cnmMemFree(prAdapter, prMsgHdr); |
| scnFsmSteps(prAdapter, SCAN_STATE_SCANNING); |
| } else { |
| LINK_INSERT_TAIL(&prScanInfo->rPendingMsgList, &prMsgHdr->rLinkEntry); |
| } |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) |
| { |
| P_MSG_SCN_SCAN_CANCEL prScanCancel; |
| P_SCAN_INFO_T prScanInfo; |
| P_SCAN_PARAM_T prScanParam; |
| CMD_SCAN_CANCEL rCmdScanCancel; |
| |
| ASSERT(prMsgHdr); |
| |
| prScanCancel = (P_MSG_SCN_SCAN_CANCEL) prMsgHdr; |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prScanParam = &prScanInfo->rScanParam; |
| |
| if (prScanInfo->eCurrentState != SCAN_STATE_IDLE) { |
| if (prScanCancel->ucSeqNum == prScanParam->ucSeqNum && |
| prScanCancel->ucBssIndex == prScanParam->ucBssIndex) { |
| /* send cancel message to firmware domain */ |
| rCmdScanCancel.ucSeqNum = prScanParam->ucSeqNum; |
| rCmdScanCancel.ucIsExtChannel = (UINT_8) prScanCancel->fgIsChannelExt; |
| |
| wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SCAN_CANCEL, |
| TRUE, |
| FALSE, |
| FALSE, |
| NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8) &rCmdScanCancel, NULL, 0); |
| |
| /* generate scan-done event for caller */ |
| scnFsmGenerateScanDoneMsg(prAdapter, |
| prScanParam->ucSeqNum, |
| prScanParam->ucBssIndex, SCAN_STATUS_CANCELLED); |
| |
| /* switch to next pending scan */ |
| scnFsmSteps(prAdapter, SCAN_STATE_IDLE); |
| } else { |
| scnFsmRemovePendingMsg(prAdapter, prScanCancel->ucSeqNum, prScanCancel->ucBssIndex); |
| } |
| } |
| |
| cnmMemFree(prAdapter, prMsgHdr); |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Scan Message Parsing (Legacy) |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_SCAN_PARAM_T prScanParam; |
| UINT_32 i; |
| |
| ASSERT(prAdapter); |
| ASSERT(prScanReqMsg); |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prScanParam = &prScanInfo->rScanParam; |
| |
| prScanParam->eScanType = prScanReqMsg->eScanType; |
| prScanParam->ucBssIndex = prScanReqMsg->ucBssIndex; |
| prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; |
| if (prScanParam->ucSSIDType & (SCAN_REQ_SSID_SPECIFIED | SCAN_REQ_SSID_P2P_WILDCARD)) { |
| prScanParam->ucSSIDNum = 1; |
| |
| COPY_SSID(prScanParam->aucSpecifiedSSID[0], |
| prScanParam->ucSpecifiedSSIDLen[0], prScanReqMsg->aucSSID, prScanReqMsg->ucSSIDLength); |
| |
| /* reset SSID length to zero for rest array entries */ |
| for (i = 1; i < SCN_SSID_MAX_NUM; i++) |
| prScanParam->ucSpecifiedSSIDLen[i] = 0; |
| } else { |
| prScanParam->ucSSIDNum = 0; |
| |
| for (i = 0; i < SCN_SSID_MAX_NUM; i++) |
| prScanParam->ucSpecifiedSSIDLen[i] = 0; |
| } |
| |
| prScanParam->u2ProbeDelayTime = 0; |
| prScanParam->eScanChannel = prScanReqMsg->eScanChannel; |
| if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { |
| if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) |
| prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; |
| else |
| prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; |
| |
| kalMemCopy(prScanParam->arChnlInfoList, |
| prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); |
| } |
| |
| if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) |
| prScanParam->u2IELen = prScanReqMsg->u2IELen; |
| else |
| prScanParam->u2IELen = MAX_IE_LENGTH; |
| |
| if (prScanParam->u2IELen) |
| kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); |
| |
| prScanParam->u2ChannelDwellTime = prScanReqMsg->u2ChannelDwellTime; |
| prScanParam->u2TimeoutValue = prScanReqMsg->u2TimeoutValue; |
| prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; |
| |
| if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) |
| prScanParam->fgIsObssScan = TRUE; |
| else |
| prScanParam->fgIsObssScan = FALSE; |
| |
| prScanParam->fgIsScanV2 = FALSE; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Scan Message Parsing - V2 with multiple SSID support |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_SCAN_PARAM_T prScanParam; |
| UINT_32 i; |
| |
| ASSERT(prAdapter); |
| ASSERT(prScanReqMsg); |
| ASSERT(prScanReqMsg->ucSSIDNum <= SCN_SSID_MAX_NUM); |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prScanParam = &prScanInfo->rScanParam; |
| |
| prScanParam->eScanType = prScanReqMsg->eScanType; |
| prScanParam->ucBssIndex = prScanReqMsg->ucBssIndex; |
| prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; |
| prScanParam->ucSSIDNum = prScanReqMsg->ucSSIDNum; |
| |
| for (i = 0; i < prScanReqMsg->ucSSIDNum; i++) { |
| COPY_SSID(prScanParam->aucSpecifiedSSID[i], |
| prScanParam->ucSpecifiedSSIDLen[i], |
| prScanReqMsg->prSsid[i].aucSsid, (UINT_8) prScanReqMsg->prSsid[i].u4SsidLen); |
| } |
| |
| prScanParam->u2ProbeDelayTime = prScanReqMsg->u2ProbeDelay; |
| prScanParam->eScanChannel = prScanReqMsg->eScanChannel; |
| if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { |
| if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) |
| prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; |
| else |
| prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; |
| |
| kalMemCopy(prScanParam->arChnlInfoList, |
| prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); |
| } |
| |
| if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) |
| prScanParam->u2IELen = prScanReqMsg->u2IELen; |
| else |
| prScanParam->u2IELen = MAX_IE_LENGTH; |
| |
| if (prScanParam->u2IELen) |
| kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); |
| |
| prScanParam->u2ChannelDwellTime = prScanReqMsg->u2ChannelDwellTime; |
| prScanParam->u2TimeoutValue = prScanReqMsg->u2TimeoutValue; |
| prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; |
| |
| if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) |
| prScanParam->fgIsObssScan = TRUE; |
| else |
| prScanParam->fgIsObssScan = FALSE; |
| |
| prScanParam->fgIsScanV2 = TRUE; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Remove pending scan request |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucBssIndex) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_SCAN_PARAM_T prScanParam; |
| P_MSG_HDR_T prPendingMsgHdr, prPendingMsgHdrNext, prRemoveMsgHdr = NULL; |
| P_LINK_ENTRY_T prRemoveLinkEntry = NULL; |
| BOOLEAN fgIsRemovingScan = FALSE; |
| |
| ASSERT(prAdapter); |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prScanParam = &prScanInfo->rScanParam; |
| |
| /* traverse through rPendingMsgList for removal */ |
| LINK_FOR_EACH_ENTRY_SAFE(prPendingMsgHdr, |
| prPendingMsgHdrNext, &(prScanInfo->rPendingMsgList), rLinkEntry, MSG_HDR_T) { |
| if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ |
| || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ |
| || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ |
| || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { |
| P_MSG_SCN_SCAN_REQ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) prPendingMsgHdr; |
| |
| if (ucSeqNum == prScanReqMsg->ucSeqNum && ucBssIndex == prScanReqMsg->ucBssIndex) { |
| prRemoveLinkEntry = &(prScanReqMsg->rMsgHdr.rLinkEntry); |
| prRemoveMsgHdr = prPendingMsgHdr; |
| fgIsRemovingScan = TRUE; |
| } |
| } else if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 |
| || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 |
| || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 |
| || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { |
| P_MSG_SCN_SCAN_REQ_V2 prScanReqMsgV2 = (P_MSG_SCN_SCAN_REQ_V2) prPendingMsgHdr; |
| |
| if (ucSeqNum == prScanReqMsgV2->ucSeqNum && ucBssIndex == prScanReqMsgV2->ucBssIndex) { |
| prRemoveLinkEntry = &(prScanReqMsgV2->rMsgHdr.rLinkEntry); |
| prRemoveMsgHdr = prPendingMsgHdr; |
| fgIsRemovingScan = TRUE; |
| } |
| } |
| |
| if (prRemoveLinkEntry) { |
| if (fgIsRemovingScan == TRUE) { |
| /* generate scan-done event for caller */ |
| scnFsmGenerateScanDoneMsg(prAdapter, ucSeqNum, ucBssIndex, SCAN_STATUS_CANCELLED); |
| } |
| |
| /* remove from pending list */ |
| LINK_REMOVE_KNOWN_ENTRY(&(prScanInfo->rPendingMsgList), prRemoveLinkEntry); |
| cnmMemFree(prAdapter, prRemoveMsgHdr); |
| |
| break; |
| } |
| } |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone, BOOLEAN fgIsNewVersion) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_SCAN_PARAM_T prScanParam; |
| UINT_32 u4ChCnt; |
| UINT_32 u4PrintfIdx = 0; |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prScanParam = &prScanInfo->rScanParam; |
| |
| kalMemZero(g_aucScanChannelNum, SCN_SCAN_DONE_PRINT_BUFFER_LENGTH); |
| kalMemZero(g_aucScanChannelIdleTime, SCN_SCAN_DONE_PRINT_BUFFER_LENGTH); |
| kalMemZero(g_aucScanChannelMDRDY, SCN_SCAN_DONE_PRINT_BUFFER_LENGTH); |
| |
| if (fgIsNewVersion) { |
| DBGLOG(SCN, INFO, |
| "scnEventScanDone Version%d!size of ScanDone%d,ucCompleteChanCount[%d],ucCurrentState%d, u4ScanDurBcnCnt[%lu]\n", |
| prScanDone->ucScanDoneVersion, sizeof(EVENT_SCAN_DONE), prScanDone->ucCompleteChanCount, |
| prScanDone->ucCurrentState, prScanDone->u4ScanDurBcnCnt); |
| |
| if (prScanDone->ucCurrentState != FW_SCAN_STATE_SCAN_DONE) { |
| DBGLOG(SCN, INFO, |
| "FW Scan timeout!generate ScanDone event at State%d complete chan count%d ucChannelListNum%d\n", |
| prScanDone->ucCurrentState, prScanDone->ucCompleteChanCount, |
| prScanParam->ucChannelListNum); |
| |
| } else { |
| DBGLOG(SCN, INFO, " scnEventScanDone at FW_SCAN_STATE_SCAN_DONE state\n"); |
| } |
| } else { |
| DBGLOG(SCN, INFO, "Old scnEventScanDone Version\n"); |
| } |
| |
| /* buffer empty channel information */ |
| if (prScanParam->eScanChannel == SCAN_CHANNEL_FULL || prScanParam->eScanChannel == SCAN_CHANNEL_2G4) { |
| if (prScanDone->ucSparseChannelValid) { |
| prScanInfo->fgIsSparseChannelValid = TRUE; |
| prScanInfo->rSparseChannel.eBand = (ENUM_BAND_T) prScanDone->rSparseChannel.ucBand; |
| prScanInfo->rSparseChannel.ucChannelNum = prScanDone->rSparseChannel.ucChannelNum; |
| prScanInfo->ucSparseChannelArrayValidNum = prScanDone->ucSparseChannelArrayValidNum; |
| DBGLOG(SCN, INFO, "Detected_Channel_Num = %d\n", prScanInfo->ucSparseChannelArrayValidNum); |
| |
| for (u4ChCnt = 0; u4ChCnt < prScanInfo->ucSparseChannelArrayValidNum; u4ChCnt++) { |
| prScanInfo->aucChannelNum[u4ChCnt] = prScanDone->aucChannelNum[u4ChCnt]; |
| prScanInfo->au2ChannelIdleTime[u4ChCnt] = prScanDone->au2ChannelIdleTime[u4ChCnt]; |
| prScanInfo->aucChannelMDRDYCnt[u4ChCnt] = prScanDone->aucChannelMDRDYCnt[u4ChCnt]; |
| |
| if (u4PrintfIdx % 10 == 0 && u4PrintfIdx != 0) { |
| DBGLOG(SCN, INFO, "Channel : %s\n", g_aucScanChannelNum); |
| DBGLOG(SCN, INFO, "IdleTime : %s\n", g_aucScanChannelIdleTime); |
| DBGLOG(SCN, INFO, "MdrdyCnt : %s\n", g_aucScanChannelMDRDY); |
| DBGLOG(SCN, INFO, |
| "==================================================================================\n"); |
| kalMemZero(g_aucScanChannelNum, SCN_SCAN_DONE_PRINT_BUFFER_LENGTH); |
| kalMemZero(g_aucScanChannelIdleTime, SCN_SCAN_DONE_PRINT_BUFFER_LENGTH); |
| kalMemZero(g_aucScanChannelMDRDY, SCN_SCAN_DONE_PRINT_BUFFER_LENGTH); |
| u4PrintfIdx = 0; |
| } |
| kalSprintf(g_aucScanChannelNum + u4PrintfIdx*7, "%7d", |
| prScanInfo->aucChannelNum[u4ChCnt]); |
| kalSprintf(g_aucScanChannelIdleTime + u4PrintfIdx*7, "%7d", |
| prScanInfo->au2ChannelIdleTime[u4ChCnt]); |
| kalSprintf(g_aucScanChannelMDRDY + u4PrintfIdx*7, "%7d", |
| prScanInfo->aucChannelMDRDYCnt[u4ChCnt]); |
| u4PrintfIdx++; |
| } |
| |
| DBGLOG(SCN, INFO, "Channel : %s\n", g_aucScanChannelNum); |
| DBGLOG(SCN, INFO, "IdleTime : %s\n", g_aucScanChannelIdleTime); |
| DBGLOG(SCN, INFO, "MdrdyCnt : %s\n", g_aucScanChannelMDRDY); |
| } else { |
| prScanInfo->fgIsSparseChannelValid = FALSE; |
| } |
| } |
| |
| if (prScanInfo->eCurrentState == SCAN_STATE_SCANNING && prScanDone->ucSeqNum == prScanParam->ucSeqNum) { |
| /* generate scan-done event for caller */ |
| scnFsmGenerateScanDoneMsg(prAdapter, prScanParam->ucSeqNum, prScanParam->ucBssIndex, SCAN_STATUS_DONE); |
| |
| /* switch to next pending scan */ |
| scnFsmSteps(prAdapter, SCAN_STATE_IDLE); |
| } else { |
| DBGLOG(SCN, INFO, "Unexpected SCAN-DONE event: SeqNum = %d, Current State = %d\n", |
| prScanDone->ucSeqNum, prScanInfo->eCurrentState); |
| } |
| } /* end of scnEventScanDone */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID |
| scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter, |
| IN UINT_8 ucSeqNum, IN UINT_8 ucBssIndex, IN ENUM_SCAN_STATUS eScanStatus) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_SCAN_PARAM_T prScanParam; |
| P_MSG_SCN_SCAN_DONE prScanDoneMsg; |
| |
| ASSERT(prAdapter); |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prScanParam = &prScanInfo->rScanParam; |
| |
| prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_DONE)); |
| if (!prScanDoneMsg) { |
| ASSERT(0); /* Can't indicate SCAN FSM Complete */ |
| return; |
| } |
| |
| if (prScanParam->fgIsObssScan == TRUE) { |
| prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_RLM_SCAN_DONE; |
| } else { |
| switch (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType) { |
| case NETWORK_TYPE_AIS: |
| prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_AIS_SCAN_DONE; |
| break; |
| |
| case NETWORK_TYPE_P2P: |
| prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_P2P_SCAN_DONE; |
| break; |
| |
| case NETWORK_TYPE_BOW: |
| prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_BOW_SCAN_DONE; |
| break; |
| |
| default: |
| DBGLOG(SCN, LOUD, |
| "Unexpected Network Type: %d\n", |
| GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType); |
| ASSERT(0); |
| break; |
| } |
| } |
| |
| prScanDoneMsg->ucSeqNum = ucSeqNum; |
| prScanDoneMsg->ucBssIndex = ucBssIndex; |
| prScanDoneMsg->eScanStatus = eScanStatus; |
| |
| mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanDoneMsg, MSG_SEND_METHOD_BUF); |
| |
| } /* end of scnFsmGenerateScanDoneMsg() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Query for most sparse channel |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| |
| ASSERT(prAdapter); |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| |
| if (prScanInfo->fgIsSparseChannelValid == TRUE) { |
| if (prSparseBand) |
| *prSparseBand = prScanInfo->rSparseChannel.eBand; |
| |
| if (pucSparseChannel) |
| *pucSparseChannel = prScanInfo->rSparseChannel.ucChannelNum; |
| |
| return TRUE; |
| } else { |
| return FALSE; |
| } |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Event handler for NLO done event |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_NLO_PARAM_T prNloParam; |
| P_SCAN_PARAM_T prScanParam; |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prNloParam = &prScanInfo->rNloParam; |
| prScanParam = &prNloParam->rScanParam; |
| |
| if (prScanInfo->fgNloScanning == TRUE && prNloDone->ucSeqNum == prScanParam->ucSeqNum) { |
| |
| DBGLOG(SCN, INFO, "scnEventNloDone reporting to uplayer\n"); |
| |
| kalSchedScanResults(prAdapter->prGlueInfo); |
| |
| if (prNloParam->fgStopAfterIndication == TRUE) |
| prScanInfo->fgNloScanning = FALSE; |
| } else { |
| DBGLOG(SCN, INFO, "Unexpected NLO-DONE event: SeqNum = %d, Current State = %d\n", |
| prNloDone->ucSeqNum, prScanInfo->eCurrentState); |
| } |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief OID handler for starting scheduled scan |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| BOOLEAN |
| scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter, |
| IN UINT_8 ucSsidNum, |
| IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_NLO_PARAM_T prNloParam; |
| P_SCAN_PARAM_T prScanParam; |
| P_CMD_NLO_REQ prCmdNloReq; |
| UINT_32 i, j; |
| |
| ASSERT(prAdapter); |
| |
| DBGLOG(SCN, INFO, "scnFsmSchedScanRequest\n"); |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prNloParam = &prScanInfo->rNloParam; |
| prScanParam = &prNloParam->rScanParam; |
| |
| /* ASSERT(prScanInfo->fgNloScanning == FALSE); */ |
| if (prScanInfo->fgNloScanning) { |
| DBGLOG(SCN, INFO, "prScanInfo->fgNloScanning == FALSE already scanning\n"); |
| return TRUE; |
| } |
| |
| prScanInfo->fgNloScanning = TRUE; |
| |
| /* 1. load parameters */ |
| prScanParam->ucSeqNum++; |
| prScanParam->ucBssIndex = prAdapter->prAisBssInfo->ucBssIndex; |
| prNloParam->fgStopAfterIndication = FALSE; |
| prNloParam->ucFastScanIteration = 0; |
| |
| if (u2Interval < SCAN_NLO_DEFAULT_INTERVAL) { |
| u2Interval = SCAN_NLO_DEFAULT_INTERVAL; |
| DBGLOG(SCN, INFO, "force interval to SCAN_NLO_DEFAULT_INTERVAL\n"); |
| } |
| prAdapter->prAisBssInfo->fgIsPNOEnable = TRUE; |
| |
| if (!IS_NET_ACTIVE(prAdapter, prAdapter->prAisBssInfo->ucBssIndex)) { |
| SET_NET_ACTIVE(prAdapter, prAdapter->prAisBssInfo->ucBssIndex); |
| |
| DBGLOG(SCN, INFO, "ACTIVE AIS from INACTIVE to enable PNO\n"); |
| /* sync with firmware */ |
| nicActivateNetwork(prAdapter, prAdapter->prAisBssInfo->ucBssIndex); |
| } |
| prNloParam->u2FastScanPeriod = u2Interval; |
| prNloParam->u2SlowScanPeriod = u2Interval; |
| |
| if (ucSsidNum > CFG_SCAN_SSID_MAX_NUM) |
| prScanParam->ucSSIDNum = CFG_SCAN_SSID_MAX_NUM; |
| else |
| prScanParam->ucSSIDNum = ucSsidNum; |
| |
| if (ucSsidNum > CFG_SCAN_SSID_MATCH_MAX_NUM) |
| prNloParam->ucMatchSSIDNum = CFG_SCAN_SSID_MATCH_MAX_NUM; |
| else |
| prNloParam->ucMatchSSIDNum = ucSsidNum; |
| |
| for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { |
| if (i < CFG_SCAN_SSID_MAX_NUM) { |
| COPY_SSID(prScanParam->aucSpecifiedSSID[i], |
| prScanParam->ucSpecifiedSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); |
| } |
| |
| COPY_SSID(prNloParam->aucMatchSSID[i], |
| prNloParam->ucMatchSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); |
| |
| /* for linux the Ciper,Auth Algo will be zero */ |
| prNloParam->aucCipherAlgo[i] = 0; |
| prNloParam->au2AuthAlgo[i] = 0; |
| |
| for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) |
| prNloParam->aucChannelHint[i][j] = 0; |
| } |
| |
| /* 2. prepare command for sending */ |
| prCmdNloReq = (P_CMD_NLO_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_NLO_REQ) + u4IeLength); |
| |
| if (!prCmdNloReq) { |
| ASSERT(0); /* Can't initiate NLO operation */ |
| return FALSE; |
| } |
| |
| /* 3. send command packet for NLO operation */ |
| kalMemZero(prCmdNloReq, sizeof(CMD_NLO_REQ)); |
| |
| prCmdNloReq->ucSeqNum = prScanParam->ucSeqNum; |
| prCmdNloReq->ucBssIndex = prScanParam->ucBssIndex; |
| prCmdNloReq->fgStopAfterIndication = prNloParam->fgStopAfterIndication; |
| prCmdNloReq->ucFastScanIteration = prNloParam->ucFastScanIteration; |
| prCmdNloReq->u2FastScanPeriod = prNloParam->u2FastScanPeriod; |
| prCmdNloReq->u2SlowScanPeriod = prNloParam->u2SlowScanPeriod; |
| prCmdNloReq->ucEntryNum = prNloParam->ucMatchSSIDNum; |
| |
| #ifdef LINUX |
| prCmdNloReq->ucFlag = SCAN_NLO_CHECK_SSID_ONLY; |
| DBGLOG(SCN, INFO, "LINUX only check SSID for PNO SCAN\n"); |
| #endif |
| for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { |
| COPY_SSID(prCmdNloReq->arNetworkList[i].aucSSID, |
| prCmdNloReq->arNetworkList[i].ucSSIDLength, |
| prNloParam->aucMatchSSID[i], prNloParam->ucMatchSSIDLen[i]); |
| |
| prCmdNloReq->arNetworkList[i].ucCipherAlgo = prNloParam->aucCipherAlgo[i]; |
| prCmdNloReq->arNetworkList[i].u2AuthAlgo = prNloParam->au2AuthAlgo[i]; |
| DBGLOG(SCN, INFO, "prCmdNloReq->arNetworkList[i].aucSSID %s\n", prCmdNloReq->arNetworkList[i].aucSSID); |
| DBGLOG(SCN, INFO, |
| "prCmdNloReq->arNetworkList[i].ucSSIDLength %d\n", prCmdNloReq->arNetworkList[i].ucSSIDLength); |
| DBGLOG(SCN, INFO, |
| "prCmdNloReq->arNetworkList[i].ucCipherAlgo %d\n", prCmdNloReq->arNetworkList[i].ucCipherAlgo); |
| DBGLOG(SCN, INFO, |
| "prCmdNloReq->arNetworkList[i].u2AuthAlgo %d\n", prCmdNloReq->arNetworkList[i].u2AuthAlgo); |
| |
| for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) |
| prCmdNloReq->arNetworkList[i].ucNumChannelHint[j] = prNloParam->aucChannelHint[i][j]; |
| } |
| |
| if (u4IeLength <= MAX_IE_LENGTH) |
| prCmdNloReq->u2IELen = prScanParam->u2IELen; |
| else |
| prCmdNloReq->u2IELen = MAX_IE_LENGTH; |
| |
| if (u4IeLength) { |
| kalMemCopy(prScanParam->aucIE, pucIe, prCmdNloReq->u2IELen); |
| kalMemCopy(prCmdNloReq->aucIE, pucIe, prCmdNloReq->u2IELen); |
| } |
| |
| wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_NLO_REQ, |
| TRUE, |
| FALSE, |
| TRUE, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(CMD_NLO_REQ) + prCmdNloReq->u2IELen, (PUINT_8) prCmdNloReq, NULL, 0); |
| |
| cnmMemFree(prAdapter, (PVOID) prCmdNloReq); |
| |
| return TRUE; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief OID handler for stopping scheduled scan |
| * |
| * \param[in] |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter) |
| { |
| P_SCAN_INFO_T prScanInfo; |
| P_NLO_PARAM_T prNloParam; |
| P_SCAN_PARAM_T prScanParam; |
| CMD_NLO_CANCEL rCmdNloCancel; |
| WLAN_STATUS rStatus; |
| |
| ASSERT(prAdapter); |
| DBGLOG(SCN, INFO, "scnFsmSchedScanStopRequest\n"); |
| |
| prScanInfo = &(prAdapter->rWifiVar.rScanInfo); |
| prNloParam = &prScanInfo->rNloParam; |
| prScanParam = &prNloParam->rScanParam; |
| |
| if (prAdapter->prAisBssInfo->fgIsNetRequestInActive && prAdapter->prAisBssInfo->fgIsPNOEnable) { |
| UNSET_NET_ACTIVE(prAdapter, prAdapter->prAisBssInfo->ucBssIndex); |
| |
| DBGLOG(SCN, INFO, "INACTIVE AIS from ACTIVE to DISABLE PNO\n"); |
| /* sync with firmware */ |
| nicDeactivateNetwork(prAdapter, prAdapter->prAisBssInfo->ucBssIndex); |
| } else { |
| DBGLOG(SCN, INFO, |
| "fgIsNetRequestInActive %d, fgIsPNOEnable %d\n", |
| prAdapter->prAisBssInfo->fgIsNetRequestInActive, prAdapter->prAisBssInfo->fgIsPNOEnable); |
| } |
| |
| prAdapter->prAisBssInfo->fgIsPNOEnable = FALSE; |
| |
| /* send cancel message to firmware domain */ |
| rCmdNloCancel.ucSeqNum = prScanParam->ucSeqNum; |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_NLO_CANCEL, TRUE, FALSE, TRUE, nicCmdEventSetStopSchedScan, |
| /* nicCmdEventSetCommon, */ |
| nicOidCmdTimeoutCommon, |
| sizeof(CMD_NLO_CANCEL), (PUINT_8) &rCmdNloCancel, NULL, 0); |
| |
| prScanInfo->fgNloScanning = FALSE; |
| if (rStatus != WLAN_STATUS_FAILURE) |
| return TRUE; |
| else |
| return FALSE; |
| } |