qcacld-3.0: Send bss load trigger values to firmware

Introduce the following new WCNSS_qcom.ini values:
"enable_bss_load_roam_trigger"
"bss_load_threshold"
Send these values over the new wmi command,
WMI_ROAM_BSS_LOAD_CONFIG_CMDID if "enable_bss_load_roam_trigger"
is set to true.

This wmi command will be sent to firmware as part of the RSO
start or update config.

Change-Id: Ib2e21904bc7b8d87e5f51824d2694b90a3ac53f2
CRs-Fixed: 2367770
diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c
index 5d9caad..4fd55c7 100644
--- a/components/mlme/core/src/wlan_mlme_main.c
+++ b/components/mlme/core/src/wlan_mlme_main.c
@@ -1314,6 +1314,15 @@
 }
 #endif
 
+static void
+mlme_init_bss_load_trigger_params(struct wlan_objmgr_psoc *psoc,
+				  struct bss_load_trigger *bss_load_trig)
+{
+	bss_load_trig->enabled =
+		cfg_get(psoc, CFG_ENABLE_BSS_LOAD_TRIGGERED_ROAM);
+	bss_load_trig->threshold = cfg_get(psoc, CFG_BSS_LOAD_THRESHOLD);
+}
+
 static void mlme_init_lfr_cfg(struct wlan_objmgr_psoc *psoc,
 			      struct wlan_mlme_lfr_cfg *lfr)
 {
@@ -1463,6 +1472,7 @@
 				(uint8_t)neighbor_scan_chan_list_num;
 	mlme_init_roam_offload_cfg(psoc, lfr);
 	mlme_init_ese_cfg(psoc, lfr);
+	mlme_init_bss_load_trigger_params(psoc, &lfr->bss_load_trig);
 }
 
 static uint32_t
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_lfr.h b/components/mlme/dispatcher/inc/cfg_mlme_lfr.h
index 7f773e0..71082bf 100644
--- a/components/mlme/dispatcher/inc/cfg_mlme_lfr.h
+++ b/components/mlme/dispatcher/inc/cfg_mlme_lfr.h
@@ -1846,6 +1846,56 @@
 	20, \
 	CFG_VALUE_OR_DEFAULT, \
 	"wait time for tx complete before vdev stop")
