qcacld-3.0: Send scan results to kernel as and when driver receives

Currently scan results are first cached in SME and then they are
updated to kernel using results in SME cache. This may result in
updation of stale entries to kernel. Fix this by sending scan results
to kernel as and when driver receives them.

Also, add changes to send ext scan results to kernel.

Change-Id: I18f4b36cf3a9fc2e191352c868f69d797eb0a786
CRs-Fixed: 1098411
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 5c8b9b0..19cb8c6 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1605,6 +1605,7 @@
 	unsigned long tdls_source_bitmap;
 	/* tdls source timer to enable/disable TDLS on p2p listen */
 	qdf_mc_timer_t tdls_source_timer;
+	uint8_t beacon_probe_rsp_cnt_per_scan;
 };
 
 /*
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 3353507..1aa8a4e 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -11320,6 +11320,7 @@
 	bss_status =
 		cfg80211_inform_bss_frame(wiphy, chan, mgmt, frame_len, rssi,
 					  GFP_KERNEL);
+	pHddCtx->beacon_probe_rsp_cnt_per_scan++;
 	kfree(mgmt);
 	return bss_status;
 }
diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c
index 36ea7a7..a0aea11 100644
--- a/core/hdd/src/wlan_hdd_scan.c
+++ b/core/hdd/src/wlan_hdd_scan.c
@@ -1217,9 +1217,15 @@
 		goto allow_suspend;
 	}
 
-	ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
-					   pAdapter, scan_time);
-	if (0 > ret) {
+	/*
+	 * cfg80211_scan_done informing NL80211 about completion
+	 * of scanning
+	 */
+	if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE) {
+		aborted = true;
+	}
+
+	if (!aborted && !hddctx->beacon_probe_rsp_cnt_per_scan) {
 		hdd_notice("NO SCAN result");
 		if (hddctx->config->bug_report_for_no_scan_results) {
 			current_timestamp = jiffies_to_msecs(jiffies);
@@ -1241,14 +1247,7 @@
 			}
 		}
 	}
-
-	/*
-	 * cfg80211_scan_done informing NL80211 about completion
-	 * of scanning
-	 */
-	if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE) {
-		aborted = true;
-	}
+	hddctx->beacon_probe_rsp_cnt_per_scan = 0;
 
 	if (!wlan_hdd_is_scan_pending(pAdapter)) {
 		/* Scan is no longer pending */
@@ -1864,6 +1863,7 @@
 	wlan_hdd_scan_request_enqueue(pAdapter, request, source,
 			scan_req.scan_id, scan_req.timestamp);
 	pAdapter->scan_info.mScanPending = true;
+	pHddCtx->beacon_probe_rsp_cnt_per_scan = 0;
 
 free_mem:
 	if (scan_req.SSIDs.SSIDList)
diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c
index d2f0661..bc9e321 100644
--- a/core/mac/src/pe/lim/lim_process_message_queue.c
+++ b/core/mac/src/pe/lim/lim_process_message_queue.c
@@ -509,6 +509,8 @@
 	uint8_t                     *body;
 	struct scheduler_msg         mmh_msg;
 	tpSirMacMgmtHdr              hdr;
+	uint32_t frame_len;
+	tSirBssDescription *bssdescr;
 
 	result = qdf_mem_malloc(sizeof(*result) + ie_len);
 	if (NULL == result) {
@@ -542,6 +544,31 @@
 	qdf_mem_copy((uint8_t *) &result->ap.ieData,
 			body + SIR_MAC_B_PR_SSID_OFFSET, ie_len);
 
+	frame_len = sizeof(*bssdescr) + ie_len - sizeof(bssdescr->ieFields[1]);
+	bssdescr = (tSirBssDescription *) qdf_mem_malloc(frame_len);
+
+	if (NULL == bssdescr) {
+		lim_log(pmac, LOGE,
+			FL("qdf_mem_malloc(length=%d) failed"), frame_len);
+		return;
+	}
+
+	qdf_mem_zero(bssdescr, frame_len);
+
+	lim_collect_bss_description(pmac, bssdescr, frame, rx_pkt_info, false);
+	/*
+	 * Send the beacon to CSR with registered callback routine.
+	 * scan_id and flags parameters are currently unused and set to 0.
+	 * EXT scan results will also be added to scan cache in SME
+	 */
+	if (pmac->lim.add_bssdescr_callback) {
+		(pmac->lim.add_bssdescr_callback) (pmac, bssdescr, 0, 0);
+	} else {
+		lim_log(pmac, LOGE,
+			FL("No CSR callback routine to send beacon/probe response"));
+	}
+	qdf_mem_free(bssdescr);
+
 	mmh_msg.type = msg_type;
 	mmh_msg.bodyptr = result;
 	mmh_msg.bodyval = 0;
diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c
index da6b4eb..eb54692 100644
--- a/core/sme/src/csr/csr_api_scan.c
+++ b/core/sme/src/csr/csr_api_scan.c
@@ -4661,6 +4661,7 @@
 	uint8_t *chanlist = NULL;
 	uint8_t cnt_channels = 0;
 	uint32_t len = sizeof(mac_ctx->roam.validChannelList);
+	tCsrRoamInfo *roam_info;
 
 	sms_log(mac_ctx, LOG4, "CSR: Processing single bssdescr");
 	if (QDF_IS_STATUS_SUCCESS(
@@ -4678,6 +4679,19 @@
 
 	if (csr_scan_validate_scan_result(mac_ctx, chanlist,
 			cnt_channels, bssdescr, &ies)) {
+		roam_info = qdf_mem_malloc(sizeof(*roam_info));
+		if (roam_info) {
+			qdf_mem_zero(roam_info, sizeof(*roam_info));
+			roam_info->pBssDesc = bssdescr;
+
+			csr_roam_call_callback(mac_ctx, 0, roam_info, 0,
+				eCSR_ROAM_UPDATE_SCAN_RESULT,
+				eCSR_ROAM_RESULT_NONE);
+			qdf_mem_free(roam_info);
+		} else {
+			sms_log(mac_ctx, LOG1, "qdf_mem_malloc failed");
+		}
+
 		csr_scan_remove_dup_bss_description_from_interim_list
 			(mac_ctx, bssdescr, ies);
 		csr_scan_save_bss_description_to_interim_list