qcacld-3.0: Route RSO commands to WMA through LIM layer

qcacld-2.0 to qcacld-3.0 propagation.

Presently the Roam Scan Offload commands(Start/Restart/Stop etc) are all
sent directly from CSR to WMA. This fix reroutes these commands to LIM
and then to WMA. In LIM, ext cap IE present in assoc IE buffer of RSO
command is updated with FTM[Fine Time Measurement] capabilities if set
in host driver

Change-Id: I86c3b93570a38329cbc6a8a31017ece172164732
CRs-fixed: 1009486
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 585ddeb..90eb956 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -2991,6 +2991,8 @@
 };
 
 typedef struct sSirRoamOffloadScanReq {
+	uint16_t message_type;
+	uint16_t length;
 	bool RoamScanOffloadEnabled;
 	bool MAWCEnabled;
 	int8_t LookupThreshold;
diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h
index 43c0c75..264ca2e 100644
--- a/core/mac/inc/wni_api.h
+++ b/core/mac/inc/wni_api.h
@@ -265,6 +265,7 @@
 	eWNI_SME_SEND_DISASSOC_FRAME,
 	eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE,
 	eWNI_SME_DEFAULT_SCAN_IE,
+	eWNI_SME_ROAM_SCAN_OFFLOAD_REQ,
 	eWNI_SME_MSG_TYPES_END
 };
 
diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h
index 68b5a8e..9e77bcc 100644
--- a/core/mac/src/pe/include/lim_api.h
+++ b/core/mac/src/pe/include/lim_api.h
@@ -274,6 +274,7 @@
 	tpSirSmeJoinRsp rsp)
 {}
 #endif
-
+QDF_STATUS lim_update_ext_cap_ie(tpAniSirGlobal mac_ctx,
+	uint8_t *ie_data, uint8_t *local_ie_buf, uint16_t *local_ie_len);
 /************************************************************/
 #endif /* __LIM_API_H */
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
index c2d6f88..a1e0565 100644
--- a/core/mac/src/pe/lim/lim_api.c
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -2184,3 +2184,58 @@
 	}
 	psession_entry->vhtCapability = 1;
 }
+
+/**
+ * lim_update_ext_cap_ie() - Update Extended capabilities IE(if present)
+ *          with capabilities of Fine Time measurements(FTM) if set in driver
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @ie_data: Default Scan IE data
+ * @local_ie_buf: Local Scan IE data
+ * @local_ie_len: Pointer to length of @ie_data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_update_ext_cap_ie(tpAniSirGlobal mac_ctx,
+		uint8_t *ie_data, uint8_t *local_ie_buf, uint16_t *local_ie_len)
+{
+	uint32_t dot11mode;
+	bool vht_enabled = false;
+	tDot11fIEExtCap default_scan_ext_cap = {0}, driver_ext_cap = {0};
+	uint8_t ext_cap_ie_hdr[EXT_CAP_IE_HDR_LEN] = {0x7f, 0x9};
+	tSirRetStatus status;
+
+	status = lim_strip_extcap_update_struct(mac_ctx, ie_data,
+				   local_ie_len, &default_scan_ext_cap);
+	if (eSIR_SUCCESS != status) {
+		lim_log(mac_ctx, LOGE, FL("Strip ext cap fails(%d)"), status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_copy(local_ie_buf, ie_data, (*local_ie_len));
+	qdf_mem_copy(local_ie_buf + (*local_ie_len),
+			ext_cap_ie_hdr, EXT_CAP_IE_HDR_LEN);
+	(*local_ie_len) += EXT_CAP_IE_HDR_LEN;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &dot11mode);
+	if (IS_DOT11_MODE_VHT(dot11mode))
+		vht_enabled = true;
+
+	status = populate_dot11f_ext_cap(mac_ctx, vht_enabled,
+					&driver_ext_cap, NULL);
+	if (eSIR_SUCCESS != status) {
+		lim_log(mac_ctx, LOGE, FL("Failed(%d) to create ext cap IE. Use default value instead"),
+				status);
+		qdf_mem_copy(local_ie_buf + (*local_ie_len),
+				default_scan_ext_cap.bytes,
+				DOT11F_IE_EXTCAP_MAX_LEN);
+		(*local_ie_len) += DOT11F_IE_EXTCAP_MAX_LEN;
+		return QDF_STATUS_SUCCESS;
+	}
+	lim_merge_extcap_struct(&driver_ext_cap, &default_scan_ext_cap);
+
+	qdf_mem_copy(local_ie_buf + (*local_ie_len),
+			driver_ext_cap.bytes, DOT11F_IE_EXTCAP_MAX_LEN);
+	(*local_ie_len) += DOT11F_IE_EXTCAP_MAX_LEN;
+	return QDF_STATUS_SUCCESS;
+}
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 4b2fe9d..da2898f 100644
--- a/core/mac/src/pe/lim/lim_process_message_queue.c
+++ b/core/mac/src/pe/lim/lim_process_message_queue.c
@@ -334,10 +334,10 @@
 		return;
 	}
 
-	if (lim_update_default_scan_ies(mac_ctx,
+	if (lim_update_ext_cap_ie(mac_ctx,
 			(uint8_t *)set_ie_params->ie_data,
 			local_ie_buf, &local_ie_len)) {
-		lim_log(mac_ctx, LOGE, FL("Update default scan IEs fails"));
+		lim_log(mac_ctx, LOGE, FL("Update ext cap IEs fails"));
 		goto scan_ie_send_fail;
 	}
 
@@ -1542,6 +1542,7 @@
 #endif  /* FEATURE_WLAN_ESE */
 	case eWNI_SME_REGISTER_MGMT_FRAME_CB:
 	case eWNI_SME_EXT_CHANGE_CHANNEL:
+	case eWNI_SME_ROAM_SCAN_OFFLOAD_REQ:
 	case eWNI_SME_NDP_INITIATOR_REQ:
 	case eWNI_SME_NDP_RESPONDER_REQ:
 	case eWNI_SME_NDP_END_REQ:
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index ab01850..9aea67e 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -4144,6 +4144,55 @@
 	}
 }
 
+/**
+ * __lim_process_roam_scan_offload_req() - Process Roam scan offload from csr
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: Pointer to SME message buffer
+ *
+ * Return: None
+ */
+static void __lim_process_roam_scan_offload_req(tpAniSirGlobal mac_ctx,
+						uint32_t *msg_buf)
+{
+	tpPESession pe_session;
+	tSirMsgQ wma_msg;
+	tSirRetStatus status;
+	tSirRoamOffloadScanReq *req_buffer;
+	uint16_t local_ie_len;
+	uint8_t *local_ie_buf;
+
+	req_buffer = (tSirRoamOffloadScanReq *)msg_buf;
+	pe_session = pe_find_session_by_sme_session_id(mac_ctx,
+					req_buffer->sessionId);
+
+	local_ie_buf = qdf_mem_malloc(MAX_DEFAULT_SCAN_IE_LEN);
+	if (!local_ie_buf) {
+		lim_log(mac_ctx, LOGE, FL("Mem Alloc failed for local_ie_buf"));
+		return;
+	}
+
+	local_ie_len = req_buffer->assoc_ie.length;
+	/* Update ext cap IE if present */
+	if (local_ie_len &&
+		!lim_update_ext_cap_ie(mac_ctx, req_buffer->assoc_ie.addIEdata,
+					local_ie_buf, &local_ie_len)) {
+		req_buffer->assoc_ie.length = local_ie_len;
+		qdf_mem_copy(req_buffer->assoc_ie.addIEdata, local_ie_buf,
+				local_ie_len);
+	}
+	qdf_mem_free(local_ie_buf);
+
+	wma_msg.type = WMA_ROAM_SCAN_OFFLOAD_REQ;
+	wma_msg.bodyptr = req_buffer;
+
+	status = wma_post_ctrl_msg(mac_ctx, &wma_msg);
+	if (eSIR_SUCCESS != status) {
+		lim_log(mac_ctx, LOGE,
+			FL("Posting WMA_ROAM_SCAN_OFFLOAD_REQ failed"));
+		qdf_mem_free(req_buffer);
+	}
+}
+
 static void __lim_process_sme_hide_ssid(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
 {
 	tpSirUpdateParams pUpdateParams;
@@ -5213,6 +5262,10 @@
 	case eWNI_SME_HIDE_SSID_REQ:
 		__lim_process_sme_hide_ssid(pMac, pMsgBuf);
 		break;
+	case eWNI_SME_ROAM_SCAN_OFFLOAD_REQ:
+		__lim_process_roam_scan_offload_req(pMac, pMsgBuf);
+		bufConsumed = false;
+		break;
 	case eWNI_SME_UPDATE_APWPSIE_REQ:
 		__lim_process_sme_update_apwpsi_es(pMac, pMsgBuf);
 		break;