From 3dedae635ebcf22d7407caec251ee5ee8d7ae018 Mon Sep 17 00:00:00 2001 From: Srinivas Girigowda Date: Wed, 17 Sep 2014 15:01:22 -0700 Subject: qcacld: ExtScan: Forward beacon/probe rsp if report_events >= 2 This change addresses the requirement of forwarding beacons/probe responses in real-time to HAL. Firmware forwards the frames to host driver with scan source id set to EXTSCAN. Based on this host driver determines this beacon/probe rsp received is as a part of EXTSCAN and forwards the same to the HAL using NL vendor events. Any beacon/probe response with IE data exceeding NL size 4k limitation; such frames shall be dropped. Change-Id: Ifd3fd70d2f9b461315981a9f1d15ef2b55f8f415 CRs-Fixed: 726133 --- CORE/CLD_TXRX/TLSHIM/tl_shim.c | 2 + CORE/HDD/src/wlan_hdd_cfg80211.c | 33 +++++--- CORE/MAC/inc/wniApi.h | 3 + CORE/MAC/src/pe/lim/limProcessMessageQueue.c | 108 +++++++++++++++++++++++++++ CORE/SERVICES/WMA/wma.c | 8 +- CORE/SME/src/sme_common/sme_Api.c | 10 +++ CORE/VOSS/inc/i_vos_packet.h | 1 + CORE/WDA/inc/wlan_qct_wda.h | 5 ++ 8 files changed, 160 insertions(+), 10 deletions(-) diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c index 8eb01a096b2b..cdf87f38e3fd 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c @@ -515,6 +515,8 @@ static int tlshim_mgmt_rx_process(void *context, u_int8_t *data, * TODO: Try to maintain rx metainfo as part of skb->data. */ rx_pkt->pkt_meta.channel = hdr->channel; + rx_pkt->pkt_meta.scan_src = hdr->flags; + /*Get the absolute rssi value from the current rssi value *the sinr value is hardcoded into 0 in the core stack*/ rx_pkt->pkt_meta.rssi = hdr->snr + TLSHIM_TGT_NOISE_FLOOR_DBM; diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index c4b74521ad87..d5d69fb03f14 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -15076,33 +15076,48 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx, return; } + /* + * If the full scan result including IE data exceeds NL 4K size limitation, + * drop that beacon/probe rsp frame. + */ + if ((sizeof(*pData) + pData->ap.ieLength) >= EXTSCAN_EVENT_BUF_SIZE) { + hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!!")); + return; + } skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX, GFP_KERNEL); if (!skb) { - hddLog(VOS_TRACE_LEVEL_ERROR, - FL("cfg80211_vendor_event_alloc failed")); + hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed")); return; } - hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); - hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData); - hddLog(VOS_TRACE_LEVEL_INFO, "AP Info: Timestamp(0x%llX) " - "Ssid (%s) " + pData->ap.channel = vos_chan_to_freq(pData->ap.channel); + hddLog(LOG1, "Req Id (%u) More Data (%u)", pData->requestId, + pData->moreData); + hddLog(LOG1, "AP Info: Timestamp(0x%llX) Ssid (%s) " "Bssid (" MAC_ADDRESS_STR ") " "Channel (%u) " - "Rssi (%u) " + "Rssi (%d) " "RTT (%u) " - "RTT_SD (%u)", + "RTT_SD (%u) " + "Bcn Period (%d) " + "Capability (0x%X) " + "IE Length (%d)", pData->ap.ts, pData->ap.ssid, MAC_ADDR_ARRAY(pData->ap.bssid), pData->ap.channel, pData->ap.rssi, pData->ap.rtt, - pData->ap.rtt_sd); + pData->ap.rtt_sd, + pData->ap.beaconPeriod, + pData->ap.capability, + pData->ap.ieLength); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + pData->ap.ieData, pData->ap.ieLength); if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, pData->requestId) || diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h index 24043f54ec5d..66ac55ecd6b4 100644 --- a/CORE/MAC/inc/wniApi.h +++ b/CORE/MAC/inc/wniApi.h @@ -388,6 +388,9 @@ enum eWniMsgTypes #endif eWNI_SME_MSG_GET_TEMPERATURE_IND, eWNI_SME_SNR_IND, +#ifdef FEATURE_WLAN_EXTSCAN + eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND, +#endif eWNI_SME_MSG_TYPES_END }; diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c index a5f46480f45c..8405d2dbceb6 100644 --- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c +++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c @@ -165,6 +165,101 @@ defMsgDecision(tpAniSirGlobal pMac, tpSirMsgQ limMsg) return false; } +#ifdef FEATURE_WLAN_EXTSCAN +static void +__limExtScanForwardBcnProbeRsp(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, + tSirProbeRespBeacon *pFrame, tANI_U32 ieLen) +{ + tpSirWifiFullScanResultEvent fScanResult; + tANI_U8 *pBody; + tSirMsgQ mmhMsg; + tpSirMacMgmtHdr pHdr; + + fScanResult = vos_mem_malloc(sizeof(*fScanResult) + ieLen); + if (NULL == fScanResult) { + limLog(pMac, LOGE, FL("Memory allocation failed")); + return; + } + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + vos_mem_zero(fScanResult, sizeof(*fScanResult) + ieLen); + + /* Received frame does not have request id, hence set 0 */ + fScanResult->requestId = 0; + + fScanResult->moreData = 0; + fScanResult->ap.ts = vos_timer_get_system_time(); + fScanResult->ap.beaconPeriod = pFrame->beaconInterval; + fScanResult->ap.capability = limGetU16((tANI_U8 *)&pFrame->capabilityInfo); + fScanResult->ap.channel = WDA_GET_RX_CH(pRxPacketInfo); + fScanResult->ap.rssi = WDA_GET_RX_RSSI_DB(pRxPacketInfo); + fScanResult->ap.rtt = 0; + fScanResult->ap.rtt_sd = 0; + fScanResult->ap.ieLength = ieLen; + + vos_mem_copy((tANI_U8 *) &fScanResult->ap.ssid[0], + (tANI_U8 *) pFrame->ssId.ssId, pFrame->ssId.length); + fScanResult->ap.ssid[pFrame->ssId.length] = '\0'; + vos_mem_copy((tANI_U8 *) &fScanResult->ap.bssid, (tANI_U8 *) pHdr->bssId, + sizeof(tSirMacAddr)); + /* Copy IE fields */ + vos_mem_copy((tANI_U8 *) &fScanResult->ap.ieData, + pBody + SIR_MAC_B_PR_SSID_OFFSET, ieLen); + + mmhMsg.type = eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND; + mmhMsg.bodyptr = fScanResult; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +static void +__limProcessExtScanBeaconProbeRsp(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, + tANI_U8 subType) +{ + tSirProbeRespBeacon *pFrame; + tANI_U8 *pBody; + tANI_U32 frameLen; + tSirRetStatus status; + + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + if (frameLen <= SIR_MAC_B_PR_SSID_OFFSET) { + limLog(pMac, LOGP, + FL("RX packet has invalid length %d"), frameLen); + return; + } + + pFrame = vos_mem_malloc(sizeof(*pFrame)); + if (NULL == pFrame) { + limLog(pMac, LOGE, FL("Memory allocation failed")); + return; + } + + if (subType == SIR_MAC_MGMT_BEACON) { + limLog(pMac, LOG2, FL("Beacon due to ExtScan")); + status = sirConvertBeaconFrame2Struct(pMac, (tANI_U8 *)pRxPacketInfo, + pFrame); + } else if (subType == SIR_MAC_MGMT_PROBE_RSP) { + limLog(pMac, LOG2, FL("Probe Rsp due to ExtScan")); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + status = sirConvertProbeFrame2Struct(pMac, pBody, frameLen, pFrame); + } else { + vos_mem_free(pFrame); + return; + } + + if (status != eSIR_SUCCESS) { + limLog(pMac, LOGE, FL("Frame parsing failed")); + vos_mem_free(pFrame); + return; + } + + __limExtScanForwardBcnProbeRsp(pMac, pRxPacketInfo, pFrame, + (frameLen - SIR_MAC_B_PR_SSID_OFFSET)); + vos_mem_free(pFrame); +} +#endif + + /* * Beacon Handling Cases: * during scanning, when no session is active: @@ -560,6 +655,19 @@ limHandle80211Frames(tpAniSirGlobal pMac, tpSirMsgQ limMsg, tANI_U8 *pDeferMsg) fc.type, fc.subType); } } +#ifdef FEATURE_WLAN_EXTSCAN + if (WMA_IS_EXTSCAN_SCAN_SRC(pRxPacketInfo)) { + if (fc.subType == SIR_MAC_MGMT_BEACON || + fc.subType == SIR_MAC_MGMT_PROBE_RSP) { + __limProcessExtScanBeaconProbeRsp(pMac, pRxPacketInfo, fc.subType); + } else { + limLog(pMac, LOGE, FL("Wrong frameType %d, Subtype %d for EXTSCAN"), + fc.type, fc.subType); + } + goto end; + } +#endif + #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD if ( WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo)) { diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 0e4e4c69897e..53c760eeceda 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -21157,12 +21157,18 @@ static VOS_STATUS wma_process_ll_stats_getReq dest_blist->notify_extscan_events = WMI_EXTSCAN_CYCLE_COMPLETED_EVENT | WMI_EXTSCAN_BUCKET_OVERRUN_EVENT; + if (src_bucket->reportEvents >= 2) { + dest_blist->forwarding_flags = + WMI_EXTSCAN_FORWARD_FRAME_TO_HOST; + } else { + dest_blist->forwarding_flags = + WMI_EXTSCAN_NO_FORWARDING; + } dest_blist->min_dwell_time_active = dwelltime; dest_blist->max_dwell_time_active = dwelltime; dest_blist->min_dwell_time_passive = dwelltime; dest_blist->max_dwell_time_passive = dwelltime; - dest_blist->forwarding_flags = 0; src_channel = src_bucket->channels; /* save the channel info to later populate diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index 943bd470d013..1d70fa1dc590 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -2810,6 +2810,16 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg) } break; } +#ifdef FEATURE_WLAN_EXTSCAN + case eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND: + { + pMac->sme.pExtScanIndCb(pMac->hHdd, + eSIR_EXTSCAN_FULL_SCAN_RESULT_IND, + pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + break; + } +#endif default: if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN ) diff --git a/CORE/VOSS/inc/i_vos_packet.h b/CORE/VOSS/inc/i_vos_packet.h index 5f43e1611226..9c86f016f9db 100644 --- a/CORE/VOSS/inc/i_vos_packet.h +++ b/CORE/VOSS/inc/i_vos_packet.h @@ -64,6 +64,7 @@ typedef struct u_int8_t scan:1; u_int8_t dpuFeedback; u_int8_t sessionId; + u_int8_t scan_src:1; }t_packetmeta, *tp_packetmeta; /* implementation specific vos packet type */ diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h index 6ee1ea852cb6..e91a39acc4de 100644 --- a/CORE/WDA/inc/wlan_qct_wda.h +++ b/CORE/WDA/inc/wlan_qct_wda.h @@ -510,6 +510,11 @@ VOS_STATUS WDA_open(v_PVOID_t pVosContext, v_PVOID_t pOSContext, #endif +#ifdef FEATURE_WLAN_EXTSCAN +#define WMA_IS_EXTSCAN_SCAN_SRC(pRxMeta) \ + ((((t_packetmeta *)pRxMeta)->scan_src) == WMI_MGMT_RX_HDR_EXTSCAN) +#endif /* FEATURE_WLAN_EXTSCAN */ + #define WDA_GET_RX_SNR(pRxMeta) \ (((t_packetmeta *)pRxMeta)->snr) -- cgit v1.2.3