+/*
+ * <ini>
+ * enable_bss_load_roam_trigger - enable/disable bss load based roam trigger
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini when enabled, allows the firmware to roam when bss load outpaces
+ * the configured bss load threshold. When this ini is disabled, firmware
+ * doesn't consider bss load values to trigger roam.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_BSS_LOAD_TRIGGERED_ROAM CFG_INI_BOOL( \
+			"enable_bss_load_roam_trigger", \
+			1, \
+			"enable bss load triggered roaming")
+
+/*
+ * <ini>
+ * bss_load_threshold - bss load above which the STA should trigger roaming
+ * @Min: 0
+ * @Max: 100
+ * @Default: 70
+ *
+ * When the bss laod value that is sampled exceeds this threshold, firmware
+ * will trigger roaming if bss load trigger is enabled.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BSS_LOAD_THRESHOLD CFG_INI_UINT( \
+		"bss_load_threshold", \
+		0, \
+		100, \
+		70, \
+		CFG_VALUE_OR_DEFAULT, \
+		"bss load threshold")
+
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 /*
@@ -1972,6 +2022,8 @@
 	CFG(CFG_LFR_ROAM_SCAN_N_PROBES) \
 	CFG(CFG_LFR_ROAM_SCAN_HOME_AWAY_TIME) \
 	CFG(CFG_LFR_DELAY_BEFORE_VDEV_STOP) \
+	CFG(CFG_ENABLE_BSS_LOAD_TRIGGERED_ROAM) \
+	CFG(CFG_BSS_LOAD_THRESHOLD) \
 	ROAM_OFFLOAD_ALL \
 	LFR_ESE_ALL
 
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
index d8bf5b3..7a88749 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
@@ -1165,6 +1165,16 @@
 };
 
 /*
+ * struct bss_load_trigger - parameters related to bss load triggered roam
+ * @enabled - flag to check if this trigger is enabled/disabled
+ * @threshold - Bss load threshold value above which roaming should start
+ */
+struct bss_load_trigger {
+	bool enabled;
+	uint32_t threshold;
+};
+
+/*
  * @mawc_roam_enabled:              Enable/Disable MAWC during roaming
  * @enable_fast_roam_in_concurrency:Enable LFR roaming on STA during concurrency
  * @lfr3_roaming_offload:           Enable/disable roam offload feature
@@ -1315,6 +1325,7 @@
 	uint8_t delay_before_vdev_stop;
 	uint8_t neighbor_scan_channel_list[CFG_VALID_CHANNEL_LIST_LEN];
 	uint8_t neighbor_scan_channel_list_num;
+	struct bss_load_trigger bss_load_trig;
 };
 
 /**
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index e9533a5..0d47abd 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -2406,6 +2406,9 @@
 	uint32_t min_delay_btw_roam_scans;
 	uint32_t roam_trigger_reason_bitmask;
 	bool roam_force_rssi_trigger;
+	/* bss load triggered roam related params */
+	bool bss_load_trig_enabled;
+	struct wmi_bss_load_config bss_load_config;
 } tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq;
 
 typedef struct sSirRoamOffloadScanRsp {
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 7000e1e..c662c6a 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -17202,6 +17202,14 @@
 			mac_ctx->roam.configParam.roam_trigger_reason_bitmask;
 	req_buf->roam_force_rssi_trigger =
 			mac_ctx->roam.configParam.roam_force_rssi_trigger;
+
+	/* fill bss load triggered roam related configs */
+	req_buf->bss_load_trig_enabled =
+			mac_ctx->mlme_cfg->lfr.bss_load_trig.enabled;
+	req_buf->bss_load_config.bss_load_threshold =
+		mac_ctx->mlme_cfg->lfr.bss_load_trig.threshold;
+	req_buf->bss_load_config.vdev_id = session->sessionId;
+
 	req_buf->ReassocFailureTimeout =
 		mac_ctx->mlme_cfg->timeouts.reassoc_failure_timeout;
 	csr_update_roam_scan_ese_params(req_buf, session);
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index f58f2ab..5c5df27 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -1412,6 +1412,36 @@
 }
 
 /**
+ * wma_send_roam_bss_load_config() - API to send load bss trigger
+ * related parameters to fw
+ *
+ * @handle: WMA handle
+ * @roam_req: bss load config parameters from csr to be sent to fw
+ *
+ * Return: None
+ */
+static
+void wma_send_roam_bss_load_config(WMA_HANDLE handle,
+				   struct wmi_bss_load_config *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 bss load config");
+		return;
+	}
+
+	WMA_LOGD("%s: Sending bss load trig params vdev %u bss_load_threshold %u",
+		 __func__, params->vdev_id, params->bss_load_threshold);
+
+	status = wmi_unified_send_bss_load_config(wma_handle->wmi_handle,
+						  params);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGE("failed to send bss load trigger config command");
+}
+
+/**
  * wma_send_offload_11k_params() - API to send 11k offload params to FW
  * @handle: WMA handle
  * @params: Pointer to 11k offload params
@@ -1471,6 +1501,7 @@
 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
 	uint32_t mode = 0;
 	struct wma_txrx_node *intr = NULL;
+	struct wmi_bss_load_config *bss_load_cfg;
 
 	if (NULL == mac) {
 		WMA_LOGE("%s: mac is NULL", __func__);
@@ -1611,6 +1642,11 @@
 				break;
 			}
 		}
+
+		if (roam_req->bss_load_trig_enabled) {
+			bss_load_cfg = &roam_req->bss_load_config;
+			wma_send_roam_bss_load_config(wma_handle, bss_load_cfg);
+		}
 		break;
 
 	case ROAM_SCAN_OFFLOAD_STOP:
@@ -1860,7 +1896,6 @@
 			wma_roam_scan_offload_mode(wma_handle, &scan_params,
 						   roam_req, mode,
 						   roam_req->sessionId);
-
 		break;
 
 	default: