qcacld-3.0: Send 11k offload params as part of RSO to WMA

Currently 11k offload params is sent directly as a message from CSR to WMA
leading to timing issues where 11k offload params are sent to the FW
before RSO start is sent.

Send the 11k offload params as part of the RSO request from CSR to WMA
and handle the request to send the 11k offload WMA command to FW.

Change-Id: Icff7146171cdf325f3a7e5a067652669ec0270ff
CRs-Fixed: 2183161
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 99a5413..b69dc55 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -3276,6 +3276,7 @@
 	uint32_t btm_solicited_timeout;
 	uint32_t btm_max_attempt_cnt;
 	uint32_t btm_sticky_time;
+	struct wmi_11k_offload_params offload_11k_params;
 } tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq;
 
 typedef struct sSirRoamOffloadScanRsp {
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
index 99ba35b..472992f 100644
--- a/core/mac/src/include/sir_params.h
+++ b/core/mac/src/include/sir_params.h
@@ -693,8 +693,7 @@
 #define SIR_HAL_HLP_IE_INFO                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 392)
 #define SIR_HAL_OBSS_DETECTION_REQ          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 393)
 #define SIR_HAL_OBSS_DETECTION_INFO         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 394)
-#define SIR_HAL_SET_11K_OFFLOAD             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 395)
-#define SIR_HAL_INVOKE_NEIGHBOR_REPORT      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 396)
+#define SIR_HAL_INVOKE_NEIGHBOR_REPORT      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 395)
 #define SIR_HAL_MSG_TYPES_END               (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 
 /* CFG message types */
diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h
index 9847e39..2f3d856 100644
--- a/core/sme/inc/csr_neighbor_roam.h
+++ b/core/sme/inc/csr_neighbor_roam.h
@@ -440,16 +440,4 @@
 				struct sRrmNeighborReq *neighbor_report_req,
 				bool send_resp_to_host);
 
-/**
- * csr_send_11k_offload_params - Update 11K offload params to FW
- * @mac_ctx: MAC context
- * @session_id: session id
- *
- * API to update 11k offload params to WMA then to FW
- *
- * Return: QDF_STATUS
- */
-QDF_STATUS csr_send_11k_offload_params(tpAniSirGlobal mac_ctx,
-					uint8_t session_id);
-
 #endif /* CSR_NEIGHBOR_ROAM_H */
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 72d02fa..7e79b50 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -112,6 +112,12 @@
 #define MAWC_ROAM_RSSI_HIGH_ADJUST_DEFAULT   5
 #define MAWC_ROAM_RSSI_LOW_ADJUST_DEFAULT    5
 
+/*
+ * Neighbor report offload needs to send 0xFFFFFFFF if a particular
+ * parameter is disabled from the ini
+ */
+#define NEIGHBOR_REPORT_PARAM_INVALID (0xFFFFFFFFU)
+
 /* Static Type declarations */
 static struct csr_roam_session csr_roam_roam_session[CSR_ROAM_SESSION_MAX];
 
@@ -18307,6 +18313,142 @@
 #endif
 	return req_buf;
 }
+
+/**
+ * csr_update_11k_offload_params - Update 11K offload params
+ * @mac_ctx: MAC context
+ * @session: Pointer to the CSR Roam Session
+ * @req_buffer: Pointer to the RSO Request buffer
+ *
+ * API to update 11k offload params to Roam Scan Offload request buffer
+ *
+ * Return: none
+ */
+static void csr_update_11k_offload_params(tpAniSirGlobal mac_ctx,
+					  struct csr_roam_session *session,
+					  tSirRoamOffloadScanReq *req_buffer)
+{
+	struct wmi_11k_offload_params *params = &req_buffer->offload_11k_params;
+	struct csr_config *csr_config = &mac_ctx->roam.configParam;
+	struct csr_neighbor_report_offload_params *neighbor_report_offload =
+		&csr_config->neighbor_report_offload;
+
+	params->vdev_id = session->sessionId;
+	params->offload_11k_bitmask = csr_config->offload_11k_enable_bitmask;
+
+	/*
+	 * If none of the parameters are enabled, then set the
+	 * offload_11k_bitmask to 0, so that we don't send the command
+	 * to the FW and drop it in WMA
+	 */
+	if ((neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_ALL) == 0) {
+		sme_err("No valid neighbor report offload params %x",
+			neighbor_report_offload->params_bitmask);
+		params->offload_11k_bitmask = 0;
+	}
+
+	/*
+	 * First initialize all params to NEIGHBOR_REPORT_PARAM_INVALID
+	 * Then set the values that are enabled
+	 */
+	params->neighbor_report_params.time_offset =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+	params->neighbor_report_params.low_rssi_offset =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+	params->neighbor_report_params.bmiss_count_trigger =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+	params->neighbor_report_params.per_threshold_offset =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+	params->neighbor_report_params.neighbor_report_cache_timeout =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+	params->neighbor_report_params.max_neighbor_report_req_cap =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_TIME_OFFSET)
+		params->neighbor_report_params.time_offset =
+			neighbor_report_offload->time_offset;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_LOW_RSSI_OFFSET)
+		params->neighbor_report_params.low_rssi_offset =
+			neighbor_report_offload->low_rssi_offset;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_BMISS_COUNT_TRIGGER)
+		params->neighbor_report_params.bmiss_count_trigger =
+			neighbor_report_offload->bmiss_count_trigger;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_PER_THRESHOLD_OFFSET)
+		params->neighbor_report_params.per_threshold_offset =
+			neighbor_report_offload->per_threshold_offset;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_CACHE_TIMEOUT)
+		params->neighbor_report_params.neighbor_report_cache_timeout =
+			neighbor_report_offload->neighbor_report_cache_timeout;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_MAX_REQ_CAP)
+		params->neighbor_report_params.max_neighbor_report_req_cap =
+			neighbor_report_offload->max_neighbor_report_req_cap;
+
+	params->neighbor_report_params.ssid.length =
+		session->connectedProfile.SSID.length;
+	qdf_mem_copy(params->neighbor_report_params.ssid.mac_ssid,
+			session->connectedProfile.SSID.ssId,
+			session->connectedProfile.SSID.length);
+
+	sme_debug("Updated 11k offload params to RSO");
+}
+
+QDF_STATUS csr_invoke_neighbor_report_request(uint8_t session_id,
+				struct sRrmNeighborReq *neighbor_report_req,
+				bool send_resp_to_host)
+{
+	struct wmi_invoke_neighbor_report_params *invoke_params;
+	struct scheduler_msg msg = {0};
+
+	if (!neighbor_report_req) {
+		sme_err("Invalid params");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	invoke_params = qdf_mem_malloc(sizeof(*invoke_params));
+	if (!invoke_params) {
+		sme_err("Memory allocation failure");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	invoke_params->vdev_id = session_id;
+	invoke_params->send_resp_to_host = send_resp_to_host;
+
+	if (!neighbor_report_req->no_ssid) {
+		invoke_params->ssid.length = neighbor_report_req->ssid.length;
+		qdf_mem_copy(invoke_params->ssid.mac_ssid,
+				neighbor_report_req->ssid.ssId,
+				neighbor_report_req->ssid.length);
+	} else {
+		invoke_params->ssid.length = 0;
+	}
+
+	sme_debug("Sending SIR_HAL_INVOKE_NEIGHBOR_REPORT");
+
+	msg.type = SIR_HAL_INVOKE_NEIGHBOR_REPORT;
+	msg.reserved = 0;
+	msg.bodyptr = invoke_params;
+
+	if (QDF_STATUS_SUCCESS != scheduler_post_msg(QDF_MODULE_ID_WMA, &msg)) {
+		sme_err("Not able to post message to WMA");
+		qdf_mem_free(invoke_params);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * check_allowed_ssid_list() - Check the WhiteList
  * @req_buffer:      Buffer which contains the connected profile SSID.
@@ -19233,6 +19375,9 @@
 		csr_update_driver_assoc_ies(mac_ctx, session, req_buf);
 		csr_update_score_params(mac_ctx, req_buf);
 		csr_update_fils_params_rso(mac_ctx, session, req_buf);
+		if (reason == REASON_CTX_INIT)
+			csr_update_11k_offload_params(mac_ctx, session,
+						      req_buf);
 	}
 
 	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
@@ -19260,177 +19405,6 @@
 	return status;
 }
 
-#define NEIGHBOR_REPORT_PARAM_INVALID (0xFFFFFFFFU)
-
-QDF_STATUS csr_send_11k_offload_params(tpAniSirGlobal mac_ctx,
-					uint8_t session_id)
-{
-	struct csr_roam_session *session;
-	struct wmi_11k_offload_params *params;
-	struct scheduler_msg msg = {0};
-	QDF_STATUS status;
-	struct csr_config *csr_config = &mac_ctx->roam.configParam;
-	struct csr_neighbor_report_offload_params *neighbor_report_offload =
-		&csr_config->neighbor_report_offload;
-
-	if ((csr_config->offload_11k_enable_bitmask &
-	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) == 0) {
-		sme_debug("Neighbor report offload not enabled");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	if ((neighbor_report_offload->params_bitmask &
-	    NEIGHBOR_REPORT_PARAMS_ALL) == 0) {
-		sme_err("No valid neighbor report offload params %x",
-			neighbor_report_offload->params_bitmask);
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	status = sme_acquire_global_lock(&mac_ctx->sme);
-	if (QDF_IS_STATUS_ERROR(status)) {
-		sme_err("sme_acquire_global_lock failed");
-		return status;
-	}
-
-	session = CSR_GET_SESSION(mac_ctx, session_id);
-	if (!session) {
-		sme_release_global_lock(&mac_ctx->sme);
-		sme_err("Session not found");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	if (!session->connectedProfile.SSID.length) {
-		sme_err("SSID Len 0");
-		sme_release_global_lock(&mac_ctx->sme);
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	params = qdf_mem_malloc(sizeof(*params));
-
-	if (!params) {
-		sme_release_global_lock(&mac_ctx->sme);
-		sme_err("Memory allocation failure");
-		return QDF_STATUS_E_NOMEM;
-	}
-
-	params->vdev_id = session_id;
-	params->offload_11k_bitmask = csr_config->offload_11k_enable_bitmask;
-
-	/*
-	 * First initialize all params to NEIGHBOR_REPORT_PARAM_INVALID
-	 * Then set the values that are enabled
-	 */
-	params->neighbor_report_params.time_offset =
-		NEIGHBOR_REPORT_PARAM_INVALID;
-	params->neighbor_report_params.low_rssi_offset =
-		NEIGHBOR_REPORT_PARAM_INVALID;
-	params->neighbor_report_params.bmiss_count_trigger =
-		NEIGHBOR_REPORT_PARAM_INVALID;
-	params->neighbor_report_params.per_threshold_offset =
-		NEIGHBOR_REPORT_PARAM_INVALID;
-	params->neighbor_report_params.neighbor_report_cache_timeout =
-		NEIGHBOR_REPORT_PARAM_INVALID;
-	params->neighbor_report_params.max_neighbor_report_req_cap =
-		NEIGHBOR_REPORT_PARAM_INVALID;
-
-	if (neighbor_report_offload->params_bitmask &
-	    NEIGHBOR_REPORT_PARAMS_TIME_OFFSET)
-		params->neighbor_report_params.time_offset =
-			neighbor_report_offload->time_offset;
-
-	if (neighbor_report_offload->params_bitmask &
-	    NEIGHBOR_REPORT_PARAMS_LOW_RSSI_OFFSET)
-		params->neighbor_report_params.low_rssi_offset =
-			neighbor_report_offload->low_rssi_offset;
-
-	if (neighbor_report_offload->params_bitmask &
-	    NEIGHBOR_REPORT_PARAMS_BMISS_COUNT_TRIGGER)
-		params->neighbor_report_params.bmiss_count_trigger =
-			neighbor_report_offload->bmiss_count_trigger;
-
-	if (neighbor_report_offload->params_bitmask &
-	    NEIGHBOR_REPORT_PARAMS_PER_THRESHOLD_OFFSET)
-		params->neighbor_report_params.per_threshold_offset =
-			neighbor_report_offload->per_threshold_offset;
-
-	if (neighbor_report_offload->params_bitmask &
-	    NEIGHBOR_REPORT_PARAMS_CACHE_TIMEOUT)
-		params->neighbor_report_params.neighbor_report_cache_timeout =
-			neighbor_report_offload->neighbor_report_cache_timeout;
-
-	if (neighbor_report_offload->params_bitmask &
-	    NEIGHBOR_REPORT_PARAMS_MAX_REQ_CAP)
-		params->neighbor_report_params.max_neighbor_report_req_cap =
-			neighbor_report_offload->max_neighbor_report_req_cap;
-
-	params->neighbor_report_params.ssid.length =
-		session->connectedProfile.SSID.length;
-	qdf_mem_copy(params->neighbor_report_params.ssid.mac_ssid,
-			session->connectedProfile.SSID.ssId,
-			session->connectedProfile.SSID.length);
-	sme_release_global_lock(&mac_ctx->sme);
-
-	sme_debug("Sending SIR_HAL_SET_11K_OFFLOAD");
-
-	msg.type = SIR_HAL_SET_11K_OFFLOAD;
-	msg.reserved = 0;
-	msg.bodyptr = params;
-
-	if (QDF_STATUS_SUCCESS != scheduler_post_msg(QDF_MODULE_ID_WMA, &msg)) {
-		sme_err("Not able to post message to WMA");
-		qdf_mem_free(params);
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS csr_invoke_neighbor_report_request(uint8_t session_id,
-				struct sRrmNeighborReq *neighbor_report_req,
-				bool send_resp_to_host)
-{
-	struct wmi_invoke_neighbor_report_params *invoke_params;
-	struct scheduler_msg msg = {0};
-
-	if (!neighbor_report_req) {
-		sme_err("Invalid params");
-		return QDF_STATUS_E_INVAL;
-	}
-
-	invoke_params = qdf_mem_malloc(sizeof(*invoke_params));
-	if (!invoke_params) {
-		sme_err("Memory allocation failure");
-		return QDF_STATUS_E_NOMEM;
-	}
-
-	invoke_params->vdev_id = session_id;
-	invoke_params->send_resp_to_host = send_resp_to_host;
-
-	if (!neighbor_report_req->no_ssid) {
-		invoke_params->ssid.length = neighbor_report_req->ssid.length;
-		qdf_mem_copy(invoke_params->ssid.mac_ssid,
-				neighbor_report_req->ssid.ssId,
-				neighbor_report_req->ssid.length);
-	} else {
-		invoke_params->ssid.length = 0;
-	}
-
-	sme_debug("Sending SIR_HAL_INVOKE_NEIGHBOR_REPORT");
-
-	msg.type = SIR_HAL_INVOKE_NEIGHBOR_REPORT;
-	msg.reserved = 0;
-	msg.bodyptr = invoke_params;
-
-	if (QDF_STATUS_SUCCESS != scheduler_post_msg(QDF_MODULE_ID_WMA, &msg)) {
-		sme_err("Not able to post message to WMA");
-		qdf_mem_free(invoke_params);
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	return QDF_STATUS_SUCCESS;
-}
-
-
 QDF_STATUS csr_roam_offload_scan_rsp_hdlr(tpAniSirGlobal pMac,
 					  tpSirRoamOffloadScanRsp
 						scanOffloadRsp)
diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c
index a80446f..3e8b2f5 100644
--- a/core/sme/src/csr/csr_neighbor_roam.c
+++ b/core/sme/src/csr/csr_neighbor_roam.c
@@ -1160,7 +1160,6 @@
 		csr_neighbor_roam_reset_init_state_control_info(pMac,
 			session_id);
 		csr_neighbor_roam_info_ctx_init(pMac, session_id);
-		csr_send_11k_offload_params(pMac, session_id);
 		break;
 	default:
 		sme_err("Connect evt received in invalid state %s Ignoring",
diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h
index a37f111..e0a8e02 100644
--- a/core/wma/inc/wma_types.h
+++ b/core/wma/inc/wma_types.h
@@ -473,7 +473,6 @@
 #define WMA_SET_LIMIT_OFF_CHAN               SIR_HAL_SET_LIMIT_OFF_CHAN
 #define WMA_OBSS_DETECTION_REQ               SIR_HAL_OBSS_DETECTION_REQ
 #define WMA_OBSS_DETECTION_INFO              SIR_HAL_OBSS_DETECTION_INFO
-#define WMA_SET_11K_OFFLOAD                  SIR_HAL_SET_11K_OFFLOAD
 #define WMA_INVOKE_NEIGHBOR_REPORT           SIR_HAL_INVOKE_NEIGHBOR_REPORT
 
 /* Bit 6 will be used to control BD rate for Management frames */
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index eb507ca..fe731c0 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -7240,31 +7240,6 @@
 }
 
 /**
- * wma_send_offload_11k_params() - API to send 11k offload params to FW
- * @handle: WMA handle
- * @params: Pointer to 11k offload params
- *
- * Return: None
- */
-static
-void wma_send_offload_11k_params(WMA_HANDLE handle,
-				    struct wmi_11k_offload_params *params)
-{
-	QDF_STATUS status;
-	tp_wma_handle wma_handle = (tp_wma_handle) handle;
-
-	if (!wma_handle || !wma_handle->wmi_handle) {
-		WMA_LOGE("WMA is closed, cannot send 11k offload cmd");
-		return;
-	}
-
-	status = wmi_unified_offload_11k_cmd(wma_handle->wmi_handle, params);
-
-	if (status != QDF_STATUS_SUCCESS)
-		WMA_LOGE("failed to send 11k offload command");
-}
-
-/**
  * wma_send_invoke_neighbor_report() - API to send invoke neighbor report
  * command to fw
  *
@@ -8303,10 +8278,6 @@
 		wma_send_obss_detection_cfg(wma_handle, msg->bodyptr);
 		qdf_mem_free(msg->bodyptr);
 		break;
-	case WMA_SET_11K_OFFLOAD:
-		wma_send_offload_11k_params(wma_handle, msg->bodyptr);
-		qdf_mem_free(msg->bodyptr);
-		break;
 	case WMA_INVOKE_NEIGHBOR_REPORT:
 		wma_send_invoke_neighbor_report(wma_handle, msg->bodyptr);
 		qdf_mem_free(msg->bodyptr);
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index e07f4ca..2fcafbe 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -1844,6 +1844,47 @@
 }
 
 /**
+ * wma_send_offload_11k_params() - API to send 11k offload params to FW
+ * @handle: WMA handle
+ * @params: Pointer to 11k offload params
+ *
+ * Return: None
+ */
+static
+QDF_STATUS wma_send_offload_11k_params(WMA_HANDLE handle,
+				    struct wmi_11k_offload_params *params)
+{
+	QDF_STATUS status;
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, cannot send 11k offload cmd",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!WMI_SERVICE_EXT_IS_ENABLED(wma_handle->wmi_service_bitmap,
+				wma_handle->wmi_service_ext_bitmap,
+				WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT)) {
+		WMA_LOGE("%s: FW doesn't support 11k offload",
+			 __func__);
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	if (!params->neighbor_report_params.ssid.length) {
+		WMA_LOGD("%s: SSID Len 0", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_offload_11k_cmd(wma_handle->wmi_handle, params);
+
+	if (status != QDF_STATUS_SUCCESS)
+		WMA_LOGE("failed to send 11k offload command");
+
+	return status;
+}
+
+/**
  * wma_process_roaming_config() - process roam request
  * @wma_handle: wma handle
  * @roam_req: roam request parameters
@@ -1985,6 +2026,16 @@
 			WMA_LOGE("Sending BTM config to fw failed");
 			break;
 		}
+
+		if (roam_req->reason == REASON_CTX_INIT) {
+			qdf_status = wma_send_offload_11k_params(wma_handle,
+						&roam_req->offload_11k_params);
+			if (qdf_status != QDF_STATUS_SUCCESS) {
+				WMA_LOGE("11k offload params not sent, status %d",
+					 qdf_status);
+				break;
+			}
+		}
 		break;
 
 	case ROAM_SCAN_OFFLOAD_STOP: