| /* |
| * Copyright (c) 2011-2014, 2016-2018 The Linux Foundation. All rights reserved. |
| * |
| * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| * |
| * |
| * Permission to use, copy, modify, and/or distribute this software for |
| * any purpose with or without fee is hereby granted, provided that the |
| * above copyright notice and this permission notice appear in all |
| * copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| * PERFORMANCE OF THIS SOFTWARE. |
| */ |
| |
| /* |
| * This file was originally distributed by Qualcomm Atheros, Inc. |
| * under proprietary terms before Copyright ownership was assigned |
| * to the Linux Foundation. |
| */ |
| |
| /* |
| * This file limScanResultUtils.cc contains the utility functions |
| * LIM uses for maintaining and accessing scan results on STA. |
| * Author: Chandra Modumudi |
| * Date: 02/13/02 |
| * History:- |
| * Date Modified by Modification Information |
| * -------------------------------------------------------------------- |
| */ |
| |
| #include "limTypes.h" |
| #include "limUtils.h" |
| #include "limSerDesUtils.h" |
| #include "limApi.h" |
| #include "limSession.h" |
| #if defined WLAN_FEATURE_VOWIFI |
| #include "rrmApi.h" |
| #endif |
| #include "vos_utils.h" |
| |
| /** |
| * limDeactiveMinChannelTimerDuringScan() |
| * |
| *FUNCTION: |
| * This function is called during scan upon receiving |
| * Beacon/Probe Response frame to deactivate MIN channel |
| * timer if running. |
| * |
| * This function should be called only when pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * |
| * @return eSIR_SUCCESS in case of success |
| */ |
| |
| tANI_U32 |
| limDeactivateMinChannelTimerDuringScan(tpAniSirGlobal pMac) |
| { |
| if ((VOS_TRUE == |
| tx_timer_running(&pMac->lim.limTimers.gLimMinChannelTimer)) && |
| (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) && |
| (pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE)) |
| { |
| /** |
| * Beacon/Probe Response is received during active scanning. |
| * Deactivate MIN channel timer if running. |
| */ |
| limDeactivateAndChangeTimer(pMac,eLIM_MIN_CHANNEL_TIMER); |
| |
| } |
| return eSIR_SUCCESS; |
| } /*** end limDeactivateMinChannelTimerDuringScan() ***/ |
| |
| |
| |
| /** |
| * limCollectBssDescription() |
| * |
| *FUNCTION: |
| * This function is called during scan upon receiving |
| * Beacon/Probe Response frame to check if the received |
| * frame matches scan criteria, collect BSS description |
| * and add it to cached scan results. |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param pBPR - Pointer to parsed Beacon/Probe Response structure |
| * @param pRxPacketInfo - Pointer to Received frame's BD |
| * ---------if defined WLAN_FEATURE_VOWIFI------ |
| * @param fScanning - flag to indicate if it is during scan. |
| * --------------------------------------------- |
| * |
| * @return None |
| */ |
| #if defined WLAN_FEATURE_VOWIFI |
| void |
| limCollectBssDescription(tpAniSirGlobal pMac, |
| tSirBssDescription *pBssDescr, |
| tpSirProbeRespBeacon pBPR, |
| tANI_U8 *pRxPacketInfo, |
| tANI_U8 fScanning) |
| #else |
| void |
| limCollectBssDescription(tpAniSirGlobal pMac, |
| tSirBssDescription *pBssDescr, |
| tpSirProbeRespBeacon pBPR, |
| tANI_U8 *pRxPacketInfo) |
| #endif |
| { |
| tANI_U8 *pBody; |
| tANI_U32 ieLen = 0; |
| tpSirMacMgmtHdr pHdr; |
| tANI_U8 channelNum; |
| tANI_U8 rxChannel; |
| tANI_U8 rfBand = 0; |
| |
| pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); |
| VOS_ASSERT(WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) >= SIR_MAC_B_PR_SSID_OFFSET); |
| ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET; |
| rxChannel = WDA_GET_RX_CH(pRxPacketInfo); |
| pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); |
| rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo); |
| |
| |
| /** |
| * Length of BSS desription is without length of |
| * length itself and length of pointer |
| * that holds ieFields |
| */ |
| pBssDescr->length = (tANI_U16)( |
| ((uintptr_t)OFFSET_OF(tSirBssDescription, ieFields)) - |
| sizeof(pBssDescr->length) + ieLen); |
| |
| // Copy BSS Id |
| vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, |
| (tANI_U8 *) pHdr->bssId, |
| sizeof(tSirMacAddr)); |
| |
| // Copy Timestamp, Beacon Interval and Capability Info |
| pBssDescr->scanSysTimeMsec = vos_timer_get_system_time(); |
| |
| pBssDescr->timeStamp[0] = pBPR->timeStamp[0]; |
| pBssDescr->timeStamp[1] = pBPR->timeStamp[1]; |
| pBssDescr->beaconInterval = pBPR->beaconInterval; |
| pBssDescr->capabilityInfo = limGetU16((tANI_U8 *) &pBPR->capabilityInfo); |
| |
| pBssDescr->HTCapsPresent = 0; |
| pBssDescr->chanWidth = eHT_CHANNEL_WIDTH_20MHZ; |
| pBssDescr->wmeInfoPresent = 0; |
| pBssDescr->vhtCapsPresent = 0; |
| pBssDescr->beacomformingCapable = 0; |
| /* HT capability */ |
| if (pBPR->HTCaps.present) { |
| pBssDescr->HTCapsPresent = 1; |
| if (pBPR->HTCaps.supportedChannelWidthSet) |
| pBssDescr->chanWidth = eHT_CHANNEL_WIDTH_40MHZ; |
| } |
| if (pBPR->wmeEdcaPresent) |
| pBssDescr->wmeInfoPresent = 1; |
| |
| #ifdef WLAN_FEATURE_11AC |
| /* VHT Parameters */ |
| if (pBPR->VHTCaps.present) { |
| pBssDescr->vhtCapsPresent = 1; |
| if (pBPR->VHTCaps.muBeamformerCap) |
| pBssDescr->beacomformingCapable = 1; |
| } |
| if (pBPR->VHTOperation.present) |
| if (pBPR->VHTOperation.chanWidth == 1) |
| pBssDescr->chanWidth = eHT_CHANNEL_WIDTH_80MHZ; |
| #endif |
| if(!pBssDescr->beaconInterval ) |
| { |
| limLog(pMac, LOGW, |
| FL("Beacon Interval is ZERO, making it to default 100 " |
| MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->bssId)); |
| pBssDescr->beaconInterval= 100; |
| } |
| /* |
| * There is a narrow window after Channel Switch msg is sent to HAL and before the AGC is shut |
| * down and beacons/Probe Rsps can trickle in and we may report the incorrect channel in 5Ghz |
| * band, so not relying on the 'last Scanned Channel' stored in LIM. |
| * Instead use the value returned by RXP in BD. This the the same value which HAL programs into |
| * RXP before every channel switch. |
| * Right now there is a problem in 5Ghz, where we are receiving beacons from a channel different from |
| * the currently scanned channel. so incorrect channel is reported to CSR and association does not happen. |
| * So for now we keep on looking for the channel info in the beacon (DSParamSet IE OR HT Info IE), and only if it |
| * is not present in the beacon, we go for the channel info present in RXP. |
| * This fix will work for 5Ghz 11n devices, but for 11a devices, we have to rely on RXP routing flag to get the correct channel. |
| * So The problem of incorrect channel reporting in 5Ghz will still remain for 11a devices. |
| */ |
| pBssDescr->channelId = limGetChannelFromBeacon(pMac, pBPR); |
| |
| if (pBssDescr->channelId == 0) |
| { |
| /* If the channel Id is not retrieved from Beacon, extract the channel from BD */ |
| /* Unmapped the channel.This We have to do since we have done mapping in the hal to |
| overcome the limitation of RXBD of not able to accomodate the bigger channel number.*/ |
| if ((!rfBand) || IS_5G_BAND(rfBand)) |
| { |
| rxChannel = limUnmapChannel(rxChannel); |
| } |
| if (!rxChannel) |
| { |
| rxChannel = pMac->lim.gLimCurrentScanChannelId; |
| } |
| pBssDescr->channelId = rxChannel; |
| } |
| |
| pBssDescr->channelIdSelf = pBssDescr->channelId; |
| //set the network type in bss description |
| channelNum = pBssDescr->channelId; |
| pBssDescr->nwType = limGetNwType(pMac, channelNum, SIR_MAC_MGMT_FRAME, pBPR); |
| |
| pBssDescr->aniIndicator = pBPR->propIEinfo.aniIndicator; |
| |
| // Copy RSSI & SINR from BD |
| |
| PELOG4(limLog(pMac, LOG4, "***********BSS Description for BSSID:*********** "); |
| sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pBssDescr->bssId, 6 ); |
| sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG4, (tANI_U8*)pRxPacketInfo, 36 );) |
| |
| pBssDescr->rssi = (tANI_S8)WDA_GET_RX_RSSI_DB(pRxPacketInfo); |
| |
| //SINR no longer reported by HW |
| pBssDescr->sinr = 0; |
| |
| pBssDescr->nReceivedTime = vos_timer_get_system_time(); |
| |
| #if defined WLAN_FEATURE_VOWIFI |
| if( fScanning ) |
| { |
| rrmGetStartTSF( pMac, pBssDescr->startTSF ); |
| pBssDescr->parentTSF = WDA_GET_RX_TIMESTAMP(pRxPacketInfo); |
| } |
| #endif |
| |
| #ifdef WLAN_FEATURE_VOWIFI_11R |
| // MobilityDomain |
| pBssDescr->mdie[0] = 0; |
| pBssDescr->mdie[1] = 0; |
| pBssDescr->mdie[2] = 0; |
| pBssDescr->mdiePresent = FALSE; |
| // If mdie is present in the probe resp we |
| // fill it in the bss description |
| if( pBPR->mdiePresent) |
| { |
| pBssDescr->mdiePresent = TRUE; |
| pBssDescr->mdie[0] = pBPR->mdie[0]; |
| pBssDescr->mdie[1] = pBPR->mdie[1]; |
| pBssDescr->mdie[2] = pBPR->mdie[2]; |
| } |
| #endif |
| |
| #if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) |
| pBssDescr->QBSSLoad_present = FALSE; |
| pBssDescr->QBSSLoad_avail = 0; |
| if( pBPR->QBSSLoad.present) |
| { |
| pBssDescr->QBSSLoad_present = TRUE; |
| pBssDescr->QBSSLoad_avail = pBPR->QBSSLoad.avail; |
| pBssDescr->QBSS_ChanLoad = pBPR->QBSSLoad.chautil; |
| } |
| #endif |
| // Copy IE fields |
| vos_mem_copy((tANI_U8 *) &pBssDescr->ieFields, |
| pBody + SIR_MAC_B_PR_SSID_OFFSET, |
| ieLen); |
| |
| //sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOGW, (tANI_U8 *) pBssDescr, pBssDescr->length + 2 ); |
| limLog( pMac, LOG3, |
| FL("Collected BSS Description for Channel(%1d), length(%u), aniIndicator(%d), IE Fields(%u)"), |
| pBssDescr->channelId, |
| pBssDescr->length, |
| pBssDescr->aniIndicator, |
| ieLen ); |
| |
| return; |
| } /*** end limCollectBssDescription() ***/ |
| |
| /** |
| * limIsScanRequestedSSID() |
| * |
| *FUNCTION: |
| * This function is called during scan upon receiving |
| * Beacon/Probe Response frame to check if the received |
| * SSID is present in the list of requested SSIDs in scan |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param ssId - SSID Received in beacons/Probe responses that is compared against the |
| requeusted SSID in scan list |
| * --------------------------------------------- |
| * |
| * @return boolean - TRUE if SSID is present in requested list, FALSE otherwise |
| */ |
| |
| tANI_BOOLEAN limIsScanRequestedSSID(tpAniSirGlobal pMac, tSirMacSSid *ssId) |
| { |
| tANI_U8 i = 0; |
| |
| for (i = 0; i < pMac->lim.gpLimMlmScanReq->numSsid; i++) |
| { |
| if ( eANI_BOOLEAN_TRUE == vos_mem_compare((tANI_U8 *) ssId, |
| (tANI_U8 *) &pMac->lim.gpLimMlmScanReq->ssId[i], |
| (tANI_U8) (pMac->lim.gpLimMlmScanReq->ssId[i].length + 1))) |
| { |
| return eANI_BOOLEAN_TRUE; |
| } |
| } |
| return eANI_BOOLEAN_FALSE; |
| } |
| |
| /** |
| * limCheckAndAddBssDescription() |
| * |
| *FUNCTION: |
| * This function is called during scan upon receiving |
| * Beacon/Probe Response frame to check if the received |
| * frame matches scan criteria, collect BSS description |
| * and add it to cached scan results. |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param pBPR - Pointer to parsed Beacon/Probe Response structure |
| * @param pRxPacketInfo - Pointer to Received frame's BD |
| * @param fScanning - boolean to indicate whether the BSS is from current scan or just happen to receive a beacon |
| * |
| * @return None |
| */ |
| |
| void |
| limCheckAndAddBssDescription(tpAniSirGlobal pMac, |
| tpSirProbeRespBeacon pBPR, |
| tANI_U8 *pRxPacketInfo, |
| tANI_BOOLEAN fScanning, |
| tANI_U8 fProbeRsp) |
| { |
| tLimScanResultNode *pBssDescr; |
| tANI_U32 frameLen, ieLen = 0; |
| tANI_U8 rxChannelInBeacon = 0; |
| eHalStatus status; |
| tANI_U8 dontUpdateAll = 0; |
| tANI_U8 rfBand = 0; |
| tANI_U8 rxChannelInBD = 0; |
| bool chan_info_present = true; |
| |
| tSirMacAddr bssid = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
| tSirMacAddr bssid_zero = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; |
| tANI_BOOLEAN fFound = FALSE; |
| tpSirMacDataHdr3a pHdr; |
| |
| pHdr = WDA_GET_RX_MPDUHEADER3A((tANI_U8 *)pRxPacketInfo); |
| |
| // Check For Null BSSID; Skip in case of P2P. |
| if (vos_mem_compare(bssid_zero, &pHdr->addr3, 6)) |
| { |
| return ; |
| } |
| |
| //Checking if scanning for a particular BSSID |
| if ((fScanning) && (pMac->lim.gpLimMlmScanReq)) |
| { |
| fFound = vos_mem_compare(pHdr->addr3, &pMac->lim.gpLimMlmScanReq->bssId, 6); |
| if (!fFound) |
| { |
| if ((pMac->lim.gpLimMlmScanReq->p2pSearch) && |
| (vos_mem_compare(pBPR->P2PProbeRes.P2PDeviceInfo.P2PDeviceAddress, |
| &pMac->lim.gpLimMlmScanReq->bssId, 6))) |
| { |
| fFound = eANI_BOOLEAN_TRUE; |
| } |
| } |
| } |
| |
| /** |
| * Compare SSID with the one sent in |
| * Probe Request frame, if any. |
| * If they don't match, ignore the |
| * Beacon frame. |
| * pMac->lim.gLimMlmScanReq->ssId.length == 0 |
| * indicates Broadcast SSID. |
| * When gLimReturnAfterFirstMatch is set, it means the scan has to match |
| * a SSID (if it is also set). Ignore the other BSS in that case. |
| */ |
| |
| #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| if (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))) |
| { |
| #endif |
| if ((pMac->lim.gpLimMlmScanReq) && |
| (((fScanning) && |
| ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 ) && |
| (pMac->lim.gpLimMlmScanReq->numSsid) && |
| !limIsScanRequestedSSID(pMac, &pBPR->ssId)) || |
| (!fFound && (pMac->lim.gpLimMlmScanReq && |
| pMac->lim.gpLimMlmScanReq->bssId) && |
| !vos_mem_compare(bssid, |
| &pMac->lim.gpLimMlmScanReq->bssId, 6)))) |
| { |
| /** |
| * Received SSID does not match with |
| * the one we're scanning for. |
| * Ignore received Beacon frame |
| */ |
| |
| return; |
| } |
| #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| } |
| #endif |
| |
| /* There is no point in caching & reporting the scan results for APs |
| * which are in the process of switching the channel. So, we are not |
| * caching the scan results for APs which are adverzing the channel-switch |
| * element in their beacons and probe responses. |
| */ |
| if(pBPR->channelSwitchPresent) |
| { |
| if (pBPR->ext_chan_switch_ann.new_channel != |
| limGetChannelFromBeacon(pMac, pBPR)) |
| return; |
| } |
| |
| if(pBPR->ecsa_present) { |
| limLog(pMac, LOGW, FL("ECSA IE present")); |
| /* Still add to scan result if ECSA IE present and new channel |
| * equal to current channel. |
| */ |
| if (pBPR->channelNumber!= HAL_INVALID_CHANNEL_ID && |
| pBPR->ext_chan_switch_ann.new_channel != HAL_INVALID_CHANNEL_ID && |
| pBPR->channelNumber != pBPR->ext_chan_switch_ann.new_channel) { |
| limLog(pMac, LOGW, FL("ignore this AP")); |
| return; |
| } |
| |
| } |
| |
| /* If beacon/probe resp DS param channel does not match with |
| * RX BD channel then don't save the results. It might be a beacon |
| * from another channel heard as noise on the current scanning channel |
| */ |
| |
| if ((pBPR->dsParamsPresent) || (pBPR->HTInfo.present)) |
| { |
| /* This means that we are in 2.4GHz mode or 5GHz 11n mode */ |
| rxChannelInBeacon = limGetChannelFromBeacon(pMac, pBPR); |
| rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo); |
| rxChannelInBD = WDA_GET_RX_CH(pRxPacketInfo); |
| |
| if ((!rfBand) || IS_5G_BAND(rfBand)) |
| { |
| rxChannelInBD = limUnmapChannel(rxChannelInBD); |
| } |
| |
| if(rxChannelInBD != rxChannelInBeacon) |
| { |
| /* BCAST Frame, if CH do not match, Drop */ |
| if(WDA_IS_RX_BCAST(pRxPacketInfo)) |
| { |
| limLog(pMac, LOG3, FL("Beacon/Probe Rsp dropped. Channel in BD %d. " |
| "Channel in beacon" " %d"), |
| WDA_GET_RX_CH(pRxPacketInfo),limGetChannelFromBeacon(pMac, pBPR)); |
| return; |
| } |
| /* Unit cast frame, Probe RSP, do not drop */ |
| else |
| { |
| dontUpdateAll = 1; |
| limLog(pMac, LOG3, FL("SSID %s, CH in ProbeRsp %d, CH in BD %d, miss-match, Do Not Drop"), |
| pBPR->ssId.ssId, |
| rxChannelInBeacon, |
| WDA_GET_RX_CH(pRxPacketInfo)); |
| WDA_GET_RX_CH(pRxPacketInfo) = rxChannelInBeacon; |
| } |
| } |
| } |
| else |
| { |
| chan_info_present = false; |
| } |
| |
| /** |
| * Allocate buffer to hold BSS description from |
| * received Beacon frame. |
| * Include size of fixed fields and IEs length |
| */ |
| |
| ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); |
| if (ieLen <= (SIR_MAC_B_PR_SSID_OFFSET + 2)) |
| { |
| limLog(pMac, LOGP, |
| FL("RX packet has invalid length %d"), ieLen); |
| return; |
| } |
| |
| ieLen -= SIR_MAC_B_PR_SSID_OFFSET; |
| |
| frameLen = sizeof(tLimScanResultNode) + ieLen - sizeof(tANI_U32); //Sizeof(tANI_U32) is for ieFields[1] |
| |
| pBssDescr = vos_mem_malloc(frameLen); |
| if ( NULL == pBssDescr ) |
| { |
| // Log error |
| limLog(pMac, LOGP, |
| FL("call for AllocateMemory failed for storing BSS description")); |
| |
| return; |
| } |
| |
| vos_mem_zero(pBssDescr, frameLen); |
| |
| // In scan state, store scan result. |
| #if defined WLAN_FEATURE_VOWIFI |
| limCollectBssDescription(pMac, &pBssDescr->bssDescription, |
| pBPR, pRxPacketInfo, fScanning); |
| #else |
| limCollectBssDescription(pMac, &pBssDescr->bssDescription, |
| pBPR, pRxPacketInfo); |
| #endif |
| pBssDescr->bssDescription.fProbeRsp = fProbeRsp; |
| |
| pBssDescr->next = NULL; |
| |
| /** |
| * Depending on whether to store unique or all |
| * scan results, pass hash update/add parameter |
| * For LFR candidates just add them on it's own cache |
| */ |
| |
| #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)) |
| { |
| limLog(pMac, LOG1, FL(" pHdr->addr1:"MAC_ADDRESS_STR), |
| MAC_ADDR_ARRAY(pHdr->addr1)); |
| limLog(pMac, LOG1, FL(" pHdr->addr2:"MAC_ADDRESS_STR), |
| MAC_ADDR_ARRAY(pHdr->addr2)); |
| limLog(pMac, LOG1, FL(" pHdr->addr3:"MAC_ADDRESS_STR), |
| MAC_ADDR_ARRAY(pHdr->addr3)); |
| limLog( pMac, LOG1, FL("Save this entry in LFR cache")); |
| status = limLookupNaddLfrHashEntry(pMac, pBssDescr, LIM_HASH_ADD, |
| dontUpdateAll, ieLen - 2); |
| } |
| else |
| #endif |
| //If it is not scanning, only save unique results |
| if (pMac->lim.gLimReturnUniqueResults || (!fScanning)) |
| { |
| status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE, |
| dontUpdateAll, ieLen - 2, |
| chan_info_present); |
| } |
| else |
| { |
| status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD, |
| dontUpdateAll, ieLen - 2, |
| chan_info_present); |
| } |
| |
| if(fScanning) |
| { |
| if ((pBssDescr->bssDescription.channelId <= 14) && |
| (pMac->lim.gLimReturnAfterFirstMatch & 0x40) && |
| pBPR->countryInfoPresent) |
| pMac->lim.gLim24Band11dScanDone = 1; |
| |
| if ((pBssDescr->bssDescription.channelId > 14) && |
| (pMac->lim.gLimReturnAfterFirstMatch & 0x80) && |
| pBPR->countryInfoPresent) |
| pMac->lim.gLim50Band11dScanDone = 1; |
| |
| if ( ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 ) || |
| ( pMac->lim.gLim24Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x40 ) ) || |
| ( pMac->lim.gLim50Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x80 ) ) || |
| fFound ) |
| { |
| /** |
| * Stop scanning and return the BSS description(s) |
| * collected so far. |
| */ |
| limLog(pMac, |
| LOGW, |
| FL("Completed scan: 24Band11dScan = %d, 50Band11dScan = %d BSS id"), |
| pMac->lim.gLim24Band11dScanDone, |
| pMac->lim.gLim50Band11dScanDone); |
| |
| //Need to disable the timers. If they fire, they will send END_SCAN |
| //while we already send FINISH_SCAN here. This may mess up the gLimHalScanState |
| limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); |
| limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); |
| //Set the resume channel to Any valid channel (invalid). |
| //This will instruct HAL to set it to any previous valid channel. |
| peSetResumeChannel(pMac, 0, 0); |
| limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE ); |
| //limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE ); |
| } |
| }//(eANI_BOOLEAN_TRUE == fScanning) |
| |
| if( eHAL_STATUS_SUCCESS != status ) |
| { |
| vos_mem_free( pBssDescr ); |
| } |
| } /****** end limCheckAndAddBssDescription() ******/ |
| |
| |
| |
| /** |
| * limScanHashFunction() |
| * |
| *FUNCTION: |
| * This function is called during scan hash entry operations |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param bssId - Received BSSid |
| * |
| * @return Hash index |
| */ |
| |
| tANI_U8 |
| limScanHashFunction(tSirMacAddr bssId) |
| { |
| tANI_U16 i, hash = 0; |
| |
| for (i = 0; i < sizeof(tSirMacAddr); i++) |
| hash += bssId[i]; |
| |
| return hash % LIM_MAX_NUM_OF_SCAN_RESULTS; |
| } /****** end limScanHashFunction() ******/ |
| |
| |
| |
| /** |
| * limInitHashTable() |
| * |
| *FUNCTION: |
| * This function is called upon receiving SME_START_REQ |
| * to initialize global cached scan hash table |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limInitHashTable(tpAniSirGlobal pMac) |
| { |
| tANI_U16 i; |
| for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) |
| pMac->lim.gLimCachedScanHashTable[i] = NULL; |
| } /****** end limInitHashTable() ******/ |
| |
| eHalStatus |
| limLookupNaddHashEntry(tpAniSirGlobal pMac, |
| tLimScanResultNode *pBssDescr, tANI_U8 action, |
| tANI_U8 dontUpdateAll, tANI_U32 ie_len, |
| bool chan_info_present) |
| { |
| tANI_U8 index, ssidLen = 0; |
| tANI_U8 found = false; |
| tLimScanResultNode *ptemp, *pprev; |
| tSirMacCapabilityInfo *pSirCap, *pSirCapTemp; |
| int len, elem_id, elem_len; |
| tANI_U8 *pbIe; |
| tANI_S8 rssi = 0; |
| |
| index = limScanHashFunction(pBssDescr->bssDescription.bssId); |
| ptemp = pMac->lim.gLimCachedScanHashTable[index]; |
| |
| //ieFields start with TLV of SSID IE |
| ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1); |
| if ((ssidLen > ie_len) || (ssidLen > DOT11F_IE_SSID_MAX_LEN)) { |
| limLog(pMac, LOGE, FL("SSID length %d, IE overall Length %d"), |
| ssidLen, ie_len); |
| return eHAL_STATUS_FAILURE; |
| } |
| pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo; |
| |
| for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next) |
| { |
| //For infrastructure, check BSSID and SSID. For IBSS, check more |
| pSirCapTemp = (tSirMacCapabilityInfo *)&ptemp->bssDescription.capabilityInfo; |
| if ((pSirCapTemp->ess == pSirCap->ess) && //matching ESS type first |
| (vos_mem_compare( (tANI_U8 *) pBssDescr->bssDescription.bssId, |
| (tANI_U8 *) ptemp->bssDescription.bssId, |
| sizeof(tSirMacAddr))) && //matching BSSID |
| // matching band to update new channel info |
| (vos_chan_to_band(pBssDescr->bssDescription.channelId) == |
| vos_chan_to_band(ptemp->bssDescription.channelId)) && |
| (*((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1) == |
| *((tANI_U8 *) &ptemp->bssDescription.ieFields + 1)) && |
| vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1), |
| ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1), |
| (tANI_U8) (ssidLen + 1)) && |
| ((pSirCapTemp->ess) || //we are done for infrastructure |
| //For IBSS, nwType and channelId |
| (((pBssDescr->bssDescription.nwType == |
| ptemp->bssDescription.nwType) && |
| (pBssDescr->bssDescription.channelId == |
| ptemp->bssDescription.channelId)))) |
| ) |
| { |
| // Found the same BSS description |
| if (action == LIM_HASH_UPDATE) |
| { |
| if(dontUpdateAll) |
| { |
| rssi = ptemp->bssDescription.rssi; |
| } |
| |
| if(pBssDescr->bssDescription.fProbeRsp != |
| ptemp->bssDescription.fProbeRsp) |
| { |
| //We get a different, save the old frame WSC IE if it is there |
| len = ptemp->bssDescription.length - |
| sizeof(tSirBssDescription) + |
| sizeof(tANI_U16) + sizeof(tANI_U32); |
| pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields; |
| //Save WPS IE if it exists |
| pBssDescr->bssDescription.WscIeLen = 0; |
| while (len >= 2) |
| { |
| elem_id = pbIe[0]; |
| elem_len = pbIe[1]; |
| len -= 2; |
| if (elem_len > len) { |
| limLog(pMac, LOGW, FL("Invalid eid: %d elem_len: %d left: %d"), |
| elem_id, elem_len, len); |
| return eHAL_STATUS_FAILURE; |
| } |
| if ((elem_id == DOT11F_EID_WSCPROBERES) && |
| (elem_len >= DOT11F_IE_WSCPROBERES_MIN_LEN) && |
| ((pbIe[2] == 0x00) && (pbIe[3] == 0x50) && |
| (pbIe[4] == 0xf2) && |
| (pbIe[5] == 0x04))) |
| { |
| if((elem_len + 2) <= WSCIE_PROBE_RSP_LEN) |
| { |
| vos_mem_copy( |
| pBssDescr->bssDescription.WscIeProbeRsp, |
| pbIe, elem_len + 2); |
| pBssDescr->bssDescription.WscIeLen = |
| elem_len + 2; |
| } |
| break; |
| } |
| len -= elem_len; |
| pbIe += (elem_len + 2); |
| } |
| } |
| /* |
| * Due to Rx sensitivity issue, sometime beacons are seen on |
| * adjacent channel so workaround in software is needed. If DS |
| * params or HT info are present driver can get proper channel |
| * info from these IEs and the older RSSI values are used in new |
| * entry. |
| * |
| * For the cases where DS params and HT info is not present, |
| * driver needs to check below conditions to update proper |
| * channel so that the older RSSI and channel values are used in |
| * new entry: |
| * -- The old entry channel and new entry channel are not same |
| * -- RSSI is below 15db or more from old value, this indicate |
| * that the signal has leaked in adjacent channel |
| */ |
| if (!pBssDescr->bssDescription.fProbeRsp && |
| !chan_info_present && |
| (pBssDescr->bssDescription.channelId != |
| ptemp->bssDescription.channelId) && |
| ((ptemp->bssDescription.rssi - |
| pBssDescr->bssDescription.rssi) > |
| SIR_ADJACENT_CHANNEL_RSSI_DIFF_THRESHOLD)) { |
| pBssDescr->bssDescription.channelId = |
| ptemp->bssDescription.channelId; |
| pBssDescr->bssDescription.rssi = |
| ptemp->bssDescription.rssi; |
| } |
| |
| |
| if(NULL != pMac->lim.gpLimMlmScanReq) |
| { |
| if((pMac->lim.gpLimMlmScanReq->numSsid)&& |
| ( limIsNullSsid((tSirMacSSid *)((tANI_U8 *) |
| &pBssDescr->bssDescription.ieFields + 1)))) |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| // Delete this entry |
| if (ptemp == pMac->lim.gLimCachedScanHashTable[index]) |
| pprev = pMac->lim.gLimCachedScanHashTable[index] = ptemp->next; |
| else |
| pprev->next = ptemp->next; |
| |
| pMac->lim.gLimMlmScanResultLength -= |
| ptemp->bssDescription.length + sizeof(tANI_U16); |
| |
| vos_mem_free(ptemp); |
| } |
| found = true; |
| break; |
| } |
| } |
| |
| //for now, only rssi, we can add more if needed |
| if ((action == LIM_HASH_UPDATE) && dontUpdateAll && rssi) |
| { |
| pBssDescr->bssDescription.rssi = rssi; |
| } |
| |
| // Add this BSS description at same index |
| if (pprev == pMac->lim.gLimCachedScanHashTable[index]) |
| { |
| pBssDescr->next = pMac->lim.gLimCachedScanHashTable[index]; |
| pMac->lim.gLimCachedScanHashTable[index] = pBssDescr; |
| } |
| else |
| { |
| pBssDescr->next = pprev->next; |
| pprev->next = pBssDescr; |
| } |
| pMac->lim.gLimMlmScanResultLength += |
| pBssDescr->bssDescription.length + sizeof(tANI_U16); |
| |
| PELOG2(limLog(pMac, LOG2, FL("Added new BSS description size %d TOT %d BSS id"), |
| pBssDescr->bssDescription.length, |
| pMac->lim.gLimMlmScanResultLength); |
| limPrintMacAddr(pMac, pBssDescr->bssDescription.bssId, LOG2);) |
| |
| // Send new BSS found indication to HDD if CFG option is set |
| if (!found) limSendSmeNeighborBssInd(pMac, pBssDescr); |
| |
| // |
| // TODO: IF applicable, do we need to send: |
| // Mesg - eWNI_SME_WM_STATUS_CHANGE_NTF |
| // Status change code - eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP |
| // |
| return eHAL_STATUS_SUCCESS; |
| } |
| |
| |
| |
| /** |
| * limDeleteHashEntry() |
| * |
| *FUNCTION: |
| * This function is called upon to delete |
| * a BSS description from scan result hash table. |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * Yet to find the utility of the function |
| * |
| * @param pBssDescr - Pointer to BSS description to be |
| * deleted from the scan result hash table. |
| * |
| * @return None |
| */ |
| |
| void limDeleteHashEntry(tLimScanResultNode *pBssDescr) |
| { |
| } /****** end limDeleteHashEntry() ******/ |
| |
| |
| #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| /** |
| * limInitLfrHashTable() |
| * |
| *FUNCTION: |
| * This function is called upon receiving SME_START_REQ |
| * to initialize global cached Lfr scan hash table |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limInitLfrHashTable(tpAniSirGlobal pMac) |
| { |
| tANI_U16 i; |
| for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) |
| pMac->lim.gLimCachedLfrScanHashTable[i] = NULL; |
| } /****** end limInitLfrHashTable() ******/ |
| |
| |
| |
| /** |
| * limLookupNaddLfrHashEntry() |
| * |
| *FUNCTION: |
| * This function is called upon receiving a Beacon or |
| * Probe Response frame during Lfr scan phase from FW to store |
| * received BSS description into Lfr scan result hash table. |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param pBssDescr - Pointer to BSS description to be |
| * added to the Lfr scan result hash table. |
| * @param action - Indicates action to be performed |
| * when same BSS description is found. This is |
| * dependent on whether unique scan result to |
| * be stored or not. |
| * |
| * @return None |
| */ |
| |
| eHalStatus |
| limLookupNaddLfrHashEntry(tpAniSirGlobal pMac, |
| tLimScanResultNode *pBssDescr, tANI_U8 action, |
| tANI_U8 dontUpdateAll, tANI_U32 ie_len) |
| { |
| tANI_U8 index, ssidLen = 0; |
| tLimScanResultNode *ptemp, *pprev; |
| tSirMacCapabilityInfo *pSirCap, *pSirCapTemp; |
| int idx, len; |
| tANI_U8 *pbIe; |
| tANI_S8 rssi = 0; |
| |
| index = limScanHashFunction(pBssDescr->bssDescription.bssId); |
| ptemp = pMac->lim.gLimCachedLfrScanHashTable[index]; |
| |
| //ieFields start with TLV of SSID IE |
| ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1); |
| if ((ssidLen > ie_len) || (ssidLen > DOT11F_IE_SSID_MAX_LEN)) { |
| limLog(pMac, LOGE, FL("SSID length %d, IE overall Length %d"), |
| ssidLen, ie_len); |
| return eHAL_STATUS_FAILURE; |
| } |
| pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo; |
| |
| for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next) |
| { |
| //For infrastructure, check BSSID and SSID. For IBSS, check more |
| pSirCapTemp = (tSirMacCapabilityInfo *)&ptemp->bssDescription.capabilityInfo; |
| if ((pSirCapTemp->ess == pSirCap->ess) && //matching ESS type first |
| (vos_mem_compare( (tANI_U8 *) pBssDescr->bssDescription.bssId, |
| (tANI_U8 *) ptemp->bssDescription.bssId, |
| sizeof(tSirMacAddr))) && //matching BSSID |
| (pBssDescr->bssDescription.channelId == |
| ptemp->bssDescription.channelId) && |
| (*((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1) == |
| *((tANI_U8 *) &ptemp->bssDescription.ieFields + 1)) && |
| vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1), |
| ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1), |
| (tANI_U8) (ssidLen + 1)) && |
| ((pSirCapTemp->ess) || //we are done for infrastructure |
| //For IBSS, nwType and channelId |
| (((pBssDescr->bssDescription.nwType == |
| ptemp->bssDescription.nwType) && |
| (pBssDescr->bssDescription.channelId == |
| ptemp->bssDescription.channelId)))) |
| ) |
| { |
| // Found the same BSS description |
| if (action == LIM_HASH_UPDATE) |
| { |
| if(dontUpdateAll) |
| { |
| rssi = ptemp->bssDescription.rssi; |
| } |
| |
| if(pBssDescr->bssDescription.fProbeRsp != ptemp->bssDescription.fProbeRsp) |
| { |
| //We get a different, save the old frame WSC IE if it is there |
| idx = 0; |
| len = ptemp->bssDescription.length - sizeof(tSirBssDescription) + |
| sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2; |
| pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields; |
| //Save WPS IE if it exists |
| pBssDescr->bssDescription.WscIeLen = 0; |
| while(idx < len) |
| { |
| if((DOT11F_EID_WSCPROBERES == pbIe[0]) && |
| (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && |
| (0xf2 == pbIe[4]) && (0x04 == pbIe[5])) |
| { |
| //Found it |
| if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1]) |
| { |
| vos_mem_copy( pBssDescr->bssDescription.WscIeProbeRsp, |
| pbIe, pbIe[1] + 2); |
| pBssDescr->bssDescription.WscIeLen = pbIe[1] + 2; |
| } |
| break; |
| } |
| idx += pbIe[1] + 2; |
| pbIe += pbIe[1] + 2; |
| } |
| } |
| |
| |
| if(NULL != pMac->lim.gpLimMlmScanReq) |
| { |
| if((pMac->lim.gpLimMlmScanReq->numSsid)&& |
| ( limIsNullSsid((tSirMacSSid *)((tANI_U8 *) |
| &pBssDescr->bssDescription.ieFields + 1)))) |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| // Delete this entry |
| if (ptemp == pMac->lim.gLimCachedLfrScanHashTable[index]) |
| pprev = pMac->lim.gLimCachedLfrScanHashTable[index] = ptemp->next; |
| else |
| pprev->next = ptemp->next; |
| |
| pMac->lim.gLimMlmLfrScanResultLength -= |
| ptemp->bssDescription.length + sizeof(tANI_U16); |
| |
| vos_mem_free(ptemp); |
| } |
| break; |
| } |
| } |
| |
| //for now, only rssi, we can add more if needed |
| if ((action == LIM_HASH_UPDATE) && dontUpdateAll && rssi) |
| { |
| pBssDescr->bssDescription.rssi = rssi; |
| } |
| |
| // Add this BSS description at same index |
| if (pprev == pMac->lim.gLimCachedLfrScanHashTable[index]) |
| { |
| pBssDescr->next = pMac->lim.gLimCachedLfrScanHashTable[index]; |
| pMac->lim.gLimCachedLfrScanHashTable[index] = pBssDescr; |
| } |
| else |
| { |
| pBssDescr->next = pprev->next; |
| pprev->next = pBssDescr; |
| } |
| pMac->lim.gLimMlmLfrScanResultLength += |
| pBssDescr->bssDescription.length + sizeof(tANI_U16); |
| |
| PELOG2(limLog(pMac, LOG2, FL("Added new BSS description size %d TOT %d BSS id\n"), |
| pBssDescr->bssDescription.length, |
| pMac->lim.gLimMlmLfrScanResultLength); |
| limPrintMacAddr(pMac, pBssDescr->bssDescription.bssId, LOG2);) |
| |
| // |
| // TODO: IF applicable, do we need to send: |
| // Mesg - eWNI_SME_WM_STATUS_CHANGE_NTF |
| // Status change code - eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP |
| // |
| return eHAL_STATUS_SUCCESS; |
| } |
| |
| |
| |
| /** |
| * limDeleteLfrHashEntry() |
| * |
| *FUNCTION: |
| * This function is called upon to delete |
| * a BSS description from LFR scan result hash table. |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * Yet to find the utility of the function |
| * |
| * @param pBssDescr - Pointer to BSS description to be |
| * deleted from the LFR scan result hash table. |
| * |
| * @return None |
| */ |
| |
| void limDeleteLfrHashEntry(tLimScanResultNode *pBssDescr) |
| { |
| } /****** end limDeleteLfrHashEntry() ******/ |
| |
| #endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| |
| /** |
| * limCopyScanResult() |
| * |
| *FUNCTION: |
| * This function is called by limProcessSmeMessages() while |
| * sending SME_SCAN_RSP with scan result to HDD. |
| * |
| *LOGIC: |
| * This function traverses the scan list stored in scan hash table |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param pDest - Destination pointer |
| * |
| * @return None |
| */ |
| |
| void |
| limCopyScanResult(tpAniSirGlobal pMac, tANI_U8 *pDest) |
| { |
| tLimScanResultNode *ptemp; |
| tANI_U16 i; |
| for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) |
| { |
| if ((ptemp = pMac->lim.gLimCachedScanHashTable[i]) != NULL) |
| { |
| while(ptemp) |
| { |
| /// Copy entire BSS description including length |
| vos_mem_copy( pDest, |
| (tANI_U8 *) &ptemp->bssDescription, |
| ptemp->bssDescription.length + 2); |
| pDest += ptemp->bssDescription.length + 2; |
| ptemp = ptemp->next; |
| } |
| } |
| } |
| } /****** end limCopyScanResult() ******/ |
| |
| |
| |
| /** |
| * limDeleteCachedScanResults() |
| * |
| *FUNCTION: |
| * This function is called by limProcessSmeMessages() upon receiving |
| * SME_SCAN_REQ with fresh scan result flag set. |
| * |
| *LOGIC: |
| * This function traverses the scan list stored in scan hash table |
| * and deletes the entries if any |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limDeleteCachedScanResults(tpAniSirGlobal pMac) |
| { |
| tLimScanResultNode *pNode, *pNextNode; |
| tANI_U16 i; |
| |
| for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) |
| { |
| if ((pNode = pMac->lim.gLimCachedScanHashTable[i]) != NULL) |
| { |
| while (pNode) |
| { |
| pNextNode = pNode->next; |
| |
| // Delete the current node |
| vos_mem_free(pNode); |
| |
| pNode = pNextNode; |
| } |
| } |
| } |
| |
| pMac->lim.gLimSmeScanResultLength = 0; |
| } /****** end limDeleteCachedScanResults() ******/ |
| |
| |
| |
| /** |
| * limReInitScanResults() |
| * |
| *FUNCTION: |
| * This function is called delete exisiting scan results |
| * and initialize the scan hash table |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limReInitScanResults(tpAniSirGlobal pMac) |
| { |
| limLog(pMac, LOG1, FL("Re initialize scan hash table.")); |
| limDeleteCachedScanResults(pMac); |
| limInitHashTable(pMac); |
| |
| // !!LAC - need to clear out the global scan result length |
| // since the list was just purged from the hash table. |
| pMac->lim.gLimMlmScanResultLength = 0; |
| |
| } /****** end limReInitScanResults() ******/ |
| #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| /** |
| * limDeleteCachedLfrScanResults() |
| * |
| *FUNCTION: |
| * This function is called by limProcessSmeMessages() upon receiving |
| * SME_SCAN_REQ with flush scan result flag set for LFR. |
| * |
| *LOGIC: |
| * This function traverses the scan list stored in lfr scan hash |
| * table and deletes the entries if any |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limDeleteCachedLfrScanResults(tpAniSirGlobal pMac) |
| { |
| tLimScanResultNode *pNode, *pNextNode; |
| tANI_U16 i; |
| for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) |
| { |
| if ((pNode = pMac->lim.gLimCachedLfrScanHashTable[i]) != NULL) |
| { |
| while (pNode) |
| { |
| pNextNode = pNode->next; |
| |
| // Delete the current node |
| vos_mem_free(pNode); |
| |
| pNode = pNextNode; |
| } |
| } |
| } |
| |
| pMac->lim.gLimSmeLfrScanResultLength = 0; |
| } /****** end limDeleteCachedLfrScanResults() ******/ |
| |
| |
| |
| /** |
| * limReInitLfrScanResults() |
| * |
| *FUNCTION: |
| * This function is called delete exisiting scan results |
| * and initialize the lfr scan hash table |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limReInitLfrScanResults(tpAniSirGlobal pMac) |
| { |
| limLog(pMac, LOG1, FL("Re initialize lfr scan hash table.")); |
| limDeleteCachedLfrScanResults(pMac); |
| limInitLfrHashTable(pMac); |
| |
| // !!LAC - need to clear out the global scan result length |
| // since the list was just purged from the hash table. |
| pMac->lim.gLimMlmLfrScanResultLength = 0; |
| |
| } /****** end limReInitLfrScanResults() ******/ |
| #endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD |