Browse Source

qcacld-3.0: Send roam triggers from vendor cmd to firmware

Userspace can configure different roam control params as
defined in qca_vendor_attr_roam_control through the roam subcmd
QCA_NL80211_VENDOR_SUBCMD_ROAM and the below attributes:
QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_SCHEME
QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD
QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD
QCA_ATTR_ROAM_CONTROL_USER_REASON

Send value of above attribute to fw through command
WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID for trigger
reason WMI_ROAM_TRIGGER_REASON_BTM_WTC.

Change-Id: I17502eebab56652192164144b7ebdadb32033117
CRs-Fixed: 2729119
Abhinav Kumar 4 years ago
parent
commit
c871ecddbd

+ 56 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -28,6 +28,9 @@
 #include "wlan_mlme_main.h"
 #include "wlan_mlme_api.h"
 
+/* Default value of reason code */
+#define DISABLE_VENDOR_BTM_CONFIG 2
+
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 /**
  * wlan_cm_roam_extract_btm_response() - Extract BTM rsp stats
@@ -117,6 +120,44 @@ wlan_cm_dual_sta_is_freq_allowed(struct wlan_objmgr_psoc *psoc, uint32_t freq,
 void
 wlan_cm_dual_sta_roam_update_connect_channels(struct wlan_objmgr_psoc *psoc,
 					      struct scan_filter *filter);
+/**
+ * wlan_cm_roam_set_vendor_btm_params  - API to set vendor btm params
+ * @psoc: PSOC pointer
+ * @vdev_id: VDEV id
+ * @param: vendor configured roam trigger param
+ *
+ * Return: none
+ */
+void
+wlan_cm_roam_set_vendor_btm_params(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id,
+				   struct wlan_cm_roam_vendor_btm_params
+								*param);
+/**
+ * wlan_cm_roam_disable_vendor_btm  - API to disable vendor btm by default
+ * reason
+ * @psoc: PSOC pointer
+ * @vdev_id: VDEV id
+ *
+ * Return: none
+ */
+void
+wlan_cm_roam_disable_vendor_btm(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id);
+
+/**
+ * wlan_cm_roam_get_vendor_btm_params - API to get vendor btm param
+ * @psoc: PSOC pointer
+ * @vdev_id: VDEV id
+ * @param: vendor configured roam trigger param
+ *
+ * Return: none
+ */
+void
+wlan_cm_roam_get_vendor_btm_params(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id,
+				   struct wlan_cm_roam_vendor_btm_params
+								*param);
+
 #else
 static inline
 void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc,
@@ -159,5 +200,20 @@ wlan_cm_roam_extract_roam_initial_info(wmi_unified_t wmi, void *evt_buf,
 	return true;
 }
 
+static inline void
+wlan_cm_roam_disable_vendor_btm(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{}
+
+static inline void
+wlan_cm_roam_set_vendor_btm_params(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id,
+				   struct wlan_cm_roam_vendor_btm_params *param)
+{}
+
+static inline void
+wlan_cm_roam_get_vendor_btm_params(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id,
+				   struct wlan_cm_roam_vendor_btm_params *param)
+{}
 #endif  /* FEATURE_ROAM_OFFLOAD */
 #endif  /* WLAN_CM_ROAM_API_H__ */

+ 47 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h

@@ -127,15 +127,62 @@ struct wlan_cm_roam_tx_ops {
 					     struct set_pcl_req *req);
 };
 
+/**
+ * enum roam_scan_freq_scheme - Scan mode for triggering roam
+ * ROAM_SCAN_FREQ_SCHEME_NO_SCAN: Indicates the fw to not scan.
+ * ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN: Indicates the firmware to
+ * trigger partial frequency scans.
+ * ROAM_SCAN_FREQ_SCHEME_FULL_SCAN: Indicates the firmware to
+ * trigger full frequency scans.
+ */
+enum roam_scan_freq_scheme {
+	ROAM_SCAN_FREQ_SCHEME_NO_SCAN = 0,
+	ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN = 1,
+	ROAM_SCAN_FREQ_SCHEME_FULL_SCAN = 2,
+};
+
+/**
+ * struct wlan_cm_roam_vendor_btm_params - vendor config roam control param
+ * @scan_freq_scheme: scan frequency scheme from enum
+ * qca_roam_scan_freq_scheme
+ * @connected_rssi_threshold: RSSI threshold of the current
+ * connected AP
+ * @candidate_rssi_threshold: RSSI threshold of the
+ * candidate AP
+ * @user_roam_reason: Roam triggered reason code, value zero is for enable
+ * and non zero value is disable
+ */
+struct wlan_cm_roam_vendor_btm_params {
+	uint32_t scan_freq_scheme;
+	uint32_t connected_rssi_threshold;
+	uint32_t candidate_rssi_threshold;
+	uint32_t user_roam_reason;
+};
+
+/**
+ * struct wlan_roam_triggers - vendor configured roam triggers
+ * @vdev_id: vdev id
+ * @trigger_bitmap: vendor configured roam trigger bitmap as
+ *		    defined @enum roam_control_trigger_reason
+ * @control_param: roam trigger param
+ */
+struct wlan_roam_triggers {
+	uint32_t vdev_id;
+	uint32_t trigger_bitmap;
+	struct wlan_cm_roam_vendor_btm_params vendor_btm_param;
+};
+
 /**
  * struct wlan_cm_roam  - Connection manager roam configs, state and roam
  * data related structure
  * @tx_ops: Roam Tx ops to send roam offload commands to firmware
  * @pcl_vdev_cmd_active:  Flag to check if vdev level pcl command needs to be
  * sent or PDEV level PCL command needs to be sent
+ * @control_param: vendor configured roam control param
  */
 struct wlan_cm_roam {
 	struct wlan_cm_roam_tx_ops tx_ops;
 	bool pcl_vdev_cmd_active;
+	struct wlan_cm_roam_vendor_btm_params vendor_btm_param;
 };
 #endif

+ 82 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -179,4 +179,86 @@ wlan_cm_dual_sta_roam_update_connect_channels(struct wlan_objmgr_psoc *psoc,
 	}
 	qdf_mem_free(channel_list);
 }
+
+void
+wlan_cm_roam_disable_vendor_btm(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_NB_ID);
+	if (!vdev) {
+		mlme_err("vdev object is NULL");
+		return;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
+		return;
+	}
+
+	/* Set default value of reason code */
+	mlme_priv->cm_roam.vendor_btm_param.user_roam_reason =
+						DISABLE_VENDOR_BTM_CONFIG;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
+}
+
+void
+wlan_cm_roam_set_vendor_btm_params(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id,
+				   struct wlan_cm_roam_vendor_btm_params
+									*param)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_NB_ID);
+	if (!vdev) {
+		mlme_err("vdev object is NULL");
+		return;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
+		return;
+	}
+
+	qdf_mem_copy(&mlme_priv->cm_roam.vendor_btm_param, param,
+		     sizeof(struct wlan_cm_roam_vendor_btm_params));
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
+}
+
+void
+wlan_cm_roam_get_vendor_btm_params(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id,
+				   struct wlan_cm_roam_vendor_btm_params *param)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_NB_ID);
+	if (!vdev) {
+		mlme_err("vdev object is NULL");
+		return;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
+		return;
+	}
+
+	qdf_mem_copy(param, &mlme_priv->cm_roam.vendor_btm_param,
+		     sizeof(struct wlan_cm_roam_vendor_btm_params));
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
+}
 #endif

+ 1 - 1
components/wmi/inc/wmi_unified_roam_api.h

@@ -178,7 +178,7 @@ wmi_unified_roam_invoke_cmd(wmi_unified_t wmi_handle,
  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
  */
 QDF_STATUS wmi_unified_set_roam_triggers(wmi_unified_t wmi_handle,
-					 struct roam_triggers *triggers);
+					 struct wlan_roam_triggers *triggers);
 
 /**
  * wmi_unified_send_disconnect_roam_params() - Send disconnect roam trigger

+ 0 - 11
components/wmi/inc/wmi_unified_roam_param.h

@@ -712,17 +712,6 @@ struct wmi_invoke_neighbor_report_params {
 	struct wlan_ssid ssid;
 };
 
-/**
- * struct roam_triggers - vendor configured roam triggers
- * @vdev_id: vdev id
- * @trigger_bitmap: vendor configured roam trigger bitmap as
- *		    defined @enum roam_control_trigger_reason
- */
-struct roam_triggers {
-	uint32_t vdev_id;
-	uint32_t trigger_bitmap;
-};
-
 /**
  * set_pcl_cmd_params  - Set PCL command params
  * @vdev_id: Vdev id

+ 2 - 2
components/wmi/src/wmi_unified_roam_api.c

@@ -337,11 +337,11 @@ QDF_STATUS wmi_unified_get_roam_scan_ch_list(wmi_unified_t wmi_handle,
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 QDF_STATUS wmi_unified_set_roam_triggers(wmi_unified_t wmi_handle,
-					 struct roam_triggers *triggers)
+					 struct wlan_roam_triggers *triggers)
 {
 	if (wmi_handle->ops->send_set_roam_trigger_cmd)
 		return wmi_handle->ops->send_set_roam_trigger_cmd(wmi_handle,
-				triggers->vdev_id, triggers->trigger_bitmap);
+								  triggers);
 
 	return QDF_STATUS_E_FAILURE;
 }

+ 201 - 151
components/wmi/src/wmi_unified_roam_tlv.c

@@ -921,6 +921,206 @@ static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * convert_control_roam_trigger_reason_bitmap() - Convert roam trigger bitmap
+ *
+ * @trigger_reason_bitmap: Roam trigger reason bitmap received from upper layers
+ *
+ * Converts the controlled roam trigger reason bitmap of
+ * type @roam_control_trigger_reason to firmware trigger
+ * reason bitmap as defined in
+ * trigger_reason_bitmask @wmi_roam_enable_disable_trigger_reason_fixed_param
+ *
+ * Return: trigger_reason_bitmask as defined in
+ *	   wmi_roam_enable_disable_trigger_reason_fixed_param
+ */
+static uint32_t
+convert_control_roam_trigger_reason_bitmap(uint32_t trigger_reason_bitmap)
+{
+	uint32_t fw_trigger_bitmap = 0, all_bitmap;
+
+	/* Enable the complete trigger bitmap when all bits are set in
+	 * the control config bitmap
+	 */
+	all_bitmap = BIT(ROAM_TRIGGER_REASON_MAX) - 1;
+	if (trigger_reason_bitmap == all_bitmap)
+		return BIT(WMI_ROAM_TRIGGER_EXT_REASON_MAX) - 1;
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_NONE))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_NONE);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PER))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PER);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BMISS))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BMISS);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_LOW_RSSI))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_LOW_RSSI);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_HIGH_RSSI))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_HIGH_RSSI);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PERIODIC))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PERIODIC);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_MAWC))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_MAWC);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DENSE))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DENSE);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BACKGROUND))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BACKGROUND);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_FORCED))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_FORCED);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BTM))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BTM);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_UNIT_TEST))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_UNIT_TEST);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BSS_LOAD))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BSS_LOAD);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DEAUTH))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DEAUTH);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_IDLE))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_IDLE);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_STA_KICKOUT))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_STA_KICKOUT);
+
+	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_ESS_RSSI))
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_ESS_RSSI);
+
+	return fw_trigger_bitmap;
+}
+
+/**
+ * get_internal_mandatory_roam_triggers() - Internal triggers to be added
+ *
+ * Return: the bitmap of mandatory triggers to be sent to firmware but not given
+ * by user.
+ */
+static uint32_t
+get_internal_mandatory_roam_triggers(void)
+{
+	return BIT(WMI_ROAM_TRIGGER_REASON_FORCED);
+}
+
+/**
+ * convert_roam_trigger_scan_mode() - Function to convert unified Roam trigger
+ * scan mode enum to TLV specific ROAM_TRIGGER_SCAN_MODE
+ * @scan_freq_scheme: scan freq scheme coming from userspace
+ *
+ * Return: ROAM_TRIGGER_SCAN_MODE
+ */
+static WMI_ROAM_TRIGGER_SCAN_MODE
+convert_roam_trigger_scan_mode(enum roam_scan_freq_scheme scan_freq_scheme)
+{
+	switch (scan_freq_scheme) {
+	case ROAM_SCAN_FREQ_SCHEME_NO_SCAN:
+		return ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION;
+	case ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN:
+		return ROAM_TRIGGER_SCAN_MODE_PARTIAL;
+	case ROAM_SCAN_FREQ_SCHEME_FULL_SCAN:
+		return ROAM_TRIGGER_SCAN_MODE_FULL;
+	default:
+		return ROAM_TRIGGER_SCAN_MODE_NONE;
+	}
+}
+
+/**
+ * send_set_roam_trigger_cmd_tlv() - send set roam triggers to fw
+ *
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @trigger_bitmap: roam trigger bitmap to be enabled
+ *
+ * Send WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID to fw.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle,
+					struct wlan_roam_triggers *triggers)
+{
+	wmi_buf_t buf;
+	wmi_roam_enable_disable_trigger_reason_fixed_param *cmd;
+	uint16_t len = sizeof(*cmd);
+	int ret;
+	uint8_t *buf_ptr;
+	wmi_configure_roam_trigger_parameters
+					*roam_trigger_parameters;
+
+	len += WMI_TLV_HDR_SIZE +
+		sizeof(wmi_configure_roam_trigger_parameters);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+
+	cmd = (wmi_roam_enable_disable_trigger_reason_fixed_param *)
+					wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	WMITLV_TAG_STRUC_wmi_roam_enable_disable_trigger_reason_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		      (wmi_roam_enable_disable_trigger_reason_fixed_param));
+	cmd->vdev_id = triggers->vdev_id;
+	cmd->trigger_reason_bitmask =
+	   convert_control_roam_trigger_reason_bitmap(triggers->trigger_bitmap);
+	WMI_LOGD("Received trigger bitmap: 0x%x converted trigger_bitmap: 0x%x",
+		 triggers->trigger_bitmap, cmd->trigger_reason_bitmask);
+	cmd->trigger_reason_bitmask |= get_internal_mandatory_roam_triggers();
+	WMI_LOGD("vdev id: %d final trigger_bitmap: 0x%x",
+		 cmd->vdev_id, cmd->trigger_reason_bitmask);
+
+	buf_ptr += sizeof(wmi_roam_enable_disable_trigger_reason_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		sizeof(wmi_configure_roam_trigger_parameters));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	roam_trigger_parameters =
+		(wmi_configure_roam_trigger_parameters *)buf_ptr;
+	WMITLV_SET_HDR(&roam_trigger_parameters->tlv_header,
+		WMITLV_TAG_STRUC_wmi_configure_roam_trigger_parameters,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_configure_roam_trigger_parameters));
+
+	roam_trigger_parameters->trigger_reason =
+				WMI_ROAM_TRIGGER_REASON_WTC_BTM;
+	if (triggers->vendor_btm_param.user_roam_reason == 0)
+		roam_trigger_parameters->enable = 1;
+	roam_trigger_parameters->scan_mode =
+		convert_roam_trigger_scan_mode(triggers->vendor_btm_param.
+							scan_freq_scheme);
+	roam_trigger_parameters->trigger_rssi_threshold =
+			triggers->vendor_btm_param.connected_rssi_threshold;
+	roam_trigger_parameters->cand_ap_min_rssi_threshold =
+			triggers->vendor_btm_param.candidate_rssi_threshold;
+	roam_trigger_parameters->roam_score_delta_percentage = 0;
+	roam_trigger_parameters->reason_code =
+			triggers->vendor_btm_param.user_roam_reason;
+
+	wmi_mtrace(WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID,
+		   triggers->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Failed to send set roam triggers command ret = %d",
+			 ret);
+		wmi_buf_free(buf);
+	}
+	return ret;
+}
+
 /**
  * send_vdev_set_pcl_cmd_tlv() - Send WMI_VDEV_SET_PCL_CMDID to FW
  * @wmi_handle: wmi handle
@@ -1072,6 +1272,7 @@ void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
 			send_process_roam_synch_complete_cmd_tlv;
 	ops->send_roam_invoke_cmd = send_roam_invoke_cmd_tlv;
 	ops->send_vdev_set_pcl_cmd = send_vdev_set_pcl_cmd_tlv;
+	ops->send_set_roam_trigger_cmd = send_set_roam_trigger_cmd_tlv;
 }
 #else
 static inline QDF_STATUS
@@ -2619,148 +2820,6 @@ send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
 
 	return QDF_STATUS_SUCCESS;
 }
-
-/**
- * convert_control_roam_trigger_reason_bitmap() - Convert roam trigger bitmap
- *
- * @trigger_reason_bitmap: Roam trigger reason bitmap received from upper layers
- *
- * Converts the controlled roam trigger reason bitmap of
- * type @roam_control_trigger_reason to firmware trigger
- * reason bitmap as defined in
- * trigger_reason_bitmask @wmi_roam_enable_disable_trigger_reason_fixed_param
- *
- * Return: trigger_reason_bitmask as defined in
- *	   wmi_roam_enable_disable_trigger_reason_fixed_param
- */
-static uint32_t
-convert_control_roam_trigger_reason_bitmap(uint32_t trigger_reason_bitmap)
-{
-	uint32_t fw_trigger_bitmap = 0, all_bitmap;
-
-	/* Enable the complete trigger bitmap when all bits are set in
-	 * the control config bitmap
-	 */
-	all_bitmap = BIT(ROAM_TRIGGER_REASON_MAX) - 1;
-	if (trigger_reason_bitmap == all_bitmap)
-		return BIT(WMI_ROAM_TRIGGER_EXT_REASON_MAX) - 1;
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_NONE))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_NONE);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PER))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PER);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BMISS))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BMISS);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_LOW_RSSI))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_LOW_RSSI);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_HIGH_RSSI))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_HIGH_RSSI);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PERIODIC))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PERIODIC);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_MAWC))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_MAWC);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DENSE))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DENSE);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BACKGROUND))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BACKGROUND);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_FORCED))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_FORCED);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BTM))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BTM);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_UNIT_TEST))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_UNIT_TEST);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BSS_LOAD))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BSS_LOAD);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DEAUTH))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DEAUTH);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_IDLE))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_IDLE);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_STA_KICKOUT))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_STA_KICKOUT);
-
-	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_ESS_RSSI))
-		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_ESS_RSSI);
-
-	return fw_trigger_bitmap;
-}
-
-/**
- * get_internal_mandatory_roam_triggers() - Internal triggers to be added
- *
- * Return: the bitmap of mandatory triggers to be sent to firmware but not given
- * by user.
- */
-static uint32_t
-get_internal_mandatory_roam_triggers(void)
-{
-	return BIT(WMI_ROAM_TRIGGER_REASON_FORCED);
-}
-
-/**
- * send_set_roam_trigger_cmd_tlv() - send set roam triggers to fw
- *
- * @wmi_handle: wmi handle
- * @vdev_id: vdev id
- * @trigger_bitmap: roam trigger bitmap to be enabled
- *
- * Send WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID to fw.
- *
- * Return: QDF_STATUS
- */
-static QDF_STATUS send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle,
-						uint32_t vdev_id,
-						uint32_t trigger_bitmap)
-{
-	wmi_buf_t buf;
-	wmi_roam_enable_disable_trigger_reason_fixed_param *cmd;
-	uint16_t len = sizeof(*cmd);
-	int ret;
-
-	buf = wmi_buf_alloc(wmi_handle, len);
-	if (!buf) {
-		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
-		return QDF_STATUS_E_NOMEM;
-	}
-
-	cmd = (wmi_roam_enable_disable_trigger_reason_fixed_param *)
-					wmi_buf_data(buf);
-	WMITLV_SET_HDR(&cmd->tlv_header,
-	WMITLV_TAG_STRUC_wmi_roam_enable_disable_trigger_reason_fixed_param,
-		       WMITLV_GET_STRUCT_TLVLEN
-		      (wmi_roam_enable_disable_trigger_reason_fixed_param));
-	cmd->vdev_id = vdev_id;
-	cmd->trigger_reason_bitmask =
-		convert_control_roam_trigger_reason_bitmap(trigger_bitmap);
-	WMI_LOGD("Received trigger bitmap: 0x%x converted trigger_bitmap: 0x%x",
-		 trigger_bitmap, cmd->trigger_reason_bitmask);
-	cmd->trigger_reason_bitmask |= get_internal_mandatory_roam_triggers();
-	WMI_LOGD("vdev id: %d final trigger_bitmap: 0x%x",
-		 cmd->vdev_id, cmd->trigger_reason_bitmask);
-	wmi_mtrace(WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID, vdev_id, 0);
-	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
-				   WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID);
-	if (QDF_IS_STATUS_ERROR(ret)) {
-		WMI_LOGE("Failed to send set roam triggers command ret = %d",
-			 ret);
-		wmi_buf_free(buf);
-	}
-	return ret;
-}
 #else
 static inline QDF_STATUS
 send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle,
@@ -2782,14 +2841,6 @@ send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
 {
 	return QDF_STATUS_E_FAILURE;
 }
-
-static QDF_STATUS
-send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle,
-			      uint32_t vdev_id,
-			      uint32_t trigger_bitmap)
-{
-	return QDF_STATUS_E_FAILURE;
-}
 #endif
 
 /**
@@ -2961,7 +3012,6 @@ void wmi_roam_attach_tlv(wmi_unified_t wmi_handle)
 	ops->send_idle_roam_params = send_idle_roam_params_tlv;
 	ops->send_disconnect_roam_params = send_disconnect_roam_params_tlv;
 	ops->send_roam_preauth_status = send_roam_preauth_status_tlv;
-	ops->send_set_roam_trigger_cmd = send_set_roam_trigger_cmd_tlv,
 
 	wmi_lfr_subnet_detection_attach_tlv(wmi_handle);
 	wmi_rssi_monitor_attach_tlv(wmi_handle);

+ 27 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -153,6 +153,7 @@
 #include "wlan_hdd_apf.h"
 #include "wlan_hdd_cfr.h"
 #include "wlan_hdd_ioctl.h"
+#include "wlan_cm_roam_api.h"
 
 #define g_mode_rates_size (12)
 #define a_mode_rates_size (8)
@@ -4508,6 +4509,10 @@ roam_control_policy[QCA_ATTR_ROAM_CONTROL_MAX + 1] = {
 	[QCA_ATTR_ROAM_CONTROL_TRIGGERS] = {.type = NLA_U32},
 	[QCA_ATTR_ROAM_CONTROL_SELECTION_CRITERIA] = {.type = NLA_NESTED},
 	[QCA_ATTR_ROAM_CONTROL_SCAN_PERIOD] = {.type = NLA_U32},
+	[QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME] = {.type = NLA_U32},
+	[QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD] = {.type = NLA_U32},
+	[QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD] = {.type = NLA_U32},
+	[QCA_ATTR_ROAM_CONTROL_USER_REASON] = {.type = NLA_U32},
 };
 
 /**
@@ -4625,7 +4630,7 @@ hdd_send_roam_triggers_to_sme(struct hdd_context *hdd_ctx,
 			      uint32_t roam_trigger_bitmap)
 {
 	QDF_STATUS status;
-	struct roam_triggers triggers;
+	struct wlan_roam_triggers triggers;
 	struct hdd_adapter *adapter;
 
 	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
@@ -4838,6 +4843,7 @@ hdd_set_roam_with_control_config(struct hdd_context *hdd_ctx,
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct nlattr *tb2[QCA_ATTR_ROAM_CONTROL_MAX + 1], *attr;
 	uint32_t value;
+	struct wlan_cm_roam_vendor_btm_params param = {0};
 
 	hdd_enter();
 	/* The command must carry PARAM_ROAM_CONTROL_CONFIG */
@@ -4945,6 +4951,26 @@ hdd_set_roam_with_control_config(struct hdd_context *hdd_ctx,
 			hdd_err("failed to set candidate selection criteria");
 	}
 
+	attr = tb2[QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME];
+	if (attr)
+		param.scan_freq_scheme = nla_get_u32(attr);
+
+	attr = tb2[QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD];
+	if (attr)
+		param.connected_rssi_threshold = nla_get_u32(attr);
+
+	attr = tb2[QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD];
+	if (attr)
+		param.candidate_rssi_threshold = nla_get_u32(attr);
+
+	attr = tb2[QCA_ATTR_ROAM_CONTROL_USER_REASON];
+	if (attr)
+		param.user_roam_reason = nla_get_u32(attr);
+	 else
+		param.user_roam_reason = DISABLE_VENDOR_BTM_CONFIG;
+	wlan_cm_roam_set_vendor_btm_params(hdd_ctx->psoc, vdev_id, &param);
+	sme_send_vendor_btm_params(hdd_ctx->mac_handle, vdev_id);
+
 	return qdf_status_to_os_return(status);
 }
 

+ 3 - 1
core/hdd/src/wlan_hdd_main.c

@@ -190,6 +190,7 @@
 #include <wlan_hdd_hang_event.h>
 #include "wlan_global_lmac_if_api.h"
 #include "wlan_coex_ucfg_api.h"
+#include "wlan_cm_roam_api.h"
 
 #ifdef MODULE
 #define WLAN_MODULE_NAME  module_name(THIS_MODULE)
@@ -5367,7 +5368,8 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
 		roam_triggers = ucfg_mlme_get_roaming_triggers(hdd_ctx->psoc);
 		mlme_set_roam_trigger_bitmap(hdd_ctx->psoc, adapter->vdev_id,
 					     roam_triggers);
-
+		wlan_cm_roam_disable_vendor_btm(hdd_ctx->psoc,
+						adapter->vdev_id);
 		ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
 						 &fine_time_meas_cap);
 		sme_cli_set_command(

+ 1 - 1
core/mac/inc/sir_api.h

@@ -2217,7 +2217,7 @@ struct roam_offload_scan_req {
 	struct wmi_disconnect_roam_params disconnect_roam_params;
 #endif
 	struct roam_ext_params roam_params;
-	struct roam_triggers roam_triggers;
+	struct wlan_roam_triggers roam_triggers;
 	uint8_t  middle_of_roaming;
 	uint32_t hi_rssi_scan_max_count;
 	uint32_t hi_rssi_scan_rssi_delta;

+ 1 - 1
core/sme/inc/csr_neighbor_roam.h

@@ -263,7 +263,7 @@ void csr_roam_reset_roam_params(struct mac_context *mac_ptr);
 #define REASON_SUPPLICANT_INIT_ROAMING              46
 #define REASON_SUPPLICANT_DE_INIT_ROAMING           47
 #define REASON_DRIVER_DISABLED                      48
-#define REASON_ROAM_CONTROL_CONFIG_RESTORED         49
+#define REASON_ROAM_CONTROL_CONFIG_CHANGED          49
 #define REASON_ROAM_CONTROL_CONFIG_ENABLED          50
 #define REASON_ROAM_CANDIDATE_FOUND                 51
 #define REASON_ROAM_HANDOFF_DONE                    52

+ 13 - 1
core/sme/inc/sme_api.h

@@ -4069,7 +4069,7 @@ void sme_chan_to_freq_list(
  * Return: QDF_STATUS
  */
 QDF_STATUS sme_set_roam_triggers(mac_handle_t mac_handle,
-				 struct roam_triggers *triggers);
+				 struct wlan_roam_triggers *triggers);
 
 /**
  * sme_set_roam_config_enable() - Cache roam config status in SME
@@ -4087,6 +4087,18 @@ QDF_STATUS sme_set_roam_config_enable(mac_handle_t mac_handle,
 				      uint8_t vdev_id,
 				      uint8_t roam_control_enable);
 
+/**
+ * sme_send_vendor_btm_params - Send vendor btm params to FW
+ * @hdd_ctx: HDD context
+ * @vdev_id: vdev id
+ *
+ * Send roam trigger param to firmware if valid.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+sme_send_vendor_btm_params(mac_handle_t mac_handle, uint8_t vdev_id);
+
 /**
  * sme_get_roam_config_status() - Get roam config status from SME
  * @mac_handle: Opaque handle to the MAC context

+ 25 - 3
core/sme/src/common/sme_api.c

@@ -64,7 +64,6 @@
 #include "wlan_mlme_ucfg_api.h"
 #include "wlan_psoc_mlme_api.h"
 #include "mac_init_api.h"
-#include "wlan_cm_roam_public_srtuct.h"
 #include "wlan_cm_roam_api.h"
 #include "wlan_cm_tgt_if_tx_api.h"
 
@@ -15981,12 +15980,12 @@ static QDF_STATUS sme_enable_roaming(struct mac_context *mac, uint32_t vdev_id,
 }
 
 QDF_STATUS sme_set_roam_triggers(mac_handle_t mac_handle,
-				 struct roam_triggers *triggers)
+				 struct wlan_roam_triggers *triggers)
 {
 	QDF_STATUS status;
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
 	struct scheduler_msg message = {0};
-	struct roam_triggers *roam_trigger_data;
+	struct wlan_roam_triggers *roam_trigger_data;
 
 	mlme_set_roam_trigger_bitmap(mac->psoc, triggers->vdev_id,
 				     triggers->trigger_bitmap);
@@ -16028,6 +16027,29 @@ QDF_STATUS sme_set_roam_triggers(mac_handle_t mac_handle,
 	return status;
 }
 
+QDF_STATUS
+sme_send_vendor_btm_params(mac_handle_t mac_handle, uint8_t vdev_id)
+{
+	struct mac_context *mac = MAC_CONTEXT(mac_handle);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (vdev_id >= WLAN_MAX_VDEVS) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (mac->mlme_cfg->lfr.roam_scan_offload_enabled)
+			csr_roam_update_cfg(mac, vdev_id,
+					    REASON_ROAM_CONTROL_CONFIG_CHANGED);
+		sme_release_global_lock(&mac->sme);
+	}
+
+	return status;
+}
+
 QDF_STATUS sme_set_roam_config_enable(mac_handle_t mac_handle,
 				      uint8_t vdev_id,
 				      uint8_t roam_control_enable)

+ 4 - 0
core/sme/src/csr/csr_api_roam.c

@@ -19223,6 +19223,10 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id,
 	else if (command == ROAM_SCAN_OFFLOAD_STOP)
 		csr_update_11k_offload_params(mac_ctx, session, req_buf, FALSE);
 
+	wlan_cm_roam_get_vendor_btm_params(mac_ctx->psoc, session_id,
+					   &req_buf->roam_triggers.
+							vendor_btm_param);
+
 	prev_roaming_state = mlme_get_roam_state(mac_ctx->psoc, session_id);
 
 	/* Update PER config to FW. No need to update in case of stop command,

+ 1 - 1
core/sme/src/csr/csr_neighbor_roam.c

@@ -637,7 +637,7 @@ void csr_roam_reset_roam_params(struct mac_context *mac_ctx)
 static void csr_roam_restore_default_config(struct mac_context *mac_ctx,
 					    uint8_t vdev_id)
 {
-	struct roam_triggers triggers;
+	struct wlan_roam_triggers triggers;
 
 	sme_set_roam_config_enable(MAC_HANDLE(mac_ctx), vdev_id, 0);
 

+ 1 - 1
core/wma/inc/wma_internal.h

@@ -1809,7 +1809,7 @@ int wma_oem_event_handler(void *wma_ctx, uint8_t *event_buff, uint32_t len);
  * Return: Success or Failure status
  */
 QDF_STATUS wma_set_roam_triggers(tp_wma_handle wma_handle,
-				 struct roam_triggers *triggers);
+				 struct wlan_roam_triggers *triggers);
 
 /**
  * wma_get_ani_level_evt_handler - event handler to fetch ani level

+ 4 - 3
core/wma/src/wma_scan_roam.c

@@ -2072,7 +2072,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle,
 		 * disconnect
 		 */
 		if (mode == WMI_ROAM_SCAN_MODE_NONE) {
-			struct roam_triggers roam_triggers;
+			struct wlan_roam_triggers roam_triggers;
 
 			roam_triggers.vdev_id = roam_req->sessionId;
 			roam_triggers.trigger_bitmap = 0;
@@ -2213,6 +2213,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle,
 
 		wma_send_disconnect_roam_params(wma_handle, roam_req);
 		wma_send_idle_roam_params(wma_handle, roam_req);
+		wma_set_roam_triggers(wma_handle, &roam_req->roam_triggers);
 
 		break;
 
@@ -6435,7 +6436,7 @@ int wma_handle_btm_blacklist_event(void *handle, uint8_t *cmd_param_info,
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 QDF_STATUS wma_set_roam_triggers(tp_wma_handle wma,
-				 struct roam_triggers *triggers)
+				 struct wlan_roam_triggers *triggers)
 {
 	if (!wma_is_vdev_valid(triggers->vdev_id))
 		return QDF_STATUS_E_INVAL;
@@ -6543,7 +6544,7 @@ int wma_roam_pmkid_request_event_handler(void *handle, uint8_t *event,
 #endif /* WLAN_FEATURE_FIPS */
 #else
 inline QDF_STATUS
-wma_set_roam_triggers(tp_wma_handle wma, struct roam_triggers *triggers)
+wma_set_roam_triggers(tp_wma_handle wma, struct wlan_roam_triggers *triggers)
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }