Browse Source

qcacld-3.0: Move sta related wmi functions from cmn to qcacld

Move STA specific wmi functions from qca-wifi-host-cmn to
qcacld-3.0 under components/wmi. Below is the wmi source tree
	qcacld-3.0 \
	    - components \
		-wmi \
		  src\
		  inc\

wmi_tlv_attach() will call the STA specific attach functions
defined in wmi_unified_priv.h.

Change-Id: Ia99e12d79500add94791db4447e1f6dbf44c99af
CRs-Fixed: 2714589
Pragaspathi Thilagaraj 4 years ago
parent
commit
bd697c1786

+ 14 - 5
Kbuild

@@ -715,6 +715,18 @@ SYS_OBJS :=	$(SYS_COMMON_SRC_DIR)/wlan_qct_sys.o \
 		$(SYS_LEGACY_SRC_DIR)/utils/src/parser_api.o \
 		$(SYS_LEGACY_SRC_DIR)/utils/src/utils_parser.o
 
+############ Qcacld WMI ###################
+WMI_DIR := components/wmi
+
+CLD_WMI_INC  :=	-I$(WLAN_ROOT)/$(WMI_DIR)/inc
+
+ifeq ($(CONFIG_WMI_ROAM_SUPPORT), y)
+CLD_WMI_ROAM_OBJS +=	$(WMI_DIR)/src/wmi_unified_roam_tlv.o \
+			$(WMI_DIR)/src/wmi_unified_roam_api.o
+endif
+
+CLD_WMI_OBJS :=	$(CLD_WMI_ROAM_OBJS)
+
 ############ Qca-wifi-host-cmn ############
 QDF_OS_DIR :=	qdf
 QDF_OS_INC_DIR := $(QDF_OS_DIR)/inc
@@ -1476,11 +1488,6 @@ WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_p2p_api.o
 WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_p2p_tlv.o
 endif
 
-ifeq ($(CONFIG_WMI_ROAM_SUPPORT), y)
-WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_roam_api.o
-WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_roam_tlv.o
-endif
-
 ifeq ($(CONFIG_WMI_CONCURRENCY_SUPPORT), y)
 WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_concurrency_api.o
 WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_concurrency_tlv.o
@@ -2193,6 +2200,7 @@ INCS :=		$(HDD_INC) \
 		$(SAP_INC) \
 		$(SME_INC) \
 		$(SYS_INC) \
+		$(CLD_WMI_INC) \
 		$(QAL_INC) \
 		$(QDF_INC) \
 		$(WBUFF_INC) \
@@ -2312,6 +2320,7 @@ OBJS :=		$(HDD_OBJS) \
 		$(SAP_OBJS) \
 		$(SME_OBJS) \
 		$(SYS_OBJS) \
+		$(CLD_WMI_OBJS) \
 		$(QDF_OBJS) \
 		$(WBUFF_OBJS) \
 		$(CDS_OBJS) \

+ 406 - 0
components/wmi/inc/wmi_unified_roam_api.h

@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: Implement API's specific to ROAMING component.
+ */
+
+#ifndef _WMI_UNIFIED_ROAM_API_H_
+#define _WMI_UNIFIED_ROAM_API_H_
+
+#include <wmi_unified_roam_param.h>
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+/**
+ * wmi_unified_set_gateway_params_cmd() - set gateway parameters
+ * @wmi_handle: wmi handle
+ * @req: gateway parameter update request structure
+ *
+ * This function reads the incoming @req and fill in the destination
+ * WMI structure and sends down the gateway configs down to the firmware
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failures;
+ *         error number otherwise
+ */
+QDF_STATUS
+wmi_unified_set_gateway_params_cmd(wmi_unified_t wmi_handle,
+				   struct gateway_update_req_param *req);
+#endif
+
+#ifdef FEATURE_RSSI_MONITOR
+/**
+ * wmi_unified_set_rssi_monitoring_cmd() - set rssi monitoring
+ * @wmi_handle: wmi handle
+ * @req: rssi monitoring request structure
+ *
+ * This function reads the incoming @req and fill in the destination
+ * WMI structure and send down the rssi monitoring configs down to the firmware
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failures;
+ *         error number otherwise
+ */
+QDF_STATUS
+wmi_unified_set_rssi_monitoring_cmd(wmi_unified_t wmi_handle,
+				    struct rssi_monitor_param *req);
+#endif
+
+/**
+ * wmi_unified_roam_scan_offload_rssi_thresh_cmd() - set roam scan rssi
+ *							parameters
+ * @wmi_handle: wmi handle
+ * @roam_req: roam rssi related parameters
+ *
+ * This function reads the incoming @roam_req and fill in the destination
+ * WMI structure and send down the roam scan rssi configs down to the firmware
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_roam_scan_offload_rssi_thresh_cmd(
+		wmi_unified_t wmi_handle,
+		struct roam_offload_scan_rssi_params *roam_req);
+
+/**
+ * wmi_unified_roam_mawc_params_cmd() - configure roaming MAWC parameters
+ * @wmi_handle: wmi handle
+ * @params: Parameters to be configured
+ *
+ * Pass the MAWC(Motion Aided wireless connectivity) related roaming
+ * parameters from the host to the target
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS
+wmi_unified_roam_mawc_params_cmd(wmi_unified_t wmi_handle,
+				 struct wmi_mawc_roam_params *params);
+
+/**
+ * wmi_unified_roam_scan_filter_cmd() - send roam scan whitelist,
+ *                                      blacklist and preferred list
+ * @wmi_handle: wmi handle
+ * @roam_req: roam scan lists related parameters
+ *
+ * This function reads the incoming @roam_req and fill in the destination
+ * WMI structure and send down the different roam scan lists down to the fw
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS
+wmi_unified_roam_scan_filter_cmd(wmi_unified_t wmi_handle,
+				 struct roam_scan_filter_params *roam_req);
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * wmi_unified_plm_stop_cmd() - plm stop request
+ * @wmi_handle: wmi handle
+ * @plm: plm request parameters
+ *
+ * This function request FW to stop PLM.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_plm_stop_cmd(wmi_unified_t wmi_handle,
+				    const struct plm_req_params *plm);
+
+/**
+ * wmi_unified_plm_start_cmd() - plm start request
+ * @wmi_handle: wmi handle
+ * @plm: plm request parameters
+ *
+ * This function request FW to start PLM.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_plm_start_cmd(wmi_unified_t wmi_handle,
+				     const struct plm_req_params *plm);
+#endif /* FEATURE_WLAN_ESE */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/* wmi_unified_set_ric_req_cmd() - set ric request element
+ * @wmi_handle: wmi handle
+ * @msg: message
+ * @is_add_ts: is addts required
+ *
+ * This function sets ric request element for 11r roaming.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_set_ric_req_cmd(wmi_unified_t wmi_handle, void *msg,
+				       uint8_t is_add_ts);
+
+/**
+ * wmi_unified_roam_synch_complete_cmd() - roam synch complete command to fw.
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ *
+ * This function sends roam synch complete event to fw.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_roam_synch_complete_cmd(wmi_unified_t wmi_handle,
+					       uint8_t vdev_id);
+
+/**
+ * wmi_unified__roam_invoke_cmd() - send roam invoke command to fw.
+ * @wmi_handle: wmi handle
+ * @roaminvoke: roam invoke command
+ * @ch_hz: channel
+ *
+ * Send roam invoke command to fw for fastreassoc.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS
+wmi_unified_roam_invoke_cmd(wmi_unified_t wmi_handle,
+			    struct wmi_roam_invoke_cmd *roaminvoke,
+			    uint32_t ch_hz);
+
+/**
+ * wmi_unified_set_roam_triggers() - send roam trigger bitmap
+ * @wmi_handle: wmi handle
+ * @triggers: Roam trigger bitmap params as defined @roam_control_trigger_reason
+ *
+ * This function passes the roam trigger bitmap to fw
+ *
+ * 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);
+
+/**
+ * wmi_unified_send_disconnect_roam_params() - Send disconnect roam trigger
+ * parameters to firmware
+ * @wmi_hdl:  wmi handle
+ * @params: pointer to wmi_disconnect_roam_params
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wmi_unified_send_disconnect_roam_params(wmi_unified_t wmi_handle,
+					struct wmi_disconnect_roam_params *req);
+
+/**
+ * wmi_unified_send_idle_roam_params() - Send idle roam trigger params to fw
+ * @wmi_hdl:  wmi handle
+ * @params: pointer to wmi_idle_roam_params
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wmi_unified_send_idle_roam_params(wmi_unified_t wmi_handle,
+				  struct wmi_idle_roam_params *req);
+
+/**
+ * wmi_unified_send_roam_preauth_status() - Send roam preauthentication status
+ * to target.
+ * @wmi_handle: wmi handle
+ * @param: Roam auth status params
+ *
+ * This function passes preauth status of WPA3 SAE auth to firmware. It is
+ * called when external_auth_status event is received from userspace.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wmi_unified_send_roam_preauth_status(wmi_unified_t wmi_handle,
+				     struct wmi_roam_auth_status_params *param);
+
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+/**
+ * wmi_unified_roam_scan_offload_mode_cmd() - set roam scan parameters
+ * @wmi_handle: wmi handle
+ * @scan_cmd_fp: scan related parameters
+ * @roam_req: roam related parameters
+ *
+ * This function reads the incoming @roam_req and fill in the destination
+ * WMI structure and send down the roam scan configs down to the firmware
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_roam_scan_offload_mode_cmd(
+				wmi_unified_t wmi_handle,
+				wmi_start_scan_cmd_fixed_param *scan_cmd_fp,
+				struct roam_offload_scan_params *roam_req);
+
+/**
+ * wmi_unified_send_roam_scan_offload_ap_cmd() - set roam ap profile in fw
+ * @wmi_handle: wmi handle
+ * @ap_profile: ap profile params
+ *
+ * Send WMI_ROAM_AP_PROFILE to firmware
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_send_roam_scan_offload_ap_cmd(
+				wmi_unified_t wmi_handle,
+				struct ap_profile_params *ap_profile);
+
+/**
+ * wmi_unified_roam_scan_offload_cmd() - set roam offload command
+ * @wmi_handle: wmi handle
+ * @command: command
+ * @vdev_id: vdev id
+ *
+ * This function set roam offload command to fw.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_roam_scan_offload_cmd(wmi_unified_t wmi_handle,
+					     uint32_t command,
+					     uint32_t vdev_id);
+
+/**
+ * wmi_unified_roam_scan_offload_scan_period() - set roam offload scan period
+ * @wmi_handle: wmi handle
+ * @param: pointer to roam scan period params to be sent to fw
+ *
+ * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_roam_scan_offload_scan_period(
+	wmi_unified_t wmi_handle, struct roam_scan_period_params *param);
+
+/**
+ * wmi_unified_roam_scan_offload_chan_list_cmd() - set roam offload channel list
+ * @wmi_handle: wmi handle
+ * @chan_count: channel count
+ * @chan_list: channel list
+ * @list_type: list type
+ * @vdev_id: vdev id
+ *
+ * Set roam offload channel list.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS
+wmi_unified_roam_scan_offload_chan_list_cmd(wmi_unified_t wmi_handle,
+					    uint8_t chan_count,
+					    uint32_t *chan_list,
+					    uint8_t list_type,
+					    uint32_t vdev_id);
+
+/**
+ * wmi_unified_roam_scan_offload_rssi_change_cmd() - set roam offload RSSI th
+ * @wmi_handle: wmi handle
+ * @rssi_change_thresh: RSSI Change threshold
+ * @bcn_rssi_weight: beacon RSSI weight
+ * @vdev_id: vdev id
+ *
+ * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS
+wmi_unified_roam_scan_offload_rssi_change_cmd(wmi_unified_t wmi_handle,
+					      uint32_t vdev_id,
+					      int32_t rssi_change_thresh,
+					      uint32_t bcn_rssi_weight,
+					      uint32_t hirssi_delay_btw_scans);
+
+/**
+ * wmi_unified_set_per_roam_config() - set PER roam config in FW
+ * @wmi_handle: wmi handle
+ * @req_buf: per roam config request buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS
+wmi_unified_set_per_roam_config(wmi_unified_t wmi_handle,
+				struct wmi_per_roam_config_req *req_buf);
+
+/**
+ * wmi_unified_send_limit_off_chan_cmd() - send wmi cmd of limit off channel
+ * configuration params
+ * @wmi_handle:  wmi handler
+ * @wmi_param: pointer to wmi_limit_off_chan_param
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code on failure
+ */
+QDF_STATUS wmi_unified_send_limit_off_chan_cmd(
+		wmi_unified_t wmi_handle,
+		struct wmi_limit_off_chan_param *wmi_param);
+
+#ifdef WLAN_FEATURE_FILS_SK
+/*
+ * wmi_unified_roam_send_hlp_cmd() -send HLP command info
+ * @wmi_handle: wma handle
+ * @req_buf: Pointer to HLP params
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_roam_send_hlp_cmd(wmi_unified_t wmi_handle,
+					 struct hlp_params *req_buf);
+#endif /* WLAN_FEATURE_FILS_SK */
+
+/**
+ * wmi_unified_send_btm_config() - Send BTM config to fw
+ * @wmi_handle:  wmi handle
+ * @params: pointer to wmi_btm_config
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wmi_unified_send_btm_config(wmi_unified_t wmi_handle,
+				       struct wmi_btm_config *params);
+
+/**
+ * wmi_unified_send_bss_load_config() - Send bss load trigger params to fw
+ * @wmi_handle:  wmi handle
+ * @params: pointer to wmi_bss_load_config
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wmi_unified_send_bss_load_config(wmi_unified_t wmi_handle,
+					    struct wmi_bss_load_config *params);
+
+/**
+ * wmi_unified_offload_11k_cmd() - send 11k offload command
+ * @wmi_handle: wmi handle
+ * @params: 11k offload params
+ *
+ * This function passes the 11k offload command params to FW
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_offload_11k_cmd(wmi_unified_t wmi_handle,
+				       struct wmi_11k_offload_params *params);
+/**
+ * wmi_unified_invoke_neighbor_report_cmd() - send invoke neighbor report cmd
+ * @wmi_handle: wmi handle
+ * @params: invoke neighbor report params
+ *
+ * This function passes the invoke neighbor report command to fw
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_invoke_neighbor_report_cmd(
+			wmi_unified_t wmi_handle,
+			struct wmi_invoke_neighbor_report_params *params);
+
+/**
+ * wmi_unified_get_roam_scan_ch_list() - send roam scan channel list get cmd
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ *
+ * This function sends roam scan channel list get command to firmware.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_get_roam_scan_ch_list(wmi_unified_t wmi_handle,
+					     uint8_t vdev_id);
+
+#endif /* _WMI_UNIFIED_ROAM_API_H_ */

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

@@ -0,0 +1,790 @@
+/*
+ * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file contains the API definitions for the ROAMING WMI APIs.
+ */
+
+#ifndef _WMI_UNIFIED_ROAM_PARAM_H_
+#define _WMI_UNIFIED_ROAM_PARAM_H_
+
+#include <wlan_blm_public_struct.h>
+
+/**
+ * struct gateway_update_req_param - gateway parameter update request
+ * @request_id: request id
+ * @vdev_id: vdev id
+ * @max_retries: Max ARP/NS retry attempts
+ * @timeout: Retry interval
+ * @ipv4_addr_type: on ipv4 network
+ * @ipv6_addr_type: on ipv6 network
+ * @gw_mac_addr: gateway mac addr
+ * @ipv4_addr: ipv4 addr
+ * @ipv6_addr: ipv6 addr
+ */
+struct gateway_update_req_param {
+	uint32_t     request_id;
+	uint32_t     vdev_id;
+	uint32_t     max_retries;
+	uint32_t     timeout;
+	uint32_t     ipv4_addr_type;
+	uint32_t     ipv6_addr_type;
+	struct qdf_mac_addr  gw_mac_addr;
+	uint8_t      ipv4_addr[QDF_IPV4_ADDR_SIZE];
+	uint8_t      ipv6_addr[QDF_IPV6_ADDR_SIZE];
+};
+
+/**
+ * struct rssi_monitor_param - rssi monitoring
+ * @request_id: request id
+ * @vdev_id: vdev id
+ * @min_rssi: minimum rssi
+ * @max_rssi: maximum rssi
+ * @control: flag to indicate start or stop
+ */
+struct rssi_monitor_param {
+	uint32_t request_id;
+	uint32_t vdev_id;
+	int8_t   min_rssi;
+	int8_t   max_rssi;
+	bool     control;
+};
+
+/**
+ * struct roam_offload_scan_rssi_params - structure containing
+ *              parameters for roam offload scan based on RSSI
+ * @rssi_thresh: rssi threshold
+ * @rssi_thresh_diff: difference in rssi threshold
+ * @hi_rssi_scan_max_count: 5G scan max count
+ * @hi_rssi_scan_rssi_delta: 5G scan rssi change threshold value
+ * @hi_rssi_scan_rssi_ub: 5G scan upper bound
+ * @raise_rssi_thresh_5g: flag to determine penalty and boost thresholds
+ * @vdev_id: vdev id
+ * @penalty_threshold_5g: RSSI threshold below which 5GHz RSSI is penalized
+ * @boost_threshold_5g: RSSI threshold above which 5GHz RSSI is favored
+ * @raise_factor_5g: factor by which 5GHz RSSI is boosted
+ * @drop_factor_5g: factor by which 5GHz RSSI is penalized
+ * @max_raise_rssi_5g: maximum boost that can be applied to a 5GHz RSSI
+ * @max_drop_rssi_5g: maximum penalty that can be applied to a 5GHz RSSI
+ * @good_rssi_threshold: RSSI below which roam is kicked in by background
+ *                       scan although rssi is still good
+ * @roam_earlystop_thres_min: Minimum RSSI threshold value for early stop,
+ *                            unit is dB above NF
+ * @roam_earlystop_thres_max: Maximum RSSI threshold value for early stop,
+ *                            unit is dB above NF
+ * @dense_rssi_thresh_offset: dense roam RSSI threshold difference
+ * @dense_min_aps_cnt: dense roam minimum APs
+ * @initial_dense_status: dense status detected by host
+ * @traffic_threshold: dense roam RSSI threshold
+ * @bg_scan_bad_rssi_thresh: Bad RSSI threshold to perform bg scan
+ * @roam_bad_rssi_thresh_offset_2g: Offset from Bad RSSI threshold for 2G
+ *                                  to 5G Roam
+ * @bg_scan_client_bitmap: Bitmap used to identify the client scans to snoop
+ * @flags: Flags for Background Roaming
+ *	Bit 0 : BG roaming enabled when we connect to 2G AP only and roaming
+ *	        to 5G AP only.
+ *	Bit 1-31: Reserved
+ */
+struct roam_offload_scan_rssi_params {
+	int8_t rssi_thresh;
+	uint8_t rssi_thresh_diff;
+	uint32_t hi_rssi_scan_max_count;
+	uint32_t hi_rssi_scan_rssi_delta;
+	int32_t hi_rssi_scan_rssi_ub;
+	int raise_rssi_thresh_5g;
+	uint8_t vdev_id;
+	uint32_t penalty_threshold_5g;
+	uint32_t boost_threshold_5g;
+	uint8_t raise_factor_5g;
+	uint8_t drop_factor_5g;
+	int max_raise_rssi_5g;
+	int max_drop_rssi_5g;
+	uint32_t good_rssi_threshold;
+	uint32_t roam_earlystop_thres_min;
+	uint32_t roam_earlystop_thres_max;
+	int dense_rssi_thresh_offset;
+	int dense_min_aps_cnt;
+	int initial_dense_status;
+	int traffic_threshold;
+	int32_t rssi_thresh_offset_5g;
+	int8_t bg_scan_bad_rssi_thresh;
+	uint8_t roam_bad_rssi_thresh_offset_2g;
+	uint32_t bg_scan_client_bitmap;
+	uint32_t flags;
+};
+
+/**
+ * struct roam_scan_period_params - Roam scan period parameters
+ * @vdev_id: Vdev for which the scan period parameters are sent
+ * @scan_period: Opportunistic scan runs on a timer for scan_period
+ * @scan_age: Duration after which the scan entries are to be aged out
+ * @roam_scan_inactivity_time: inactivity monitoring time in ms for which the
+ * device is considered to be inactive
+ * @roam_inactive_data_packet_count: Maximum allowed data packets count during
+ * roam_scan_inactivity_time.
+ * @roam_scan_period_after_inactivity: Roam scan period in ms after device is
+ * in inactive state.
+ * @full_scan_period: Full scan period is the idle period in seconds
+ * between two successive full channel roam scans.
+ */
+struct roam_scan_period_params {
+	uint32_t vdev_id;
+	uint32_t scan_period;
+	uint32_t scan_age;
+	uint32_t roam_scan_inactivity_time;
+	uint32_t roam_inactive_data_packet_count;
+	uint32_t roam_scan_period_after_inactivity;
+	uint32_t full_scan_period;
+};
+
+/**
+ * struct wmi_mawc_roam_params - Motion Aided wireless connectivity params
+ * @vdev_id: VDEV on which the parameters should be applied
+ * @enable: MAWC roaming feature enable/disable
+ * @traffic_load_threshold: Traffic threshold in kBps for MAWC roaming
+ * @best_ap_rssi_threshold: AP RSSI Threshold for MAWC roaming
+ * @rssi_stationary_high_adjust: High RSSI adjustment value to suppress scan
+ * @rssi_stationary_low_adjust: Low RSSI adjustment value to suppress scan
+ */
+struct wmi_mawc_roam_params {
+	uint8_t vdev_id;
+	bool enable;
+	uint32_t traffic_load_threshold;
+	uint32_t best_ap_rssi_threshold;
+	uint8_t rssi_stationary_high_adjust;
+	uint8_t rssi_stationary_low_adjust;
+};
+
+#define MAX_SSID_ALLOWED_LIST    4
+#define MAX_BSSID_AVOID_LIST     16
+#define MAX_BSSID_FAVORED      16
+
+/**
+ * struct roam_scan_filter_params - Structure holding roaming scan
+ *                                  parameters
+ * @op_bitmap: bitmap to determine reason of roaming
+ * @vdev_id: vdev id
+ * @num_bssid_black_list: The number of BSSID's that we should avoid
+ *                        connecting to. It is like a blacklist of BSSID's.
+ * @num_ssid_white_list: The number of SSID profiles that are in the
+ *                       Whitelist. When roaming, we consider the BSSID's with
+ *                       this SSID also for roaming apart from the connected
+ *                       one's
+ * @num_bssid_preferred_list: Number of BSSID's which have a preference over
+ *                            others
+ * @bssid_avoid_list: Blacklist SSID's
+ * @ssid_allowed_list: Whitelist SSID's
+ * @bssid_favored: Favorable BSSID's
+ * @bssid_favored_factor: RSSI to be added to this BSSID to prefer it
+ * @lca_disallow_config_present: LCA [Last Connected AP] disallow config
+ *                               present
+ * @disallow_duration: How long LCA AP will be disallowed before it can be a
+ *                     roaming candidate again, in seconds
+ * @rssi_channel_penalization: How much RSSI will be penalized if candidate(s)
+ *                             are found in the same channel as disallowed
+ *                             AP's, in units of db
+ * @num_disallowed_aps: How many APs the target should maintain in its LCA
+ *                      list
+ * @delta_rssi: (dB units) when AB in RSSI blacklist improved by at least
+ *              delta_rssi,it will be removed from blacklist
+ *
+ * This structure holds all the key parameters related to
+ * initial connection and roaming connections.
+ */
+
+struct roam_scan_filter_params {
+	uint32_t op_bitmap;
+	uint8_t vdev_id;
+	uint32_t num_bssid_black_list;
+	uint32_t num_ssid_white_list;
+	uint32_t num_bssid_preferred_list;
+	struct qdf_mac_addr bssid_avoid_list[MAX_BSSID_AVOID_LIST];
+	struct mac_ssid ssid_allowed_list[MAX_SSID_ALLOWED_LIST];
+	struct qdf_mac_addr bssid_favored[MAX_BSSID_FAVORED];
+	uint8_t bssid_favored_factor[MAX_BSSID_FAVORED];
+	uint8_t lca_disallow_config_present;
+	uint32_t disallow_duration;
+	uint32_t rssi_channel_penalization;
+	uint32_t num_disallowed_aps;
+	uint32_t num_rssi_rejection_ap;
+	struct reject_ap_config_params
+				rssi_rejection_ap[MAX_RSSI_AVOID_BSSID_LIST];
+	uint32_t delta_rssi;
+};
+
+#define WMI_CFG_VALID_CHANNEL_LIST_LEN    100
+/* Occupied channel list remains static */
+#define WMI_CHANNEL_LIST_STATIC                   1
+/* Occupied channel list can be learnt after init */
+#define WMI_CHANNEL_LIST_DYNAMIC_INIT             2
+/* Occupied channel list can be learnt after flush */
+#define WMI_CHANNEL_LIST_DYNAMIC_FLUSH            3
+/* Occupied channel list can be learnt after update */
+#define WMI_CHANNEL_LIST_DYNAMIC_UPDATE           4
+
+/**
+ * struct plm_req_params - plm req parameter
+ * @diag_token: Dialog token
+ * @meas_token: measurement token
+ * @num_bursts: total number of bursts
+ * @burst_int: burst interval in seconds
+ * @meas_duration:in TU's,STA goes off-ch
+ * @burst_len: no of times the STA should cycle through PLM ch list
+ * @desired_tx_pwr: desired tx power
+ * @mac_addr: MC dest addr
+ * @plm_num_ch: channel numbers
+ * @plm_ch_freq_list: channel frequency list
+ * @vdev_id: vdev id
+ * @enable:  enable/disable
+ */
+struct plm_req_params {
+	uint16_t diag_token;
+	uint16_t meas_token;
+	uint16_t num_bursts;
+	uint16_t burst_int;
+	uint16_t meas_duration;
+	/* no of times the STA should cycle through PLM ch list */
+	uint8_t burst_len;
+	int8_t desired_tx_pwr;
+	struct qdf_mac_addr mac_addr;
+	/* no of channels */
+	uint8_t plm_num_ch;
+	/* channel frequency list */
+	uint32_t plm_ch_freq_list[WMI_CFG_VALID_CHANNEL_LIST_LEN];
+	uint8_t vdev_id;
+	bool enable;
+};
+
+/**
+ * struct ap_profile - Structure ap profile to match candidate
+ * @flags: flags
+ * @rssi_threshold: the value of the the candidate AP should higher by this
+ *                  threshold than the rssi of the currrently associated AP
+ * @ssid: ssid vlaue to be matched
+ * @rsn_authmode: security params to be matched
+ * @rsn_ucastcipherset: unicast cipher set
+ * @rsn_mcastcipherset: mcast/group cipher set
+ * @rsn_mcastmgmtcipherset: mcast/group management frames cipher set
+ * @rssi_abs_thresh: the value of the candidate AP should higher than this
+ *                   absolute RSSI threshold. Zero means no absolute minimum
+ *                   RSSI is required. units are the offset from the noise
+ *                   floor in dB
+ */
+struct ap_profile {
+	uint32_t flags;
+	uint32_t rssi_threshold;
+	struct mac_ssid  ssid;
+	uint32_t rsn_authmode;
+	uint32_t rsn_ucastcipherset;
+	uint32_t rsn_mcastcipherset;
+	uint32_t rsn_mcastmgmtcipherset;
+	uint32_t rssi_abs_thresh;
+};
+
+/**
+ * struct rssi_scoring - rssi scoring param to sortlist selected AP
+ * @best_rssi_threshold: Roamable AP RSSI equal or better than this threshold,
+ *                      full rssi score 100. Units in dBm.
+ * @good_rssi_threshold: Below threshold, scoring linear percentage between
+ *                      rssi_good_pnt and 100. Units in dBm.
+ * @bad_rssi_threshold: Between good and bad rssi threshold, scoring linear
+ *                      % between rssi_bad_pcnt and rssi_good_pct in dBm.
+ * @good_rssi_pcnt: Used to assigned scoring percentage of each slot between
+ *                 best to good rssi threshold. Units in percentage.
+ * @bad_rssi_pcnt: Used to assigned scoring percentage of each slot between good
+ *                to bad rssi threshold. Unites in percentage.
+ * @good_bucket_size : bucket size of slot in good zone
+ * @bad_bucket_size : bucket size of slot in bad zone
+ * @rssi_pref_5g_rssi_thresh: Below rssi threshold, 5G AP have given preference
+ *                           of band percentage. Units in dBm.
+ */
+struct rssi_scoring {
+	int32_t best_rssi_threshold;
+	int32_t good_rssi_threshold;
+	int32_t  bad_rssi_threshold;
+	uint32_t good_rssi_pcnt;
+	uint32_t bad_rssi_pcnt;
+	uint32_t good_bucket_size;
+	uint32_t bad_bucket_size;
+	int32_t  rssi_pref_5g_rssi_thresh;
+};
+
+/**
+ * struct param_slot_scoring - define % score for differents slots for a
+ *                             scoring param.
+ * @num_slot: number of slots in which the param will be divided.
+ *           Max 15. index 0 is used for 'not_present. Num_slot will
+ *           equally divide 100. e.g, if num_slot = 4 slot 0 = 0-25%, slot
+ *           1 = 26-50% slot 2 = 51-75%, slot 3 = 76-100%
+ * @score_pcnt3_to_0: Conatins score percentage for slot 0-3
+ *             BITS 0-7   :- the scoring pcnt when not present
+ *             BITS 8-15  :- SLOT_1
+ *             BITS 16-23 :- SLOT_2
+ *             BITS 24-31 :- SLOT_3
+ * @score_pcnt7_to_4: Conatins score percentage for slot 4-7
+ *             BITS 0-7   :- SLOT_4
+ *             BITS 8-15  :- SLOT_5
+ *             BITS 16-23 :- SLOT_6
+ *             BITS 24-31 :- SLOT_7
+ * @score_pcnt11_to_8: Conatins score percentage for slot 8-11
+ *             BITS 0-7   :- SLOT_8
+ *             BITS 8-15  :- SLOT_9
+ *             BITS 16-23 :- SLOT_10
+ *             BITS 24-31 :- SLOT_11
+ * @score_pcnt15_to_12: Conatins score percentage for slot 12-15
+ *             BITS 0-7   :- SLOT_12
+ *             BITS 8-15  :- SLOT_13
+ *             BITS 16-23 :- SLOT_14
+ *             BITS 24-31 :- SLOT_15
+ */
+struct param_slot_scoring {
+	uint32_t num_slot;
+	uint32_t score_pcnt3_to_0;
+	uint32_t score_pcnt7_to_4;
+	uint32_t score_pcnt11_to_8;
+	uint32_t score_pcnt15_to_12;
+};
+
+/**
+ * struct scoring_param - scoring param to sortlist selected AP
+ * @disable_bitmap: Each bit will be either allow(0)/disallow(1) to
+ *                 considered the roam score param.
+ * @rssi_weightage: RSSI weightage out of total score in %
+ * @ht_weightage: HT weightage out of total score in %.
+ * @vht_weightage: VHT weightage out of total score in %.
+ * @he_weightaget: 11ax weightage out of total score in %.
+ * @bw_weightage: Bandwidth weightage out of total score in %.
+ * @band_weightage: Band(2G/5G) weightage out of total score in %.
+ * @nss_weightage: NSS(1x1 / 2x2)weightage out of total score in %.
+ * @esp_qbss_weightage: ESP/QBSS weightage out of total score in %.
+ * @beamforming_weightage: Beamforming weightage out of total score in %.
+ * @pcl_weightage: PCL weightage out of total score in %.
+ * @oce_wan_weightage OCE WAN metrics weightage out of total score in %.
+ * @oce_ap_tx_pwr_weightage: OCE AP TX power score in %
+ * @oce_subnet_id_weightage: OCE subnet id score in %
+ * @bw_index_score: channel BW scoring percentage information.
+ *                 BITS 0-7   :- It contains scoring percentage of 20MHz   BW
+ *                 BITS 8-15  :- It contains scoring percentage of 40MHz   BW
+ *                 BITS 16-23 :- It contains scoring percentage of 80MHz   BW
+ *                 BITS 24-31 :- It contains scoring percentage of 1600MHz BW
+ *                 The value of each index must be 0-100
+ * @band_index_score: band scording percentage information.
+ *                   BITS 0-7   :- It contains scoring percentage of 2G
+ *                   BITS 8-15  :- It contains scoring percentage of 5G
+ *                   BITS 16-23 :- reserved
+ *                   BITS 24-31 :- reserved
+ *                   The value of each index must be 0-100
+ * @nss_index_score: NSS scoring percentage information.
+ *                  BITS 0-7   :- It contains scoring percentage of 1x1
+ *                  BITS 8-15  :- It contains scoring percentage of 2x2
+ *                  BITS 16-23 :- It contains scoring percentage of 3x3
+ *                  BITS 24-31 :- It contains scoring percentage of 4x4
+ *                  The value of each index must be 0-100
+ * @roam_score_delta: delta value expected over the roam score of the candidate
+ * ap over the roam score of the current ap
+ * @roam_trigger_bitmap: bitmap of roam triggers on which roam_score_delta
+ * will be applied
+ * @vendor_roam_score_algorithm: Prefered algorithm for roam candidate selection
+ * @cand_min_roam_score_delta: candidate min roam score delta value
+ * @rssi_scoring: RSSI scoring information.
+ * @esp_qbss_scoring: ESP/QBSS scoring percentage information
+ * @oce_wan_scoring: OCE WAN metrics percentage information
+ */
+struct scoring_param {
+	uint32_t disable_bitmap;
+	int32_t rssi_weightage;
+	int32_t ht_weightage;
+	int32_t vht_weightage;
+	int32_t he_weightage;
+	int32_t bw_weightage;
+	int32_t band_weightage;
+	int32_t nss_weightage;
+	int32_t esp_qbss_weightage;
+	int32_t beamforming_weightage;
+	int32_t pcl_weightage;
+	int32_t oce_wan_weightage;
+	uint32_t oce_ap_tx_pwr_weightage;
+	uint32_t oce_subnet_id_weightage;
+	uint32_t bw_index_score;
+	uint32_t band_index_score;
+	uint32_t nss_index_score;
+	uint32_t roam_score_delta;
+	uint32_t roam_trigger_bitmap;
+	uint32_t vendor_roam_score_algorithm;
+	uint32_t cand_min_roam_score_delta;
+	struct rssi_scoring rssi_scoring;
+	struct param_slot_scoring esp_qbss_scoring;
+	struct param_slot_scoring oce_wan_scoring;
+};
+
+/*
+ * Currently roam score delta value and min rssi values are sent
+ * for 2 triggers
+ */
+#define NUM_OF_ROAM_TRIGGERS 2
+#define IDLE_ROAM_TRIGGER 0
+#define BTM_ROAM_TRIGGER  1
+
+#define DEAUTH_MIN_RSSI 0
+#define BMISS_MIN_RSSI  1
+
+/**
+ * enum roam_trigger_reason - Reason for triggering roam
+ * ROAM_TRIGGER_REASON_NONE: Roam trigger reason none
+ * ROAM_TRIGGER_REASON_PER:  Roam triggered due to packet error
+ * ROAM_TRIGGER_REASON_BMISS: Roam triggered due to beacon miss
+ * ROAM_TRIGGER_REASON_LOW_RSSI: Roam triggered due to low RSSI of current
+ * connected AP.
+ * ROAM_TRIGGER_REASON_HIGH_RSSI: Roam triggered because sta is connected to
+ * a AP in 2.4GHz band and a better 5GHz AP is available
+ * ROAM_TRIGGER_REASON_PERIODIC: Roam triggered as better AP was found during
+ * periodic roam scan.
+ * ROAM_TRIGGER_REASON_MAWC: Motion Aided WiFi Connectivity triggered roam.
+ * ROAM_TRIGGER_REASON_DENSE: Roaming triggered due to dense environment
+ * detected.
+ * ROAM_TRIGGER_REASON_BACKGROUND: Roam triggered due to current AP having
+ * poor rssi and scan candidate found in scan results provided by other
+ * scan clients.
+ * ROAM_TRIGGER_REASON_FORCED: Forced roam trigger.
+ * ROAM_TRIGGER_REASON_BTM: Roam triggered due to AP sent BTM query with
+ * Disassoc imminent bit set.
+ * ROAM_TRIGGER_REASON_UNIT_TEST: Roam triggered due to unit test command.
+ * ROAM_TRIGGER_REASON_BSS_LOAD: Roam triggered due to high channel utilization
+ * in the current connected channel
+ * ROAM_TRIGGER_REASON_DEAUTH: Roam triggered due to deauth received from the
+ * current connected AP.
+ * ROAM_TRIGGER_REASON_IDLE: Roam triggered due to inactivity of the device.
+ * ROAM_TRIGGER_REASON_STA_KICKOUT: Roam triggered due to sta kickout event.
+ * ROAM_TRIGGER_REASON_ESS_RSSI: Roam triggered due to ess rssi
+ * ROAM_TRIGGER_REASON_MAX: Maximum number of roam triggers
+ */
+enum roam_trigger_reason {
+	ROAM_TRIGGER_REASON_NONE = 0,
+	ROAM_TRIGGER_REASON_PER,
+	ROAM_TRIGGER_REASON_BMISS,
+	ROAM_TRIGGER_REASON_LOW_RSSI,
+	ROAM_TRIGGER_REASON_HIGH_RSSI,
+	ROAM_TRIGGER_REASON_PERIODIC,
+	ROAM_TRIGGER_REASON_MAWC,
+	ROAM_TRIGGER_REASON_DENSE,
+	ROAM_TRIGGER_REASON_BACKGROUND,
+	ROAM_TRIGGER_REASON_FORCED,
+	ROAM_TRIGGER_REASON_BTM,
+	ROAM_TRIGGER_REASON_UNIT_TEST,
+	ROAM_TRIGGER_REASON_BSS_LOAD,
+	ROAM_TRIGGER_REASON_DEAUTH,
+	ROAM_TRIGGER_REASON_IDLE,
+	ROAM_TRIGGER_REASON_STA_KICKOUT,
+	ROAM_TRIGGER_REASON_ESS_RSSI,
+	ROAM_TRIGGER_REASON_MAX,
+};
+
+/**
+ * struct roam_trigger_min_rssi - structure to hold minimum rssi value of
+ * candidate APs for each roam trigger
+ * @min_rssi: minimum RSSI of candidate AP for the trigger reason specified in
+ * trigger_id
+ * @trigger_reason: Roam trigger reason
+ */
+struct roam_trigger_min_rssi {
+	int32_t  min_rssi;
+	enum roam_trigger_reason trigger_reason;
+};
+
+/**
+ * struct roam_trigger_score_delta - structure to hold roam score delta value of
+ * candidate APs for each roam trigger
+ * @roam_score_delta: delta value in score of the candidate AP for the roam
+ * trigger mentioned in the trigger_id.
+ * @trigger_reason: Roam trigger reason
+ */
+struct roam_trigger_score_delta {
+	uint32_t roam_score_delta;
+	enum roam_trigger_reason trigger_reason;
+};
+
+/**
+ * struct ap_profile_params - ap profile params
+ * @vdev_id: vdev id
+ * @profile: ap profile to match candidate
+ * @param: scoring params to short candidate
+ * @min_rssi_params: Min RSSI values for different roam triggers
+ * @score_delta_params: Roam score delta values for different triggers
+ */
+struct ap_profile_params {
+	uint8_t vdev_id;
+	struct ap_profile profile;
+	struct scoring_param param;
+	struct roam_trigger_min_rssi min_rssi_params[NUM_OF_ROAM_TRIGGERS];
+	struct roam_trigger_score_delta score_delta_param[NUM_OF_ROAM_TRIGGERS];
+};
+
+/**
+ * struct wmi_roam_invoke_cmd - roam invoke command
+ * @vdev_id: vdev id
+ * @bssid: mac address
+ * @channel: channel
+ * @frame_len: frame length, includs mac header, fixed params and ies
+ * @frame_buf: buffer contaning probe response or beacon
+ * @is_same_bssid: flag to indicate if roaming is requested for same bssid
+ * @forced_roaming: Roam to any bssid in any ch (here bssid & ch is not given)
+ */
+struct wmi_roam_invoke_cmd {
+	uint32_t vdev_id;
+	uint8_t bssid[QDF_MAC_ADDR_SIZE];
+	uint32_t channel;
+	uint32_t frame_len;
+	uint8_t *frame_buf;
+	uint8_t is_same_bssid;
+	bool forced_roaming;
+};
+
+/**
+ * struct wmi_per_roam_config - per based roaming parameters
+ * @enable: if PER based roaming is enabled/disabled
+ * @tx_high_rate_thresh: high rate threshold at which PER based
+ *     roam will stop in tx path
+ * @rx_high_rate_thresh: high rate threshold at which PER based
+ *     roam will stop in rx path
+ * @tx_low_rate_thresh: rate below which traffic will be considered
+ *     for PER based roaming in Tx path
+ * @rx_low_rate_thresh: rate below which traffic will be considered
+ *     for PER based roaming in Tx path
+ * @tx_rate_thresh_percnt: % above which when traffic is below low_rate_thresh
+ *     will be considered for PER based scan in tx path
+ * @rx_rate_thresh_percnt: % above which when traffic is below low_rate_thresh
+ *     will be considered for PER based scan in rx path
+ * @per_rest_time: time for which PER based roam will wait once it
+ *     issues a roam scan.
+ * @tx_per_mon_time: Minimum time required to be considered as valid scenario
+ *     for PER based roam in tx path
+ * @rx_per_mon_time: Minimum time required to be considered as valid scenario
+ *     for PER based roam in rx path
+ * @min_candidate_rssi: Minimum RSSI threshold for candidate AP to be used for
+ *     PER based roaming
+ */
+struct wmi_per_roam_config {
+	uint32_t enable;
+	uint32_t tx_high_rate_thresh;
+	uint32_t rx_high_rate_thresh;
+	uint32_t tx_low_rate_thresh;
+	uint32_t rx_low_rate_thresh;
+	uint32_t tx_rate_thresh_percnt;
+	uint32_t rx_rate_thresh_percnt;
+	uint32_t per_rest_time;
+	uint32_t tx_per_mon_time;
+	uint32_t rx_per_mon_time;
+	uint32_t min_candidate_rssi;
+};
+
+/**
+ * struct wmi_per_roam_config_req: PER based roaming config request
+ * @vdev_id: vdev id on which config needs to be set
+ * @per_config: PER config
+ */
+struct wmi_per_roam_config_req {
+	uint8_t vdev_id;
+	struct wmi_per_roam_config per_config;
+};
+
+/**
+ * struct wmi_limit_off_chan_param - limit off channel parameters
+ * @vdev_id: vdev id
+ * @status: status of the command (enable/disable)
+ * @max_offchan_time: max off channel time
+ * @rest_time: home channel time
+ * @skip_dfs_chans: skip dfs channels during scan
+ */
+struct wmi_limit_off_chan_param {
+	uint32_t vdev_id;
+	bool status;
+	uint32_t max_offchan_time;
+	uint32_t rest_time;
+	bool skip_dfs_chans;
+};
+
+#define WMI_MAX_HLP_IE_LEN 2048
+/**
+ * struct hlp_params - HLP info params
+ * @vdev_id: vdev id
+ * @hlp_ie_len: HLP IE length
+ * @hlp_ie: HLP IE
+ */
+struct hlp_params {
+	uint8_t vdev_id;
+	uint32_t  hlp_ie_len;
+	uint8_t hlp_ie[WMI_MAX_HLP_IE_LEN];
+};
+
+/**
+ * struct wmi_btm_config - BSS Transition Management offload params
+ * @vdev_id: VDEV on which the parameters should be applied
+ * @btm_offload_config: BTM config
+ * @btm_solicited_timeout: Timeout value for waiting BTM request
+ * @btm_max_attempt_cnt: Maximum attempt for sending BTM query to ESS
+ * @btm_sticky_time: Stick time after roaming to new AP by BTM
+ * @disassoc_timer_threshold: threshold value till which the firmware can
+ * wait before triggering the roam scan after receiving the disassoc iminent
+ * @btm_query_bitmask: bitmask to btm query with candidate list
+ * @btm_candidate_min_score: Minimum score of the AP to consider it as a
+ * candidate if the roam trigger is BTM kickout.
+ */
+struct wmi_btm_config {
+	uint8_t vdev_id;
+	uint32_t btm_offload_config;
+	uint32_t btm_solicited_timeout;
+	uint32_t btm_max_attempt_cnt;
+	uint32_t btm_sticky_time;
+	uint32_t disassoc_timer_threshold;
+	uint32_t btm_query_bitmask;
+	uint32_t btm_candidate_min_score;
+};
+
+/**
+ * struct wmi_bss_load_config - BSS load trigger parameters
+ * @vdev_id: VDEV on which the parameters should be applied
+ * @bss_load_threshold: BSS load threshold after which roam scan should trigger
+ * @bss_load_sample_time: Time duration in milliseconds for which the bss load
+ * trigger needs to be enabled
+ * @rssi_threshold_5ghz: RSSI threshold of the current connected AP below which
+ * roam should be triggered if bss load threshold exceeds the configured value.
+ * This value is applicable only when we are connected in 5GHz band.
+ * @rssi_threshold_24ghz: RSSI threshold of the current connected AP below which
+ * roam should be triggered if bss load threshold exceeds the configured value.
+ * This value is applicable only when we are connected in 2.4GHz band.
+ */
+struct wmi_bss_load_config {
+	uint32_t vdev_id;
+	uint32_t bss_load_threshold;
+	uint32_t bss_load_sample_time;
+	int32_t rssi_threshold_5ghz;
+	int32_t rssi_threshold_24ghz;
+};
+
+/**
+ * struct wmi_idle_roam_params - Idle roam trigger parameters
+ * @vdev_id: VDEV on which the parameters should be applied
+ * @enable: Enable/Disable Idle roaming
+ * @band: Connected AP band
+ * @conn_ap_rssi_delta: Rssi change of connected AP in dBm
+ * @conn_ap_min_rssi: If connected AP rssi is less than min rssi trigger roam
+ * @inactive_time: Connected AP idle time
+ * @data_pkt_count: Data packet count allowed during idle time
+ */
+struct wmi_idle_roam_params {
+	uint32_t vdev_id;
+	bool enable;
+	uint32_t band;
+	uint32_t conn_ap_rssi_delta;
+	int32_t conn_ap_min_rssi;
+	uint32_t inactive_time;
+	uint32_t data_pkt_count;
+};
+
+/**
+ * struct wmi_disconnect_roam_params - Emergency deauth/disconnect roam params
+ * @vdev_id: VDEV on which the parameters should be applied
+ * @enable: Enable or disable disconnect roaming.
+ */
+struct wmi_disconnect_roam_params {
+	uint32_t vdev_id;
+	bool enable;
+};
+
+/**
+ * struct wmi_roam_auth_status_params - WPA3 roam auth response status
+ * parameters
+ * @vdev_id: Vdev on which roam preauth is happening
+ * @preauth_status: Status of the Auth response.
+ *      IEEE80211_STATUS_SUCCESS(0) for success. Corresponding
+ *      IEEE80211 failure status code for failure.
+ *
+ * @bssid: Candidate BSSID
+ * @pmkid: PMKID derived for the auth
+ */
+struct wmi_roam_auth_status_params {
+	uint32_t vdev_id;
+	uint32_t preauth_status;
+	struct qdf_mac_addr bssid;
+	uint8_t pmkid[PMKID_LEN];
+};
+
+/**
+ * @time_offset: time offset after 11k offload command to trigger a neighbor
+ *	report request (in seconds)
+ * @low_rssi_offset: Offset from rssi threshold to trigger a neighbor
+ *	report request (in dBm)
+ * @bmiss_count_trigger: Number of beacon miss events to trigger neighbor
+ *	report request
+ * @per_threshold_offset: offset from PER threshold to trigger neighbor
+ *	report request (in %)
+ * @neighbor_report_cache_timeout: timeout after which new trigger can enable
+ *	sending of a neighbor report request (in seconds)
+ * @max_neighbor_report_req_cap: max number of neighbor report requests that
+ *	can be sent to the peer in the current session
+ * @ssid: Current connect SSID info
+ */
+struct wmi_11k_offload_neighbor_report_params {
+	uint32_t time_offset;
+	uint32_t low_rssi_offset;
+	uint32_t bmiss_count_trigger;
+	uint32_t per_threshold_offset;
+	uint32_t neighbor_report_cache_timeout;
+	uint32_t max_neighbor_report_req_cap;
+	struct mac_ssid ssid;
+};
+
+/**
+ * struct wmi_11k_offload_params - offload 11k features to FW
+ * @vdev_id: vdev id
+ * @offload_11k_bitmask: bitmask to specify offloaded features
+ *	B0: Neighbor Report Request offload
+ *	B1-B31: Reserved
+ * @neighbor_report_params: neighbor report offload params
+ */
+struct wmi_11k_offload_params {
+	uint32_t vdev_id;
+	uint32_t offload_11k_bitmask;
+	struct wmi_11k_offload_neighbor_report_params neighbor_report_params;
+};
+
+/**
+ * struct wmi_invoke_neighbor_report_params - Invoke neighbor report request
+ *	from IW to FW
+ * @vdev_id: vdev id
+ * @send_resp_to_host: bool to send response to host or not
+ * @ssid: ssid given from the IW command
+ */
+struct wmi_invoke_neighbor_report_params {
+	uint32_t vdev_id;
+	uint32_t send_resp_to_host;
+	struct mac_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;
+};
+
+#endif /* _WMI_UNIFIED_ROAM_PARAM_H_ */

+ 340 - 0
components/wmi/src/wmi_unified_roam_api.c

@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <osdep.h>
+#include <wmi.h>
+#include <wmi_unified_priv.h>
+#include <wmi_unified_roam_param.h>
+#include <wmi_unified_roam_api.h>
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+QDF_STATUS
+wmi_unified_set_gateway_params_cmd(wmi_unified_t wmi_handle,
+				   struct gateway_update_req_param *req)
+{
+	if (wmi_handle->ops->send_set_gateway_params_cmd)
+		return wmi_handle->ops->send_set_gateway_params_cmd(wmi_handle,
+								    req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+
+#ifdef FEATURE_RSSI_MONITOR
+QDF_STATUS
+wmi_unified_set_rssi_monitoring_cmd(wmi_unified_t wmi_handle,
+				    struct rssi_monitor_param *req)
+{
+	if (wmi_handle->ops->send_set_rssi_monitoring_cmd)
+		return wmi_handle->ops->send_set_rssi_monitoring_cmd(wmi_handle,
+								     req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* FEATURE_RSSI_MONITOR */
+
+QDF_STATUS wmi_unified_roam_scan_offload_rssi_thresh_cmd(
+		wmi_unified_t wmi_handle,
+		struct roam_offload_scan_rssi_params *roam_req)
+{
+	if (wmi_handle->ops->send_roam_scan_offload_rssi_thresh_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_rssi_thresh_cmd(
+				wmi_handle, roam_req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_mawc_params_cmd(
+			wmi_unified_t wmi_handle,
+			struct wmi_mawc_roam_params *params)
+{
+	if (wmi_handle->ops->send_roam_mawc_params_cmd)
+		return wmi_handle->ops->send_roam_mawc_params_cmd(wmi_handle,
+								  params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_unified_roam_scan_filter_cmd(wmi_unified_t wmi_handle,
+				 struct roam_scan_filter_params *roam_req)
+{
+	if (wmi_handle->ops->send_roam_scan_filter_cmd)
+		return wmi_handle->ops->send_roam_scan_filter_cmd(wmi_handle,
+								  roam_req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+#ifdef FEATURE_WLAN_ESE
+QDF_STATUS wmi_unified_plm_stop_cmd(wmi_unified_t wmi_handle,
+				    const struct plm_req_params *plm)
+{
+	if (wmi_handle->ops->send_plm_stop_cmd)
+		return wmi_handle->ops->send_plm_stop_cmd(wmi_handle, plm);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_plm_start_cmd(wmi_unified_t wmi_handle,
+				     const struct plm_req_params *plm)
+{
+	if (wmi_handle->ops->send_plm_start_cmd)
+		return wmi_handle->ops->send_plm_start_cmd(wmi_handle, plm);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* FEATURE_WLAN_ESE */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS wmi_unified_set_ric_req_cmd(wmi_unified_t wmi_handle, void *msg,
+				       uint8_t is_add_ts)
+{
+	if (wmi_handle->ops->send_set_ric_req_cmd)
+		return wmi_handle->ops->send_set_ric_req_cmd(wmi_handle, msg,
+							     is_add_ts);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_synch_complete_cmd(wmi_unified_t wmi_handle,
+					       uint8_t vdev_id)
+{
+	if (wmi_handle->ops->send_process_roam_synch_complete_cmd)
+		return wmi_handle->ops->send_process_roam_synch_complete_cmd(
+				wmi_handle, vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_invoke_cmd(wmi_unified_t wmi_handle,
+				       struct wmi_roam_invoke_cmd *roaminvoke,
+				       uint32_t ch_hz)
+{
+	if (wmi_handle->ops->send_roam_invoke_cmd)
+		return wmi_handle->ops->send_roam_invoke_cmd(wmi_handle,
+							     roaminvoke,
+							     ch_hz);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_unified_send_disconnect_roam_params(wmi_unified_t wmi_handle,
+					struct wmi_disconnect_roam_params *req)
+{
+	if (wmi_handle->ops->send_disconnect_roam_params)
+		return wmi_handle->ops->send_disconnect_roam_params(wmi_handle,
+								    req);
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_unified_send_idle_roam_params(wmi_unified_t wmi_handle,
+				  struct wmi_idle_roam_params *req)
+{
+	if (wmi_handle->ops->send_idle_roam_params)
+		return wmi_handle->ops->send_idle_roam_params(wmi_handle,
+							      req);
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_unified_send_roam_preauth_status(wmi_unified_t wmi_handle,
+				     struct wmi_roam_auth_status_params *params)
+{
+	if (wmi_handle->ops->send_roam_preauth_status)
+		return wmi_handle->ops->send_roam_preauth_status(wmi_handle,
+								 params);
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+QDF_STATUS wmi_unified_roam_scan_offload_mode_cmd(
+				wmi_unified_t wmi_handle,
+				wmi_start_scan_cmd_fixed_param *scan_cmd_fp,
+				struct roam_offload_scan_params *roam_req)
+{
+	if (wmi_handle->ops->send_roam_scan_offload_mode_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_mode_cmd(
+				wmi_handle, scan_cmd_fp, roam_req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_send_roam_scan_offload_ap_cmd(
+				wmi_unified_t wmi_handle,
+				struct ap_profile_params *ap_profile)
+{
+	if (wmi_handle->ops->send_roam_scan_offload_ap_profile_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_ap_profile_cmd(
+				  wmi_handle, ap_profile);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_roam_scan_offload_cmd(wmi_unified_t wmi_handle,
+					     uint32_t command,
+					     uint32_t vdev_id)
+{
+	if (wmi_handle->ops->send_roam_scan_offload_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_cmd(wmi_handle,
+								   command,
+								   vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_unified_roam_scan_offload_scan_period(wmi_unified_t wmi_handle,
+					  struct roam_scan_period_params *param)
+{
+	if (wmi_handle->ops->send_roam_scan_offload_scan_period_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_scan_period_cmd(
+							wmi_handle, param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_unified_roam_scan_offload_chan_list_cmd(wmi_unified_t wmi_handle,
+					    uint8_t chan_count,
+					    uint32_t *chan_list,
+					    uint8_t list_type,
+					    uint32_t vdev_id)
+{
+	if (wmi_handle->ops->send_roam_scan_offload_chan_list_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_chan_list_cmd(
+					wmi_handle, chan_count, chan_list,
+					list_type, vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_unified_roam_scan_offload_rssi_change_cmd(wmi_unified_t wmi_handle,
+					      uint32_t vdev_id,
+					      int32_t rssi_change_thresh,
+					      uint32_t bcn_rssi_weight,
+					      uint32_t hirssi_delay_btw_scans)
+{
+	if (wmi_handle->ops->send_roam_scan_offload_rssi_change_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_rssi_change_cmd(
+				wmi_handle, vdev_id, rssi_change_thresh,
+				bcn_rssi_weight, hirssi_delay_btw_scans);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_unified_set_per_roam_config(wmi_unified_t wmi_handle,
+				struct wmi_per_roam_config_req *req_buf)
+{
+	if (wmi_handle->ops->send_per_roam_config_cmd)
+		return wmi_handle->ops->send_per_roam_config_cmd(wmi_handle,
+								 req_buf);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_send_limit_off_chan_cmd(
+		wmi_unified_t wmi_handle,
+		struct wmi_limit_off_chan_param *limit_off_chan_param)
+{
+	if (wmi_handle->ops->send_limit_off_chan_cmd)
+		return wmi_handle->ops->send_limit_off_chan_cmd(wmi_handle,
+				limit_off_chan_param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+QDF_STATUS wmi_unified_roam_send_hlp_cmd(wmi_unified_t wmi_handle,
+					 struct hlp_params *req_buf)
+{
+	if (wmi_handle->ops->send_roam_scan_hlp_cmd)
+		return wmi_handle->ops->send_roam_scan_hlp_cmd(wmi_handle,
+							       req_buf);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* WLAN_FEATURE_FILS_SK */
+
+QDF_STATUS wmi_unified_send_btm_config(wmi_unified_t wmi_handle,
+				       struct wmi_btm_config *params)
+{
+	if (wmi_handle->ops->send_btm_config)
+		return wmi_handle->ops->send_btm_config(wmi_handle,
+							params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_send_bss_load_config(wmi_unified_t wmi_handle,
+					    struct wmi_bss_load_config *params)
+{
+	if (wmi_handle->ops->send_roam_bss_load_config)
+		return wmi_handle->ops->send_roam_bss_load_config(wmi_handle,
+								  params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+
+QDF_STATUS wmi_unified_offload_11k_cmd(wmi_unified_t wmi_handle,
+				       struct wmi_11k_offload_params *params)
+{
+	if (wmi_handle->ops->send_offload_11k_cmd)
+		return wmi_handle->ops->send_offload_11k_cmd(wmi_handle,
+							     params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_invoke_neighbor_report_cmd(
+			wmi_unified_t wmi_handle,
+			struct wmi_invoke_neighbor_report_params *params)
+{
+	if (wmi_handle->ops->send_invoke_neighbor_report_cmd)
+		return wmi_handle->ops->send_invoke_neighbor_report_cmd(
+				wmi_handle, params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_get_roam_scan_ch_list(wmi_unified_t wmi_handle,
+					     uint8_t vdev_id)
+{
+	if (wmi_handle->ops->send_roam_scan_ch_list_req_cmd)
+		return wmi_handle->ops->send_roam_scan_ch_list_req_cmd(
+				wmi_handle, vdev_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS wmi_unified_set_roam_triggers(wmi_unified_t wmi_handle,
+					 struct 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);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif

+ 2816 - 0
components/wmi/src/wmi_unified_roam_tlv.c

@@ -0,0 +1,2816 @@
+/*
+ * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: Implement API's specific to roaming component.
+ */
+
+#include <wmi_unified_priv.h>
+#include <wmi_unified_roam_api.h>
+#include "wmi.h"
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+/**
+ * send_set_gateway_params_cmd_tlv() - set gateway parameters
+ * @wmi_handle: wmi handle
+ * @req: gateway parameter update request structure
+ *
+ * This function reads the incoming @req and fill in the destination
+ * WMI structure and sends down the gateway configs down to the firmware
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle,
+				struct gateway_update_req_param *req)
+{
+	wmi_roam_subnet_change_config_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS ret;
+	int len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_roam_subnet_change_config_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_roam_subnet_change_config_fixed_param));
+
+	cmd->vdev_id = req->vdev_id;
+	qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr,
+		     QDF_IPV4_ADDR_SIZE);
+	qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr,
+		     QDF_IPV6_ADDR_SIZE);
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes,
+				   &cmd->inet_gw_mac_addr);
+	cmd->max_retries = req->max_retries;
+	cmd->timeout = req->timeout;
+	cmd->num_skip_subnet_change_detection_bssid_list = 0;
+	cmd->flag = 0;
+	if (req->ipv4_addr_type)
+		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag);
+
+	if (req->ipv6_addr_type)
+		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag);
+
+	wmi_mtrace(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Failed to send gw config parameter to fw, ret: %d",
+			 ret);
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+void wmi_lfr_subnet_detection_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_set_gateway_params_cmd = send_set_gateway_params_cmd_tlv;
+}
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+
+#ifdef FEATURE_RSSI_MONITOR
+/**
+ * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring
+ * @wmi_handle: wmi handle
+ * @req: rssi monitoring request structure
+ *
+ * This function reads the incoming @req and fill in the destination
+ * WMI structure and send down the rssi monitoring configs down to the firmware
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle,
+					struct rssi_monitor_param *req)
+{
+	wmi_rssi_breach_monitor_config_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS ret;
+	uint32_t len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_rssi_breach_monitor_config_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_rssi_breach_monitor_config_fixed_param));
+
+	cmd->vdev_id = req->vdev_id;
+	cmd->request_id = req->request_id;
+	cmd->lo_rssi_reenable_hysteresis = 0;
+	cmd->hi_rssi_reenable_histeresis = 0;
+	cmd->min_report_interval = 0;
+	cmd->max_num_report = 1;
+	if (req->control) {
+		/* enable one threshold for each min/max */
+		cmd->enabled_bitmap = 0x09;
+		cmd->low_rssi_breach_threshold[0] = req->min_rssi;
+		cmd->hi_rssi_breach_threshold[0] = req->max_rssi;
+	} else {
+		cmd->enabled_bitmap = 0;
+		cmd->low_rssi_breach_threshold[0] = 0;
+		cmd->hi_rssi_breach_threshold[0] = 0;
+	}
+
+	wmi_mtrace(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID");
+		wmi_buf_free(buf);
+	}
+
+	WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW");
+
+	return ret;
+}
+
+void wmi_rssi_monitor_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_set_rssi_monitoring_cmd = send_set_rssi_monitoring_cmd_tlv;
+}
+#endif /* FEATURE_RSSI_MONITOR */
+
+/**
+ * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload
+ *                                                rssi threashold
+ * @wmi_handle: wmi handle
+ * @roam_req:   Roaming request buffer
+ *
+ * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(
+		wmi_unified_t wmi_handle,
+		struct roam_offload_scan_rssi_params *roam_req)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp;
+	wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL;
+	wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL;
+	wmi_roam_dense_thres_param *dense_thresholds = NULL;
+	wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL;
+
+	len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
+	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
+	len += sizeof(wmi_roam_scan_extended_threshold_param);
+	len += WMI_TLV_HDR_SIZE;
+	len += sizeof(wmi_roam_earlystop_rssi_thres_param);
+	len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/
+	len += sizeof(wmi_roam_dense_thres_param);
+	len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/
+	len += sizeof(wmi_roam_bg_scan_roaming_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	rssi_threshold_fp =
+		(wmi_roam_scan_rssi_threshold_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header,
+		      WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param,
+		      WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_scan_rssi_threshold_fixed_param));
+	/* fill in threshold values */
+	rssi_threshold_fp->vdev_id = roam_req->vdev_id;
+	rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh;
+	rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff;
+	rssi_threshold_fp->hirssi_scan_max_count =
+			roam_req->hi_rssi_scan_max_count;
+	rssi_threshold_fp->hirssi_scan_delta =
+			roam_req->hi_rssi_scan_rssi_delta;
+	rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub;
+	rssi_threshold_fp->rssi_thresh_offset_5g =
+		roam_req->rssi_thresh_offset_5g;
+
+	buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_scan_extended_threshold_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	ext_thresholds = (wmi_roam_scan_extended_threshold_param *)buf_ptr;
+
+	ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g;
+	if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT)
+		ext_thresholds->boost_threshold_5g =
+					roam_req->boost_threshold_5g;
+
+	ext_thresholds->boost_algorithm_5g =
+		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
+	ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g;
+	ext_thresholds->penalty_algorithm_5g =
+		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
+	ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g;
+	ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g;
+	ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g;
+	ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold;
+
+	WMITLV_SET_HDR(&ext_thresholds->tlv_header,
+		WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param,
+		WMITLV_GET_STRUCT_TLVLEN
+			(wmi_roam_scan_extended_threshold_param));
+	buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param);
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_earlystop_rssi_thres_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *)buf_ptr;
+	early_stop_thresholds->roam_earlystop_thres_min =
+		roam_req->roam_earlystop_thres_min;
+	early_stop_thresholds->roam_earlystop_thres_max =
+		roam_req->roam_earlystop_thres_max;
+	WMITLV_SET_HDR(&early_stop_thresholds->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_roam_earlystop_rssi_thres_param));
+
+	buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_dense_thres_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	dense_thresholds = (wmi_roam_dense_thres_param *)buf_ptr;
+	dense_thresholds->roam_dense_rssi_thres_offset =
+			roam_req->dense_rssi_thresh_offset;
+	dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt;
+	dense_thresholds->roam_dense_traffic_thres =
+			roam_req->traffic_threshold;
+	dense_thresholds->roam_dense_status = roam_req->initial_dense_status;
+	WMITLV_SET_HDR(&dense_thresholds->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_dense_thres_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_dense_thres_param));
+
+	buf_ptr += sizeof(wmi_roam_dense_thres_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_bg_scan_roaming_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	bg_scan_params = (wmi_roam_bg_scan_roaming_param *)buf_ptr;
+	bg_scan_params->roam_bg_scan_bad_rssi_thresh =
+		roam_req->bg_scan_bad_rssi_thresh;
+	bg_scan_params->roam_bg_scan_client_bitmap =
+		roam_req->bg_scan_client_bitmap;
+	bg_scan_params->bad_rssi_thresh_offset_2g =
+		roam_req->roam_bad_rssi_thresh_offset_2g;
+	bg_scan_params->flags = roam_req->flags;
+	WMITLV_SET_HDR(&bg_scan_params->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_roam_bg_scan_roaming_param));
+
+	wmi_mtrace(WMI_ROAM_SCAN_RSSI_THRESHOLD, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_SCAN_RSSI_THRESHOLD);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d",
+			 status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle,
+		struct wmi_mawc_roam_params *params)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params;
+
+	len = sizeof(*wmi_roam_mawc_params);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	wmi_roam_mawc_params =
+		(wmi_roam_configure_mawc_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_configure_mawc_cmd_fixed_param));
+	wmi_roam_mawc_params->vdev_id = params->vdev_id;
+	if (params->enable)
+		wmi_roam_mawc_params->enable = 1;
+	else
+		wmi_roam_mawc_params->enable = 0;
+	wmi_roam_mawc_params->traffic_load_threshold =
+		params->traffic_load_threshold;
+	wmi_roam_mawc_params->best_ap_rssi_threshold =
+		params->best_ap_rssi_threshold;
+	wmi_roam_mawc_params->rssi_stationary_high_adjust =
+		params->rssi_stationary_high_adjust;
+	wmi_roam_mawc_params->rssi_stationary_low_adjust =
+		params->rssi_stationary_low_adjust;
+	WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"),
+		wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id,
+		wmi_roam_mawc_params->traffic_load_threshold,
+		wmi_roam_mawc_params->best_ap_rssi_threshold,
+		wmi_roam_mawc_params->rssi_stationary_high_adjust,
+		wmi_roam_mawc_params->rssi_stationary_low_adjust);
+
+	wmi_mtrace(WMI_ROAM_CONFIGURE_MAWC_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_CONFIGURE_MAWC_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d",
+			 status);
+		wmi_buf_free(buf);
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming
+ * @wmi_handle:     wmi handle
+ * @roam_req:       Request which contains the filters
+ *
+ * There are filters such as whitelist, blacklist and preferred
+ * list that need to be applied to the scan results to form the
+ * probable candidates for roaming.
+ *
+ * Return: Return success upon successfully passing the
+ *         parameters to the firmware, otherwise failure.
+ */
+static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle,
+				struct roam_scan_filter_params *roam_req)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	uint32_t i;
+	uint32_t len, blist_len = 0;
+	uint8_t *buf_ptr;
+	wmi_roam_filter_fixed_param *roam_filter;
+	uint8_t *bssid_src_ptr = NULL;
+	wmi_mac_addr *bssid_dst_ptr = NULL;
+	wmi_ssid *ssid_ptr = NULL;
+	uint32_t *bssid_preferred_factor_ptr = NULL;
+	wmi_roam_lca_disallow_config_tlv_param *blist_param;
+	wmi_roam_rssi_rejection_oce_config_param *rssi_rej;
+
+	len = sizeof(wmi_roam_filter_fixed_param);
+
+	len += WMI_TLV_HDR_SIZE;
+	if (roam_req->num_bssid_black_list)
+		len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr);
+	len += WMI_TLV_HDR_SIZE;
+	if (roam_req->num_ssid_white_list)
+		len += roam_req->num_ssid_white_list * sizeof(wmi_ssid);
+	len += 2 * WMI_TLV_HDR_SIZE;
+	if (roam_req->num_bssid_preferred_list) {
+		len += (roam_req->num_bssid_preferred_list *
+			sizeof(wmi_mac_addr));
+		len += roam_req->num_bssid_preferred_list * sizeof(uint32_t);
+	}
+	len += WMI_TLV_HDR_SIZE;
+	if (roam_req->lca_disallow_config_present) {
+		len += sizeof(*blist_param);
+		blist_len = sizeof(*blist_param);
+	}
+
+	len += WMI_TLV_HDR_SIZE;
+	if (roam_req->num_rssi_rejection_ap)
+		len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (u_int8_t *)wmi_buf_data(buf);
+	roam_filter = (wmi_roam_filter_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&roam_filter->tlv_header,
+		WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param));
+	/* fill in fixed values */
+	roam_filter->vdev_id = roam_req->vdev_id;
+	roam_filter->flags = 0;
+	roam_filter->op_bitmap = roam_req->op_bitmap;
+	roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list;
+	roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list;
+	roam_filter->num_bssid_preferred_list =
+			roam_req->num_bssid_preferred_list;
+	roam_filter->num_rssi_rejection_ap =
+			roam_req->num_rssi_rejection_ap;
+	roam_filter->delta_rssi = roam_req->delta_rssi;
+	buf_ptr += sizeof(wmi_roam_filter_fixed_param);
+
+	WMITLV_SET_HDR((buf_ptr),
+		WMITLV_TAG_ARRAY_FIXED_STRUC,
+		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)));
+	bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list;
+	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	for (i = 0; i < roam_req->num_bssid_black_list; i++) {
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr);
+		bssid_src_ptr += ATH_MAC_LEN;
+		bssid_dst_ptr++;
+	}
+	buf_ptr += WMI_TLV_HDR_SIZE +
+		(roam_req->num_bssid_black_list * sizeof(wmi_mac_addr));
+	WMITLV_SET_HDR((buf_ptr),
+		       WMITLV_TAG_ARRAY_FIXED_STRUC,
+		       (roam_req->num_ssid_white_list * sizeof(wmi_ssid)));
+	ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	for (i = 0; i < roam_req->num_ssid_white_list; i++) {
+		qdf_mem_copy(&ssid_ptr->ssid,
+			&roam_req->ssid_allowed_list[i].mac_ssid,
+			roam_req->ssid_allowed_list[i].length);
+		ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length;
+		ssid_ptr++;
+	}
+	buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list *
+							sizeof(wmi_ssid));
+	WMITLV_SET_HDR((buf_ptr),
+		WMITLV_TAG_ARRAY_FIXED_STRUC,
+		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)));
+	bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored;
+	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr,
+					   (wmi_mac_addr *)bssid_dst_ptr);
+		bssid_src_ptr += ATH_MAC_LEN;
+		bssid_dst_ptr++;
+	}
+	buf_ptr += WMI_TLV_HDR_SIZE +
+		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr));
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
+		(roam_req->num_bssid_preferred_list * sizeof(uint32_t)));
+	bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
+		*bssid_preferred_factor_ptr =
+			roam_req->bssid_favored_factor[i];
+		bssid_preferred_factor_ptr++;
+	}
+	buf_ptr += WMI_TLV_HDR_SIZE +
+		(roam_req->num_bssid_preferred_list * sizeof(uint32_t));
+
+	WMITLV_SET_HDR(buf_ptr,
+			WMITLV_TAG_ARRAY_STRUC, blist_len);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	if (roam_req->lca_disallow_config_present) {
+		blist_param =
+			(wmi_roam_lca_disallow_config_tlv_param *)buf_ptr;
+		WMITLV_SET_HDR(&blist_param->tlv_header,
+			WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param,
+			WMITLV_GET_STRUCT_TLVLEN(
+				wmi_roam_lca_disallow_config_tlv_param));
+
+		blist_param->disallow_duration = roam_req->disallow_duration;
+		blist_param->rssi_channel_penalization =
+				roam_req->rssi_channel_penalization;
+		blist_param->num_disallowed_aps = roam_req->num_disallowed_aps;
+		blist_param->disallow_lca_enable_source_bitmap =
+			(WMI_ROAM_LCA_DISALLOW_SOURCE_PER |
+			WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND);
+		buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param));
+	}
+
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_ARRAY_STRUC,
+		       (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej)));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) {
+		rssi_rej =
+		(wmi_roam_rssi_rejection_oce_config_param *)buf_ptr;
+
+		WMITLV_SET_HDR(&rssi_rej->tlv_header,
+		WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param,
+		WMITLV_GET_STRUCT_TLVLEN(wmi_roam_rssi_rejection_oce_config_param));
+
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(
+			roam_req->rssi_rejection_ap[i].bssid.bytes,
+			&rssi_rej->bssid);
+		rssi_rej->remaining_disallow_duration =
+			roam_req->rssi_rejection_ap[i].reject_duration;
+		rssi_rej->requested_rssi =
+			(int32_t)roam_req->rssi_rejection_ap[i].expected_rssi;
+		buf_ptr +=
+			(sizeof(wmi_roam_rssi_rejection_oce_config_param));
+	}
+
+	wmi_mtrace(WMI_ROAM_FILTER_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_FILTER_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d",
+			 status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * send_plm_stop_cmd_tlv() - plm stop request
+ * @wmi_handle: wmi handle
+ * @plm: plm request parameters
+ *
+ * This function request FW to stop PLM.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle,
+			  const struct plm_req_params *plm)
+{
+	wmi_vdev_plmreq_stop_cmd_fixed_param *cmd;
+	int32_t len;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	int ret;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *)wmi_buf_data(buf);
+
+	buf_ptr = (uint8_t *)cmd;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_vdev_plmreq_stop_cmd_fixed_param));
+
+	cmd->vdev_id = plm->vdev_id;
+
+	cmd->meas_token = plm->meas_token;
+	WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token);
+
+	wmi_mtrace(WMI_VDEV_PLMREQ_STOP_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_VDEV_PLMREQ_STOP_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_plm_start_cmd_tlv() - plm start request
+ * @wmi_handle: wmi handle
+ * @plm: plm request parameters
+ *
+ * This function request FW to start PLM.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle,
+					 const struct plm_req_params *plm)
+{
+	wmi_vdev_plmreq_start_cmd_fixed_param *cmd;
+	uint32_t *channel_list;
+	int32_t len;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	uint8_t count;
+	int ret;
+
+	/* TLV place holder for channel_list */
+	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
+	len += sizeof(uint32_t) * plm->plm_num_ch;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *)wmi_buf_data(buf);
+
+	buf_ptr = (uint8_t *)cmd;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_vdev_plmreq_start_cmd_fixed_param));
+
+	cmd->vdev_id = plm->vdev_id;
+
+	cmd->meas_token = plm->meas_token;
+	cmd->dialog_token = plm->diag_token;
+	cmd->number_bursts = plm->num_bursts;
+	cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int);
+	cmd->off_duration = plm->meas_duration;
+	cmd->burst_cycle = plm->burst_len;
+	cmd->tx_power = plm->desired_tx_pwr;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac);
+	cmd->num_chans = plm->plm_num_ch;
+
+	buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param);
+
+	WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token);
+	WMI_LOGD("dialog_token: %d", cmd->dialog_token);
+	WMI_LOGD("number_bursts: %d", cmd->number_bursts);
+	WMI_LOGD("burst_interval: %d", cmd->burst_interval);
+	WMI_LOGD("off_duration: %d", cmd->off_duration);
+	WMI_LOGD("burst_cycle: %d", cmd->burst_cycle);
+	WMI_LOGD("tx_power: %d", cmd->tx_power);
+	WMI_LOGD("Number of channels : %d", cmd->num_chans);
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
+		       (cmd->num_chans * sizeof(uint32_t)));
+
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	if (cmd->num_chans) {
+		channel_list = (uint32_t *)buf_ptr;
+		for (count = 0; count < cmd->num_chans; count++) {
+			channel_list[count] = plm->plm_ch_freq_list[count];
+			WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]);
+		}
+		buf_ptr += cmd->num_chans * sizeof(uint32_t);
+	}
+
+	wmi_mtrace(WMI_VDEV_PLMREQ_START_CMDID, cmd->vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_VDEV_PLMREQ_START_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_ese_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_plm_stop_cmd = send_plm_stop_cmd_tlv;
+	ops->send_plm_start_cmd = send_plm_start_cmd_tlv;
+}
+#endif /* FEATURE_WLAN_ESE */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/* send_set_ric_req_cmd_tlv() - set ric request element
+ * @wmi_handle: wmi handle
+ * @msg: message
+ * @is_add_ts: is addts required
+ *
+ * This function sets ric request element for 11r roaming.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle,
+			void *msg, uint8_t is_add_ts)
+{
+	wmi_ric_request_fixed_param *cmd;
+	wmi_ric_tspec *tspec_param;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	struct mac_tspec_ie *tspec_ie = NULL;
+	int32_t len = sizeof(wmi_ric_request_fixed_param) +
+		      WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+
+	cmd = (wmi_ric_request_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_ric_request_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param));
+	if (is_add_ts)
+		cmd->vdev_id = ((struct add_ts_param *)msg)->vdev_id;
+	else
+		cmd->vdev_id = ((struct del_ts_params *)msg)->sessionId;
+	cmd->num_ric_request = 1;
+	cmd->is_add_ric = is_add_ts;
+
+	buf_ptr += sizeof(wmi_ric_request_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec));
+
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	tspec_param = (wmi_ric_tspec *)buf_ptr;
+	WMITLV_SET_HDR(&tspec_param->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_ric_tspec,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec));
+
+	if (is_add_ts)
+		tspec_ie = &(((struct add_ts_param *)msg)->tspec);
+	else
+		tspec_ie = &(((struct del_ts_params *)msg)->delTsInfo.tspec);
+	if (tspec_ie) {
+		/* Fill the tsinfo in the format expected by firmware */
+#ifndef ANI_LITTLE_BIT_ENDIAN
+		qdf_mem_copy(((uint8_t *)&tspec_param->ts_info) + 1,
+			     ((uint8_t *)&tspec_ie->tsinfo) + 1, 2);
+#else
+		qdf_mem_copy(((uint8_t *)&tspec_param->ts_info),
+			     ((uint8_t *)&tspec_ie->tsinfo) + 1, 2);
+#endif /* ANI_LITTLE_BIT_ENDIAN */
+
+		tspec_param->nominal_msdu_size = tspec_ie->nomMsduSz;
+		tspec_param->maximum_msdu_size = tspec_ie->maxMsduSz;
+		tspec_param->min_service_interval = tspec_ie->minSvcInterval;
+		tspec_param->max_service_interval = tspec_ie->maxSvcInterval;
+		tspec_param->inactivity_interval = tspec_ie->inactInterval;
+		tspec_param->suspension_interval = tspec_ie->suspendInterval;
+		tspec_param->svc_start_time = tspec_ie->svcStartTime;
+		tspec_param->min_data_rate = tspec_ie->minDataRate;
+		tspec_param->mean_data_rate = tspec_ie->meanDataRate;
+		tspec_param->peak_data_rate = tspec_ie->peakDataRate;
+		tspec_param->max_burst_size = tspec_ie->maxBurstSz;
+		tspec_param->delay_bound = tspec_ie->delayBound;
+		tspec_param->min_phy_rate = tspec_ie->minPhyRate;
+		tspec_param->surplus_bw_allowance = tspec_ie->surplusBw;
+		tspec_param->medium_time = 0;
+	}
+	WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts);
+
+	wmi_mtrace(WMI_ROAM_SET_RIC_REQUEST_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_ROAM_SET_RIC_REQUEST_CMDID)) {
+		WMI_LOGP("%s: Failed to send vdev Set RIC Req command",
+			 __func__);
+		if (is_add_ts)
+			((struct add_ts_param *)msg)->status =
+					    QDF_STATUS_E_FAILURE;
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to
+ * fw.
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ *
+ * This function sends roam synch complete event to fw.
+ *
+ * Return: QDF STATUS
+ */
+static QDF_STATUS
+send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle,
+					 uint8_t vdev_id)
+{
+	wmi_roam_synch_complete_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint8_t *buf_ptr;
+	uint16_t len;
+	len = sizeof(wmi_roam_synch_complete_fixed_param);
+
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_roam_synch_complete_fixed_param *)wmi_buf_data(wmi_buf);
+	buf_ptr = (uint8_t *)cmd;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_synch_complete_fixed_param));
+	cmd->vdev_id = vdev_id;
+	wmi_mtrace(WMI_ROAM_SYNCH_COMPLETE, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+				 WMI_ROAM_SYNCH_COMPLETE)) {
+		WMI_LOGP("%s: failed to send roam synch confirmation",
+			 __func__);
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_roam_invoke_cmd_tlv() - send roam invoke command to fw.
+ * @wmi_handle: wma handle
+ * @roaminvoke: roam invoke command
+ *
+ * Send roam invoke command to fw for fastreassoc.
+ *
+ * Return: CDF STATUS
+ */
+static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,
+		struct wmi_roam_invoke_cmd *roaminvoke,
+		uint32_t ch_hz)
+{
+	wmi_roam_invoke_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	u_int8_t *buf_ptr;
+	u_int16_t len, args_tlv_len;
+	uint32_t *channel_list;
+	wmi_mac_addr *bssid_list;
+	wmi_tlv_buf_len_param *buf_len_tlv;
+
+	args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) +
+			sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) +
+			roundup(roaminvoke->frame_len, sizeof(uint32_t));
+	len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len;
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf);
+	buf_ptr = (u_int8_t *)cmd;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param,
+	WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param));
+	cmd->vdev_id = roaminvoke->vdev_id;
+	cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE);
+	if (roaminvoke->is_same_bssid)
+		cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP);
+
+	if (roaminvoke->frame_len) {
+		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP;
+		/* packing 1 beacon/probe_rsp frame with WMI cmd */
+		cmd->num_buf = 1;
+	} else {
+		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH;
+		cmd->num_buf = 0;
+	}
+
+	cmd->roam_ap_sel_mode = 0;
+	cmd->roam_delay = 0;
+	cmd->num_chan = 1;
+	cmd->num_bssid = 1;
+
+	if (roaminvoke->forced_roaming) {
+		cmd->num_chan = 0;
+		cmd->num_bssid = 0;
+		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_CACHE_MAP;
+		cmd->flags |=
+			(1 << WMI_ROAM_INVOKE_FLAG_FULL_SCAN_IF_NO_CANDIDATE);
+		cmd->reason = ROAM_INVOKE_REASON_NUD_FAILURE;
+	} else {
+		cmd->reason = ROAM_INVOKE_REASON_USER_SPACE;
+	}
+
+	buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
+		       (sizeof(u_int32_t)));
+	channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	*channel_list = ch_hz;
+	buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE;
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
+		       (sizeof(wmi_mac_addr)));
+	bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list);
+
+	/* move to next tlv i.e. bcn_prb_buf_list */
+	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr);
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
+		       sizeof(wmi_tlv_buf_len_param));
+
+	buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	buf_len_tlv->buf_len = roaminvoke->frame_len;
+
+	/* move to next tlv i.e. bcn_prb_frm */
+	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+		       roundup(roaminvoke->frame_len, sizeof(uint32_t)));
+
+	/* copy frame after the header */
+	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
+		     roaminvoke->frame_buf,
+		     roaminvoke->frame_len);
+
+	wmi_debug("flag:%d, MODE:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d, ch:%d, is_same_bss:%d",
+		  cmd->flags, cmd->roam_scan_mode,
+		  cmd->roam_ap_sel_mode, cmd->roam_delay,
+		  cmd->num_chan, cmd->num_bssid, ch_hz,
+		  roaminvoke->is_same_bssid);
+
+	wmi_mtrace(WMI_ROAM_INVOKE_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+				 WMI_ROAM_INVOKE_CMDID)) {
+		WMI_LOGP("%s: failed to send roam invoke command", __func__);
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_set_ric_req_cmd = send_set_ric_req_cmd_tlv;
+	ops->send_process_roam_synch_complete_cmd =
+			send_process_roam_synch_complete_cmd_tlv;
+	ops->send_roam_invoke_cmd = send_roam_invoke_cmd_tlv;
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+#if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command
+ * @wmi_handle: wmi handle
+ * @roam_req: Roam scan offload params
+ * @buf_ptr: command buffer to send
+ * @fils_tlv_len: fils tlv length
+ *
+ * Return: Updated buffer pointer
+ */
+static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
+			     struct roam_offload_scan_params *roam_req,
+			     uint8_t *buf_ptr, uint32_t fils_tlv_len)
+{
+	wmi_roam_fils_offload_tlv_param *fils_tlv;
+	wmi_erp_info *erp_info;
+	struct roam_fils_params *roam_fils_params;
+
+	if (!roam_req->add_fils_tlv)
+		return buf_ptr;
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(*fils_tlv));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr;
+	WMITLV_SET_HDR(&fils_tlv->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_roam_fils_offload_tlv_param));
+
+	roam_fils_params = &roam_req->roam_fils_params;
+	erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info);
+
+	erp_info->username_length = roam_fils_params->username_length;
+	qdf_mem_copy(erp_info->username, roam_fils_params->username,
+		     erp_info->username_length);
+
+	erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num;
+
+	erp_info->rRk_length = roam_fils_params->rrk_length;
+	qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk,
+		     erp_info->rRk_length);
+
+	erp_info->rIk_length = roam_fils_params->rik_length;
+	qdf_mem_copy(erp_info->rIk, roam_fils_params->rik,
+		     erp_info->rIk_length);
+
+	erp_info->realm_len = roam_fils_params->realm_len;
+	qdf_mem_copy(erp_info->realm, roam_fils_params->realm,
+		     erp_info->realm_len);
+
+	buf_ptr += sizeof(*fils_tlv);
+	return buf_ptr;
+}
+#else
+static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
+				struct roam_offload_scan_params *roam_req,
+				uint8_t *buf_ptr, uint32_t fils_tlv_len)
+{
+	return buf_ptr;
+}
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * fill_roam_offload_11r_params() - Fill roam scan params to send it to fw
+ * @auth_mode: Authentication mode
+ * @roam_offload_11r: TLV to be filled with 11r params
+ * @roam_req: roam request param
+ */
+static void
+fill_roam_offload_11r_params(uint32_t auth_mode,
+			     wmi_roam_11r_offload_tlv_param *roam_offload_11r,
+			     struct roam_offload_scan_params *roam_req)
+{
+	uint8_t *psk_msk, len;
+
+	if (auth_mode == WMI_AUTH_FT_RSNA_FILS_SHA256 ||
+	    auth_mode == WMI_AUTH_FT_RSNA_FILS_SHA384) {
+		psk_msk = roam_req->roam_fils_params.fils_ft;
+		len = roam_req->roam_fils_params.fils_ft_len;
+	} else {
+		psk_msk = roam_req->psk_pmk;
+		len = roam_req->pmk_len;
+	}
+
+	/*
+	 * For SHA384 based akm, the pmk length is 48 bytes. So fill
+	 * first 32 bytes in roam_offload_11r->psk_msk and the remaining
+	 * bytes in roam_offload_11r->psk_msk_ext buffer
+	 */
+	roam_offload_11r->psk_msk_len = len > ROAM_OFFLOAD_PSK_MSK_BYTES ?
+					ROAM_OFFLOAD_PSK_MSK_BYTES : len;
+	qdf_mem_copy(roam_offload_11r->psk_msk, psk_msk,
+		     roam_offload_11r->psk_msk_len);
+	roam_offload_11r->psk_msk_ext_len = 0;
+
+	if (len > ROAM_OFFLOAD_PSK_MSK_BYTES) {
+		roam_offload_11r->psk_msk_ext_len =
+					len - roam_offload_11r->psk_msk_len;
+		qdf_mem_copy(roam_offload_11r->psk_msk_ext,
+			     &psk_msk[roam_offload_11r->psk_msk_len],
+			     roam_offload_11r->psk_msk_ext_len);
+	}
+}
+
+/**
+ * wmi_fill_sae_single_pmk_param() - Fill sae single pmk flag to indicate fw to
+ * use same PMKID for WPA3 SAE roaming.
+ * @params: roam request param
+ * @roam_offload_11i: pointer to 11i params
+ *
+ * Return: None
+ */
+static inline void
+wmi_fill_sae_single_pmk_param(struct roam_offload_scan_params *params,
+			      wmi_roam_11i_offload_tlv_param *roam_offload_11i)
+{
+	if (params->is_sae_same_pmk)
+		roam_offload_11i->flags |=
+				1 << WMI_ROAM_OFFLOAD_FLAG_SAE_SAME_PMKID;
+}
+#else
+static inline void
+wmi_fill_sae_single_pmk_param(struct roam_offload_scan_params *params,
+			      wmi_roam_11i_offload_tlv_param *roam_offload_11i)
+{
+}
+#endif
+
+#define ROAM_OFFLOAD_PMK_EXT_BYTES 16
+
+/**
+ * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw
+ * @wmi_handle: wmi handle
+ * @scan_cmd_fp: start scan command ptr
+ * @roam_req: roam request param
+ *
+ * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
+ * of WMI_ROAM_SCAN_MODE.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS
+send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle,
+				    wmi_start_scan_cmd_fixed_param *scan_cmd_fp,
+				    struct roam_offload_scan_params *roam_req)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp;
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	int auth_mode = roam_req->auth_mode;
+	roam_offload_param *req_offload_params =
+		&roam_req->roam_offload_params;
+	wmi_roam_offload_tlv_param *roam_offload_params;
+	wmi_roam_11i_offload_tlv_param *roam_offload_11i;
+	wmi_roam_11r_offload_tlv_param *roam_offload_11r;
+	wmi_roam_ese_offload_tlv_param *roam_offload_ese;
+	wmi_tlv_buf_len_param *assoc_ies;
+	uint32_t fils_tlv_len = 0;
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+	/* Need to create a buf with roam_scan command at
+	 * front and piggyback with scan command */
+	len = sizeof(wmi_roam_scan_mode_fixed_param) +
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	      (2 * WMI_TLV_HDR_SIZE) +
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+	      sizeof(wmi_start_scan_cmd_fixed_param);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	wmi_debug("auth_mode = %d", auth_mode);
+	if (roam_req->is_roam_req_valid &&
+	    roam_req->roam_offload_enabled) {
+		len += sizeof(wmi_roam_offload_tlv_param);
+		len += WMI_TLV_HDR_SIZE;
+		if ((auth_mode != WMI_AUTH_NONE) &&
+		    ((auth_mode != WMI_AUTH_OPEN) ||
+		     (auth_mode == WMI_AUTH_OPEN &&
+		      roam_req->mdid.mdie_present &&
+		      roam_req->is_11r_assoc) ||
+		     roam_req->is_ese_assoc)) {
+			len += WMI_TLV_HDR_SIZE;
+			if (roam_req->is_ese_assoc)
+				len += sizeof(wmi_roam_ese_offload_tlv_param);
+			else if ((auth_mode == WMI_AUTH_FT_RSNA) ||
+				 (auth_mode == WMI_AUTH_FT_RSNA_PSK) ||
+				 (auth_mode == WMI_AUTH_FT_RSNA_SAE) ||
+				 (auth_mode ==
+				  WMI_AUTH_FT_RSNA_SUITE_B_8021X_SHA384) ||
+				 (auth_mode ==
+				  WMI_AUTH_FT_RSNA_FILS_SHA256) ||
+				 (auth_mode ==
+				  WMI_AUTH_FT_RSNA_FILS_SHA384) ||
+				 (auth_mode == WMI_AUTH_OPEN &&
+				  roam_req->mdid.mdie_present &&
+				  roam_req->is_11r_assoc))
+				len += sizeof(wmi_roam_11r_offload_tlv_param);
+			else
+				len += sizeof(wmi_roam_11i_offload_tlv_param);
+		} else {
+			len += WMI_TLV_HDR_SIZE;
+		}
+
+		len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE)
+			+ roundup(roam_req->assoc_ie_length, sizeof(uint32_t)));
+
+		if (roam_req->add_fils_tlv) {
+			fils_tlv_len = sizeof(wmi_roam_fils_offload_tlv_param);
+			len += WMI_TLV_HDR_SIZE + fils_tlv_len;
+		}
+	} else {
+		if (roam_req->is_roam_req_valid)
+			WMI_LOGD("%s : roam offload = %d", __func__,
+				 roam_req->roam_offload_enabled);
+
+		len += (4 * WMI_TLV_HDR_SIZE);
+	}
+
+	if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled)
+		roam_req->mode |= WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+	if (roam_req->mode ==
+	    (WMI_ROAM_SCAN_MODE_NONE | WMI_ROAM_SCAN_MODE_ROAMOFFLOAD))
+		len = sizeof(wmi_roam_scan_mode_fixed_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_mode_fixed_param));
+
+	roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask =
+			roam_req->roam_trigger_reason_bitmask;
+	roam_scan_mode_fp->min_delay_btw_scans =
+			WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans);
+	roam_scan_mode_fp->roam_scan_mode = roam_req->mode;
+	roam_scan_mode_fp->vdev_id = roam_req->vdev_id;
+	wmi_debug("roam scan mode: %d", roam_req->mode);
+	if (roam_req->mode ==
+	    (WMI_ROAM_SCAN_MODE_NONE | WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) {
+		roam_scan_mode_fp->flags |=
+			WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS;
+		goto send_roam_scan_mode_cmd;
+	}
+
+	/* Fill in scan parameters suitable for roaming scan */
+	buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param);
+
+	qdf_mem_copy(buf_ptr, scan_cmd_fp,
+		     sizeof(wmi_start_scan_cmd_fixed_param));
+	/* Ensure there is no additional IEs */
+	scan_cmd_fp->ie_len = 0;
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_start_scan_cmd_fixed_param));
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param);
+	if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       sizeof(wmi_roam_offload_tlv_param));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		roam_offload_params = (wmi_roam_offload_tlv_param *)buf_ptr;
+		WMITLV_SET_HDR(buf_ptr,
+			       WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param,
+			       WMITLV_GET_STRUCT_TLVLEN
+				       (wmi_roam_offload_tlv_param));
+		roam_offload_params->prefer_5g = roam_req->prefer_5ghz;
+		roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap;
+		roam_offload_params->select_5g_margin =
+			roam_req->select_5ghz_margin;
+		roam_offload_params->handoff_delay_for_rx =
+			req_offload_params->ho_delay_for_rx;
+		roam_offload_params->max_mlme_sw_retries =
+			req_offload_params->roam_preauth_retry_count;
+		roam_offload_params->no_ack_timeout =
+			req_offload_params->roam_preauth_no_ack_timeout;
+		roam_offload_params->reassoc_failure_timeout =
+			roam_req->reassoc_failure_timeout;
+		roam_offload_params->roam_candidate_validity_time =
+			roam_req->rct_validity_timer;
+		roam_offload_params->roam_to_current_bss_disable =
+					roam_req->disable_self_roam;
+		/* Fill the capabilities */
+		roam_offload_params->capability =
+				req_offload_params->capability;
+		roam_offload_params->ht_caps_info =
+				req_offload_params->ht_caps_info;
+		roam_offload_params->ampdu_param =
+				req_offload_params->ampdu_param;
+		roam_offload_params->ht_ext_cap =
+				req_offload_params->ht_ext_cap;
+		roam_offload_params->ht_txbf = req_offload_params->ht_txbf;
+		roam_offload_params->asel_cap = req_offload_params->asel_cap;
+		roam_offload_params->qos_caps = req_offload_params->qos_caps;
+		roam_offload_params->qos_enabled =
+				req_offload_params->qos_enabled;
+		roam_offload_params->wmm_caps = req_offload_params->wmm_caps;
+		qdf_mem_copy((uint8_t *)roam_offload_params->mcsset,
+			     (uint8_t *)req_offload_params->mcsset,
+			     ROAM_OFFLOAD_NUM_MCS_SET);
+
+		buf_ptr += sizeof(wmi_roam_offload_tlv_param);
+		/* The TLV's are in the order of 11i, 11R, ESE. Hence,
+		 * they are filled in the same order.Depending on the
+		 * authentication type, the other mode TLV's are nullified
+		 * and only headers are filled.*/
+		if (auth_mode != WMI_AUTH_NONE &&
+		    (auth_mode != WMI_AUTH_OPEN ||
+		     roam_req->is_ese_assoc ||
+		     (auth_mode == WMI_AUTH_OPEN &&
+		      roam_req->mdid.mdie_present && roam_req->is_11r_assoc))) {
+			if (roam_req->is_ese_assoc) {
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       WMITLV_GET_STRUCT_TLVLEN(0));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       WMITLV_GET_STRUCT_TLVLEN(0));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					sizeof(wmi_roam_ese_offload_tlv_param));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				roam_offload_ese =
+				    (wmi_roam_ese_offload_tlv_param *)buf_ptr;
+				qdf_mem_copy(roam_offload_ese->krk,
+					     roam_req->krk,
+					     sizeof(roam_req->krk));
+				qdf_mem_copy(roam_offload_ese->btk,
+					     roam_req->btk,
+					     sizeof(roam_req->btk));
+				WMITLV_SET_HDR(&roam_offload_ese->tlv_header,
+				WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param,
+				WMITLV_GET_STRUCT_TLVLEN
+				(wmi_roam_ese_offload_tlv_param));
+				buf_ptr +=
+					sizeof(wmi_roam_ese_offload_tlv_param);
+			} else if (auth_mode == WMI_AUTH_FT_RSNA ||
+				   auth_mode == WMI_AUTH_FT_RSNA_PSK ||
+				   auth_mode == WMI_AUTH_FT_RSNA_SAE ||
+				   (auth_mode ==
+				    WMI_AUTH_FT_RSNA_SUITE_B_8021X_SHA384) ||
+				   (auth_mode ==
+				    WMI_AUTH_FT_RSNA_FILS_SHA256) ||
+				   (auth_mode ==
+				    WMI_AUTH_FT_RSNA_FILS_SHA384) ||
+				   (auth_mode == WMI_AUTH_OPEN &&
+				    roam_req->mdid.mdie_present &&
+				    roam_req->is_11r_assoc)) {
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       0);
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					sizeof(wmi_roam_11r_offload_tlv_param));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				roam_offload_11r =
+				    (wmi_roam_11r_offload_tlv_param *)buf_ptr;
+				roam_offload_11r->r0kh_id_len =
+					roam_req->rokh_id_length;
+				qdf_mem_copy(roam_offload_11r->r0kh_id,
+					     roam_req->rokh_id,
+					     roam_offload_11r->r0kh_id_len);
+				fill_roam_offload_11r_params(auth_mode,
+							     roam_offload_11r,
+							     roam_req);
+				roam_offload_11r->mdie_present =
+					roam_req->mdid.mdie_present;
+				roam_offload_11r->mdid =
+					roam_req->mdid.mobility_domain;
+				roam_offload_11r->adaptive_11r =
+					roam_req->is_adaptive_11r;
+				roam_offload_11r->ft_im_for_deauth =
+					roam_req->enable_ft_im_roaming;
+
+				if (auth_mode == WMI_AUTH_OPEN) {
+					/*
+					 * If FT-Open ensure pmk length and
+					 * r0khid len are zero
+					 */
+					roam_offload_11r->r0kh_id_len = 0;
+					roam_offload_11r->psk_msk_len = 0;
+				}
+				WMITLV_SET_HDR(&roam_offload_11r->tlv_header,
+				WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param,
+				WMITLV_GET_STRUCT_TLVLEN
+					(wmi_roam_11r_offload_tlv_param));
+				buf_ptr +=
+					sizeof(wmi_roam_11r_offload_tlv_param);
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       WMITLV_GET_STRUCT_TLVLEN(0));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMI_LOGD("psk_msk_len = %d psk_msk_ext:%d",
+					 roam_offload_11r->psk_msk_len,
+					 roam_offload_11r->psk_msk_ext_len);
+				if (roam_offload_11r->psk_msk_len)
+					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
+						QDF_TRACE_LEVEL_DEBUG,
+						roam_offload_11r->psk_msk,
+						roam_offload_11r->psk_msk_len);
+			} else {
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					sizeof(wmi_roam_11i_offload_tlv_param));
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				roam_offload_11i =
+				     (wmi_roam_11i_offload_tlv_param *)buf_ptr;
+
+				if (roam_req->fw_okc) {
+					WMI_SET_ROAM_OFFLOAD_OKC_ENABLED
+						(roam_offload_11i->flags);
+					WMI_LOGI("LFR3:OKC enabled");
+				} else {
+					WMI_SET_ROAM_OFFLOAD_OKC_DISABLED
+						(roam_offload_11i->flags);
+					WMI_LOGI("LFR3:OKC disabled");
+				}
+
+				if (roam_req->fw_pmksa_cache) {
+					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED
+						(roam_offload_11i->flags);
+					WMI_LOGI("LFR3:PMKSA caching enabled");
+				} else {
+					WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED
+						(roam_offload_11i->flags);
+					WMI_LOGI("LFR3:PMKSA caching disabled");
+				}
+
+				wmi_fill_sae_single_pmk_param(roam_req,
+							      roam_offload_11i);
+
+				roam_offload_11i->pmk_len = roam_req->pmk_len >
+					ROAM_OFFLOAD_PMK_BYTES ?
+					ROAM_OFFLOAD_PMK_BYTES :
+					roam_req->pmk_len;
+
+				qdf_mem_copy(roam_offload_11i->pmk,
+					     roam_req->psk_pmk,
+					     roam_offload_11i->pmk_len);
+
+				roam_offload_11i->pmk_ext_len =
+					((roam_req->pmk_len >
+					 ROAM_OFFLOAD_PMK_BYTES) &&
+					 (auth_mode ==
+					 WMI_AUTH_RSNA_SUITE_B_8021X_SHA384)) ?
+					ROAM_OFFLOAD_PMK_EXT_BYTES : 0;
+
+				qdf_mem_copy(roam_offload_11i->pmk_ext,
+					     &roam_req->psk_pmk[
+					     ROAM_OFFLOAD_PMK_BYTES],
+					     roam_offload_11i->pmk_ext_len);
+
+				WMITLV_SET_HDR(&roam_offload_11i->tlv_header,
+				WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param,
+				WMITLV_GET_STRUCT_TLVLEN
+				(wmi_roam_11i_offload_tlv_param));
+				buf_ptr +=
+					sizeof(wmi_roam_11i_offload_tlv_param);
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       0);
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+					       0);
+				buf_ptr += WMI_TLV_HDR_SIZE;
+				WMI_LOGD("pmk_len:%d pmk_ext_len:%d",
+					 roam_offload_11i->pmk_len,
+					 roam_offload_11i->pmk_ext_len);
+			}
+		} else {
+			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+				       WMITLV_GET_STRUCT_TLVLEN(0));
+			buf_ptr += WMI_TLV_HDR_SIZE;
+			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+				       WMITLV_GET_STRUCT_TLVLEN(0));
+			buf_ptr += WMI_TLV_HDR_SIZE;
+			WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+				       WMITLV_GET_STRUCT_TLVLEN(0));
+			buf_ptr += WMI_TLV_HDR_SIZE;
+		}
+
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       sizeof(*assoc_ies));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+
+		assoc_ies = (wmi_tlv_buf_len_param *)buf_ptr;
+		WMITLV_SET_HDR(&assoc_ies->tlv_header,
+			WMITLV_TAG_STRUC_wmi_tlv_buf_len_param,
+			WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param));
+		assoc_ies->buf_len = roam_req->assoc_ie_length;
+
+		buf_ptr += sizeof(*assoc_ies);
+
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+				roundup(assoc_ies->buf_len, sizeof(uint32_t)));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+
+		if (assoc_ies->buf_len != 0)
+			qdf_mem_copy(buf_ptr, roam_req->assoc_ie,
+				     assoc_ies->buf_len);
+
+		buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t));
+		buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req,
+					   buf_ptr, fils_tlv_len);
+	} else {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+	}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+send_roam_scan_mode_cmd:
+	wmi_mtrace(WMI_ROAM_SCAN_MODE, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_SCAN_MODE);
+	if (QDF_IS_STATUS_ERROR(status))
+		wmi_buf_free(buf);
+
+	return status;
+}
+
+/**
+ * convert_roam_trigger_reason() - Function to convert unified Roam trigger
+ * enum to TLV specific WMI_ROAM_TRIGGER_REASON_ID
+ * @reason: Roam trigger reason
+ *
+ * Return: WMI_ROAM_TRIGGER_REASON_ID
+ */
+static WMI_ROAM_TRIGGER_REASON_ID
+convert_roam_trigger_reason(enum roam_trigger_reason trigger_reason)
+{
+	switch (trigger_reason) {
+	case ROAM_TRIGGER_REASON_NONE:
+		return WMI_ROAM_TRIGGER_REASON_NONE;
+	case ROAM_TRIGGER_REASON_PER:
+		return WMI_ROAM_TRIGGER_REASON_PER;
+	case ROAM_TRIGGER_REASON_BMISS:
+		return WMI_ROAM_TRIGGER_REASON_BMISS;
+	case ROAM_TRIGGER_REASON_LOW_RSSI:
+		return WMI_ROAM_TRIGGER_REASON_LOW_RSSI;
+	case ROAM_TRIGGER_REASON_HIGH_RSSI:
+		return WMI_ROAM_TRIGGER_REASON_HIGH_RSSI;
+	case ROAM_TRIGGER_REASON_PERIODIC:
+		return WMI_ROAM_TRIGGER_REASON_PERIODIC;
+	case ROAM_TRIGGER_REASON_MAWC:
+		return WMI_ROAM_TRIGGER_REASON_MAWC;
+	case ROAM_TRIGGER_REASON_DENSE:
+		return WMI_ROAM_TRIGGER_REASON_DENSE;
+	case ROAM_TRIGGER_REASON_BACKGROUND:
+		return WMI_ROAM_TRIGGER_REASON_BACKGROUND;
+	case ROAM_TRIGGER_REASON_FORCED:
+		return WMI_ROAM_TRIGGER_REASON_FORCED;
+	case ROAM_TRIGGER_REASON_BTM:
+		return WMI_ROAM_TRIGGER_REASON_BTM;
+	case ROAM_TRIGGER_REASON_UNIT_TEST:
+		return WMI_ROAM_TRIGGER_REASON_UNIT_TEST;
+	case ROAM_TRIGGER_REASON_BSS_LOAD:
+		return WMI_ROAM_TRIGGER_REASON_BSS_LOAD;
+	case ROAM_TRIGGER_REASON_DEAUTH:
+		return WMI_ROAM_TRIGGER_REASON_DEAUTH;
+	case ROAM_TRIGGER_REASON_IDLE:
+		return WMI_ROAM_TRIGGER_REASON_IDLE;
+	case ROAM_TRIGGER_REASON_MAX:
+		return WMI_ROAM_TRIGGER_REASON_MAX;
+	default:
+		return WMI_ROAM_TRIGGER_REASON_NONE;
+	}
+}
+
+/**
+ * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw
+ * @wmi_handle: wmi handle
+ * @ap_profile_p: ap profile
+ *
+ * Send WMI_ROAM_AP_PROFILE to firmware
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS
+send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
+					  struct ap_profile_params *ap_profile)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	size_t len;
+	uint8_t *buf_ptr;
+	wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp;
+	wmi_roam_cnd_scoring_param *score_param;
+	wmi_ap_profile *profile;
+	wmi_roam_score_delta_param *score_delta_param;
+	wmi_roam_cnd_min_rssi_param *min_rssi_param;
+	enum roam_trigger_reason trig_reason;
+
+	len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile);
+	len += sizeof(*score_param);
+	len += WMI_TLV_HDR_SIZE;
+	len += NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param);
+	len += WMI_TLV_HDR_SIZE;
+	len += NUM_OF_ROAM_TRIGGERS * sizeof(*min_rssi_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_ap_profile_fixed_param));
+	/* fill in threshold values */
+	roam_ap_profile_fp->vdev_id = ap_profile->vdev_id;
+	roam_ap_profile_fp->id = 0;
+	buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param);
+
+	profile = (wmi_ap_profile *)buf_ptr;
+	WMITLV_SET_HDR(&profile->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_ap_profile,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile));
+	profile->flags = ap_profile->profile.flags;
+	profile->rssi_threshold = ap_profile->profile.rssi_threshold;
+	profile->ssid.ssid_len = ap_profile->profile.ssid.length;
+	qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid,
+		     profile->ssid.ssid_len);
+	profile->rsn_authmode = ap_profile->profile.rsn_authmode;
+	profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset;
+	profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset;
+	profile->rsn_mcastmgmtcipherset =
+				ap_profile->profile.rsn_mcastmgmtcipherset;
+	profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh;
+
+	WMI_LOGD("AP PROFILE: flags %x rssi_thres:%d ssid:%.*s authmode %d uc cipher %d mc cipher %d mc mgmt cipher %d rssi abs thresh %d",
+		 profile->flags, profile->rssi_threshold,
+		 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid,
+		 profile->rsn_authmode, profile->rsn_ucastcipherset,
+		 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset,
+		 profile->rssi_abs_thresh);
+
+	buf_ptr += sizeof(wmi_ap_profile);
+
+	score_param = (wmi_roam_cnd_scoring_param *)buf_ptr;
+	WMITLV_SET_HDR(&score_param->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param));
+	score_param->disable_bitmap = ap_profile->param.disable_bitmap;
+	score_param->rssi_weightage_pcnt =
+			ap_profile->param.rssi_weightage;
+	score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage;
+	score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage;
+	score_param->he_weightage_pcnt = ap_profile->param.he_weightage;
+	score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage;
+	score_param->band_weightage_pcnt = ap_profile->param.band_weightage;
+	score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage;
+	score_param->esp_qbss_weightage_pcnt =
+			ap_profile->param.esp_qbss_weightage;
+	score_param->beamforming_weightage_pcnt =
+			ap_profile->param.beamforming_weightage;
+	score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage;
+	score_param->oce_wan_weightage_pcnt =
+			ap_profile->param.oce_wan_weightage;
+	score_param->oce_ap_tx_pwr_weightage_pcnt =
+				ap_profile->param.oce_ap_tx_pwr_weightage;
+	score_param->oce_ap_subnet_id_weightage_pcnt =
+				ap_profile->param.oce_subnet_id_weightage;
+	score_param->vendor_roam_score_algorithm_id =
+			ap_profile->param.vendor_roam_score_algorithm;
+
+	WMI_LOGD("Score params weightage: disable_bitmap %x rssi %d ht %d vht %d he %d BW %d band %d NSS %d ESP %d BF %d PCL %d OCE WAN %d APTX %d roam score algo %d subnet id %d",
+		 score_param->disable_bitmap, score_param->rssi_weightage_pcnt,
+		 score_param->ht_weightage_pcnt,
+		 score_param->vht_weightage_pcnt,
+		 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt,
+		 score_param->band_weightage_pcnt,
+		 score_param->nss_weightage_pcnt,
+		 score_param->esp_qbss_weightage_pcnt,
+		 score_param->beamforming_weightage_pcnt,
+		 score_param->pcl_weightage_pcnt,
+		 score_param->oce_wan_weightage_pcnt,
+		 score_param->oce_ap_tx_pwr_weightage_pcnt,
+		 score_param->vendor_roam_score_algorithm_id,
+		 score_param->oce_ap_subnet_id_weightage_pcnt);
+
+	score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score;
+	score_param->band_scoring.score_pcnt =
+			ap_profile->param.band_index_score;
+	score_param->nss_scoring.score_pcnt =
+			ap_profile->param.nss_index_score;
+
+	wmi_debug("bw_index_score %x band_index_score %x nss_index_score %x",
+		  score_param->bw_scoring.score_pcnt,
+		  score_param->band_scoring.score_pcnt,
+		  score_param->nss_scoring.score_pcnt);
+
+	score_param->rssi_scoring.best_rssi_threshold =
+		(-1) * ap_profile->param.rssi_scoring.best_rssi_threshold;
+	score_param->rssi_scoring.good_rssi_threshold =
+		(-1) * ap_profile->param.rssi_scoring.good_rssi_threshold;
+	score_param->rssi_scoring.bad_rssi_threshold =
+		(-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold;
+	score_param->rssi_scoring.good_rssi_pcnt =
+		ap_profile->param.rssi_scoring.good_rssi_pcnt;
+	score_param->rssi_scoring.bad_rssi_pcnt =
+		ap_profile->param.rssi_scoring.bad_rssi_pcnt;
+	score_param->rssi_scoring.good_bucket_size =
+		ap_profile->param.rssi_scoring.good_bucket_size;
+	score_param->rssi_scoring.bad_bucket_size =
+		ap_profile->param.rssi_scoring.bad_bucket_size;
+	score_param->rssi_scoring.rssi_pref_5g_rssi_thresh =
+		(-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh;
+
+	WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d",
+		 score_param->rssi_scoring.best_rssi_threshold,
+		 score_param->rssi_scoring.good_rssi_threshold,
+		 score_param->rssi_scoring.bad_rssi_threshold,
+		 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh);
+	WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d",
+		 score_param->rssi_scoring.good_rssi_pcnt,
+		 score_param->rssi_scoring.bad_rssi_pcnt,
+		 score_param->rssi_scoring.good_bucket_size,
+		 score_param->rssi_scoring.bad_bucket_size);
+
+	score_param->esp_qbss_scoring.num_slot =
+			ap_profile->param.esp_qbss_scoring.num_slot;
+	score_param->esp_qbss_scoring.score_pcnt3_to_0 =
+			ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0;
+	score_param->esp_qbss_scoring.score_pcnt7_to_4 =
+			ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4;
+	score_param->esp_qbss_scoring.score_pcnt11_to_8 =
+			ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8;
+	score_param->esp_qbss_scoring.score_pcnt15_to_12 =
+			ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12;
+
+	WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
+		 score_param->esp_qbss_scoring.num_slot,
+		 score_param->esp_qbss_scoring.score_pcnt3_to_0,
+		 score_param->esp_qbss_scoring.score_pcnt7_to_4,
+		 score_param->esp_qbss_scoring.score_pcnt11_to_8,
+		 score_param->esp_qbss_scoring.score_pcnt15_to_12);
+
+	score_param->oce_wan_scoring.num_slot =
+			ap_profile->param.oce_wan_scoring.num_slot;
+	score_param->oce_wan_scoring.score_pcnt3_to_0 =
+			ap_profile->param.oce_wan_scoring.score_pcnt3_to_0;
+	score_param->oce_wan_scoring.score_pcnt7_to_4 =
+			ap_profile->param.oce_wan_scoring.score_pcnt7_to_4;
+	score_param->oce_wan_scoring.score_pcnt11_to_8 =
+			ap_profile->param.oce_wan_scoring.score_pcnt11_to_8;
+	score_param->oce_wan_scoring.score_pcnt15_to_12 =
+			ap_profile->param.oce_wan_scoring.score_pcnt15_to_12;
+
+	WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
+		 score_param->oce_wan_scoring.num_slot,
+		 score_param->oce_wan_scoring.score_pcnt3_to_0,
+		 score_param->oce_wan_scoring.score_pcnt7_to_4,
+		 score_param->oce_wan_scoring.score_pcnt11_to_8,
+		 score_param->oce_wan_scoring.score_pcnt15_to_12);
+
+	score_param->roam_score_delta_pcnt = ap_profile->param.roam_score_delta;
+	score_param->roam_score_delta_mask =
+				ap_profile->param.roam_trigger_bitmap;
+	score_param->candidate_min_roam_score_delta =
+				ap_profile->param.cand_min_roam_score_delta;
+	WMI_LOGD("Roam score delta:%d Roam_trigger_bitmap:%x cand min score delta = %d",
+		 score_param->roam_score_delta_pcnt,
+		 score_param->roam_score_delta_mask,
+		 score_param->candidate_min_roam_score_delta);
+
+	buf_ptr += sizeof(*score_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       (NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param)));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	score_delta_param = (wmi_roam_score_delta_param *)buf_ptr;
+	WMITLV_SET_HDR(&score_delta_param->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_score_delta_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_score_delta_param));
+	trig_reason =
+		ap_profile->score_delta_param[IDLE_ROAM_TRIGGER].trigger_reason;
+	score_delta_param->roam_trigger_reason =
+		convert_roam_trigger_reason(trig_reason);
+	score_delta_param->roam_score_delta =
+		ap_profile->score_delta_param[IDLE_ROAM_TRIGGER].roam_score_delta;
+
+	buf_ptr += sizeof(*score_delta_param);
+	score_delta_param = (wmi_roam_score_delta_param *)buf_ptr;
+	WMITLV_SET_HDR(&score_delta_param->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_score_delta_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_score_delta_param));
+	trig_reason =
+		ap_profile->score_delta_param[BTM_ROAM_TRIGGER].trigger_reason;
+	score_delta_param->roam_trigger_reason =
+		convert_roam_trigger_reason(trig_reason);
+	score_delta_param->roam_score_delta =
+		ap_profile->score_delta_param[BTM_ROAM_TRIGGER].roam_score_delta;
+
+	buf_ptr += sizeof(*score_delta_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       (NUM_OF_ROAM_TRIGGERS * sizeof(*min_rssi_param)));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr;
+	WMITLV_SET_HDR(&min_rssi_param->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param));
+	trig_reason =
+		ap_profile->min_rssi_params[DEAUTH_MIN_RSSI].trigger_reason;
+	min_rssi_param->roam_trigger_reason =
+		convert_roam_trigger_reason(trig_reason);
+	min_rssi_param->candidate_min_rssi =
+		ap_profile->min_rssi_params[DEAUTH_MIN_RSSI].min_rssi;
+
+	buf_ptr += sizeof(*min_rssi_param);
+	min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr;
+	WMITLV_SET_HDR(&min_rssi_param->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param));
+	trig_reason =
+		ap_profile->min_rssi_params[BMISS_MIN_RSSI].trigger_reason;
+	min_rssi_param->roam_trigger_reason =
+		convert_roam_trigger_reason(trig_reason);
+	min_rssi_param->candidate_min_rssi =
+		ap_profile->min_rssi_params[BMISS_MIN_RSSI].min_rssi;
+
+	wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_AP_PROFILE);
+	if (QDF_IS_STATUS_ERROR(status))
+		wmi_buf_free(buf);
+
+	return status;
+}
+
+/**
+ * send_roam_scan_offload_cmd_tlv() - set roam offload command
+ * @wmi_handle: wmi handle
+ * @command: command
+ * @vdev_id: vdev id
+ *
+ * This function set roam offload command to fw.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS
+send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle,
+			       uint32_t command, uint32_t vdev_id)
+{
+	QDF_STATUS status;
+	wmi_roam_scan_cmd_fixed_param *cmd_fp;
+	wmi_buf_t buf = NULL;
+	int len;
+	uint8_t *buf_ptr;
+
+	len = sizeof(wmi_roam_scan_cmd_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+
+	cmd_fp = (wmi_roam_scan_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param));
+	cmd_fp->vdev_id = vdev_id;
+	cmd_fp->command_arg = command;
+
+	wmi_mtrace(WMI_ROAM_SCAN_CMD, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_SCAN_CMD);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto error;
+
+	WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__);
+	return QDF_STATUS_SUCCESS;
+
+error:
+	wmi_buf_free(buf);
+
+	return status;
+}
+
+/**
+ * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period
+ * @wmi_handle: wmi handle
+ * @param: roam scan parameters to be sent to firmware
+ *
+ * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS
+send_roam_scan_offload_scan_period_cmd_tlv(
+		wmi_unified_t wmi_handle,
+		struct roam_scan_period_params *param)
+{
+	QDF_STATUS status;
+	wmi_buf_t buf = NULL;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_scan_period_fixed_param *scan_period_fp;
+
+	/* Send scan period values */
+	len = sizeof(wmi_roam_scan_period_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	scan_period_fp = (wmi_roam_scan_period_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&scan_period_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_scan_period_fixed_param));
+	/* fill in scan period values */
+	scan_period_fp->vdev_id = param->vdev_id;
+	scan_period_fp->roam_scan_period = param->scan_period;
+	scan_period_fp->roam_scan_age = param->scan_age;
+	scan_period_fp->inactivity_time_period =
+			param->roam_scan_inactivity_time;
+	scan_period_fp->roam_inactive_count =
+			param->roam_inactive_data_packet_count;
+	scan_period_fp->roam_scan_period_after_inactivity =
+			param->roam_scan_period_after_inactivity;
+	/* Firmware expects the full scan preriod in msec whereas host
+	 * provides the same in seconds.
+	 * Convert it to msec and send to firmware
+	 */
+	scan_period_fp->roam_full_scan_period = param->full_scan_period * 1000;
+
+	wmi_debug("roam_scan_period=%d, roam_scan_age=%d, full_scan_period= %u",
+		  scan_period_fp->roam_scan_period,
+		  scan_period_fp->roam_scan_age,
+		  scan_period_fp->roam_full_scan_period);
+
+	wmi_debug("inactiviy time:%d inactive cnt:%d time after inactivity:%d",
+		  scan_period_fp->inactivity_time_period,
+		  scan_period_fp->roam_inactive_count,
+		  scan_period_fp->roam_scan_period_after_inactivity);
+
+	wmi_mtrace(WMI_ROAM_SCAN_PERIOD, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_ROAM_SCAN_PERIOD);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wmi_buf_free(buf);
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list
+ * @wmi_handle: wmi handle
+ * @chan_count: channel count
+ * @chan_list: channel list
+ * @list_type: list type
+ * @vdev_id: vdev id
+ *
+ * Set roam offload channel list.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS
+send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
+					 uint8_t chan_count,
+					 uint32_t *chan_list,
+					 uint8_t list_type, uint32_t vdev_id)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len, list_tlv_len;
+	int i;
+	uint8_t *buf_ptr;
+	wmi_roam_chan_list_fixed_param *chan_list_fp;
+	uint32_t *roam_chan_list_array;
+
+	/* Channel list is a table of 2 TLV's */
+	list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t);
+	len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	chan_list_fp = (wmi_roam_chan_list_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&chan_list_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_chan_list_fixed_param));
+	chan_list_fp->vdev_id = vdev_id;
+	chan_list_fp->num_chan = chan_count;
+	if (list_type == WMI_CHANNEL_LIST_STATIC) {
+		/* external app is controlling channel list */
+		chan_list_fp->chan_list_type =
+			WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC;
+	} else {
+		/* umac supplied occupied channel list in LFR */
+		chan_list_fp->chan_list_type =
+			WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC;
+	}
+
+	buf_ptr += sizeof(wmi_roam_chan_list_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
+		       (chan_list_fp->num_chan * sizeof(uint32_t)));
+	roam_chan_list_array = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
+	for (i = 0; ((i < chan_list_fp->num_chan) &&
+		     (i < WMI_ROAM_MAX_CHANNELS)); i++)
+		roam_chan_list_array[i] = chan_list[i];
+
+	wmi_mtrace(WMI_ROAM_CHAN_LIST, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_CHAN_LIST);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto error;
+
+	return QDF_STATUS_SUCCESS;
+error:
+	wmi_buf_free(buf);
+
+	return status;
+}
+
+/**
+ * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th
+ * @wmi_handle: wmi handle
+ * @rssi_change_thresh: RSSI Change threshold
+ * @bcn_rssi_weight: beacon RSSI weight
+ * @vdev_id: vdev id
+ *
+ * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS
+send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle,
+					   uint32_t vdev_id,
+					   int32_t rssi_change_thresh,
+					   uint32_t bcn_rssi_weight,
+					   uint32_t hirssi_delay_btw_scans)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp;
+
+	/* Send rssi change parameters */
+	len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	rssi_change_fp =
+		(wmi_roam_scan_rssi_change_threshold_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&rssi_change_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_roam_scan_rssi_change_threshold_fixed_param));
+	/* fill in rssi change threshold (hysteresis) values */
+	rssi_change_fp->vdev_id = vdev_id;
+	rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh;
+	rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight;
+	rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans;
+
+	wmi_mtrace(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto error;
+
+	wmi_nofl_debug("roam_scan_rssi_change_thresh %d bcn_rssi_weight %d hirssi_delay_btw_scans %d",
+		       rssi_change_thresh, bcn_rssi_weight,
+		       hirssi_delay_btw_scans);
+
+	return QDF_STATUS_SUCCESS;
+error:
+	wmi_buf_free(buf);
+
+	return status;
+}
+
+/**
+ * send_per_roam_config_cmd_tlv() - set per roaming config to FW
+ * @wmi_handle: wmi handle
+ * @req_buf: per roam config buffer
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS
+send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle,
+			     struct wmi_per_roam_config_req *req_buf)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_per_config_fixed_param *wmi_per_config;
+
+	len = sizeof(wmi_roam_per_config_fixed_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	wmi_per_config =
+		(wmi_roam_per_config_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&wmi_per_config->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_roam_per_config_fixed_param));
+
+	/* fill in per roam config values */
+	wmi_per_config->vdev_id = req_buf->vdev_id;
+
+	wmi_per_config->enable = req_buf->per_config.enable;
+	wmi_per_config->high_rate_thresh =
+		(req_buf->per_config.tx_high_rate_thresh << 16) |
+		(req_buf->per_config.rx_high_rate_thresh & 0x0000ffff);
+	wmi_per_config->low_rate_thresh =
+		(req_buf->per_config.tx_low_rate_thresh << 16) |
+		(req_buf->per_config.rx_low_rate_thresh & 0x0000ffff);
+	wmi_per_config->pkt_err_rate_thresh_pct =
+		(req_buf->per_config.tx_rate_thresh_percnt << 16) |
+		(req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff);
+	wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time;
+	wmi_per_config->pkt_err_rate_mon_time =
+			(req_buf->per_config.tx_per_mon_time << 16) |
+			(req_buf->per_config.rx_per_mon_time & 0x0000ffff);
+	wmi_per_config->min_candidate_rssi =
+			req_buf->per_config.min_candidate_rssi;
+
+	/* Send per roam config parameters */
+	wmi_mtrace(WMI_ROAM_PER_CONFIG_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_PER_CONFIG_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d",
+			 status);
+		wmi_buf_free(buf);
+		return status;
+	}
+	WMI_LOGD(FL("per roam enable=%d, vdev=%d"),
+		 req_buf->per_config.enable, req_buf->vdev_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan
+ * configuration params
+ * @wmi_handle: wmi handler
+ * @limit_off_chan_param: pointer to wmi_off_chan_param
+ *
+ * Return: 0 for success and non zero for failure
+ */
+static QDF_STATUS send_limit_off_chan_cmd_tlv(
+			wmi_unified_t wmi_handle,
+			struct wmi_limit_off_chan_param *limit_off_chan_param)
+{
+	wmi_vdev_limit_offchan_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len = sizeof(*cmd);
+	int err;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+			WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param,
+			WMITLV_GET_STRUCT_TLVLEN(
+				wmi_vdev_limit_offchan_cmd_fixed_param));
+
+	cmd->vdev_id = limit_off_chan_param->vdev_id;
+
+	cmd->flags &= 0;
+	if (limit_off_chan_param->status)
+		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE;
+	if (limit_off_chan_param->skip_dfs_chans)
+		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS;
+
+	cmd->max_offchan_time = limit_off_chan_param->max_offchan_time;
+	cmd->rest_time = limit_off_chan_param->rest_time;
+
+	WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d",
+		 __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time,
+		 cmd->rest_time);
+
+	wmi_mtrace(WMI_VDEV_LIMIT_OFFCHAN_CMDID, cmd->vdev_id, 0);
+	err = wmi_unified_cmd_send(wmi_handle, buf,
+				   len, WMI_VDEV_LIMIT_OFFCHAN_CMDID);
+	if (QDF_IS_STATUS_ERROR(err)) {
+		WMI_LOGE("Failed to send limit off chan cmd err=%d", err);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle,
+						  struct hlp_params *params)
+{
+	uint32_t len;
+	uint8_t *buf_ptr;
+	wmi_buf_t buf = NULL;
+	wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params;
+
+	len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param);
+	len += WMI_TLV_HDR_SIZE;
+	len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t));
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&hlp_params->tlv_header,
+		WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param));
+
+	hlp_params->vdev_id = params->vdev_id;
+	hlp_params->size = params->hlp_ie_len;
+	hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER;
+
+	buf_ptr += sizeof(*hlp_params);
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+		       round_up(params->hlp_ie_len, sizeof(uint32_t)));
+
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len);
+
+	WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"),
+		 hlp_params->vdev_id, hlp_params->size);
+	wmi_mtrace(WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID, NO_SESSION, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) {
+		WMI_LOGE(FL("Failed to send FILS HLP pkt cmd"));
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_fils_sk_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv;
+}
+#endif /* WLAN_FEATURE_FILS_SK */
+
+/*
+ * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config
+ * @wmi_handle: wmi handle
+ * @params: pointer to wmi_btm_config
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle,
+					  struct wmi_btm_config *params)
+{
+	wmi_btm_config_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_btm_config_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param));
+	cmd->vdev_id = params->vdev_id;
+	cmd->flags = params->btm_offload_config;
+	cmd->max_attempt_cnt = params->btm_max_attempt_cnt;
+	cmd->solicited_timeout_ms = params->btm_solicited_timeout;
+	cmd->stick_time_seconds = params->btm_sticky_time;
+	cmd->disassoc_timer_threshold = params->disassoc_timer_threshold;
+	cmd->btm_bitmap = params->btm_query_bitmask;
+	cmd->btm_candidate_min_score = params->btm_candidate_min_score;
+
+	wmi_mtrace(WMI_ROAM_BTM_CONFIG_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_ROAM_BTM_CONFIG_CMDID)) {
+		WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID",
+			 __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_roam_bss_load_config_tlv() - send roam load bss trigger configuration
+ * @wmi_handle: wmi handle
+ * @parms: pointer to wmi_bss_load_config
+ *
+ * This function sends the roam load bss trigger configuration to fw.
+ * the bss_load_threshold parameter is used to configure the maximum
+ * bss load percentage, above which the firmware should trigger roaming
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS
+send_roam_bss_load_config_tlv(wmi_unified_t wmi_handle,
+			      struct wmi_bss_load_config *params)
+{
+	wmi_roam_bss_load_config_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_roam_bss_load_config_cmd_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(
+	    &cmd->tlv_header,
+	    WMITLV_TAG_STRUC_wmi_roam_bss_load_config_cmd_fixed_param,
+	    WMITLV_GET_STRUCT_TLVLEN(wmi_roam_bss_load_config_cmd_fixed_param));
+
+	cmd->vdev_id = params->vdev_id;
+	cmd->bss_load_threshold = params->bss_load_threshold;
+	cmd->monitor_time_window = params->bss_load_sample_time;
+	cmd->rssi_2g_threshold = params->rssi_threshold_24ghz;
+	cmd->rssi_5g_threshold = params->rssi_threshold_5ghz;
+
+	wmi_debug("vdev:%d bss_load_thres:%d monitor_time:%d rssi_2g:%d rssi_5g:%d",
+		  cmd->vdev_id, cmd->bss_load_threshold,
+		  cmd->monitor_time_window, cmd->rssi_2g_threshold,
+		  cmd->rssi_5g_threshold);
+
+	wmi_mtrace(WMI_ROAM_BSS_LOAD_CONFIG_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_ROAM_BSS_LOAD_CONFIG_CMDID)) {
+		WMI_LOGE("%s: failed to send WMI_ROAM_BSS_LOAD_CONFIG_CMDID ",
+			 __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * send_disconnect_roam_params_tlv() - send disconnect roam trigger parameters
+ * @wmi_handle: wmi handle
+ * @disconnect_roam: pointer to wmi_disconnect_roam_params which carries the
+ * disconnect_roam_trigger parameters from CSR
+ *
+ * This function sends the disconnect roam trigger parameters to fw.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS
+send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle,
+				struct wmi_disconnect_roam_params *req)
+{
+	wmi_roam_deauth_config_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_roam_deauth_config_cmd_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(
+	    &cmd->tlv_header,
+	    WMITLV_TAG_STRUC_wmi_roam_deauth_config_cmd_fixed_param,
+	    WMITLV_GET_STRUCT_TLVLEN(wmi_roam_deauth_config_cmd_fixed_param));
+
+	cmd->vdev_id = req->vdev_id;
+	cmd->enable = req->enable;
+	WMI_LOGD("%s: Send WMI_ROAM_DEAUTH_CONFIG vdev_id:%d enable:%d",
+		 __func__, cmd->vdev_id, cmd->enable);
+
+	wmi_mtrace(WMI_ROAM_DEAUTH_CONFIG_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_ROAM_DEAUTH_CONFIG_CMDID)) {
+		WMI_LOGE("%s: failed to send WMI_ROAM_DEAUTH_CONFIG_CMDID",
+			 __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_idle_roam_params_tlv() - send idle roam trigger parameters
+ * @wmi_handle: wmi handle
+ * @idle_roam_params: pointer to wmi_idle_roam_params which carries the
+ * idle roam parameters from CSR
+ *
+ * This function sends the idle roam trigger parameters to fw.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS
+send_idle_roam_params_tlv(wmi_unified_t wmi_handle,
+			  struct wmi_idle_roam_params *idle_roam_params)
+{
+	wmi_roam_idle_config_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_roam_idle_config_cmd_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(
+	    &cmd->tlv_header,
+	    WMITLV_TAG_STRUC_wmi_roam_idle_config_cmd_fixed_param,
+	    WMITLV_GET_STRUCT_TLVLEN(wmi_roam_idle_config_cmd_fixed_param));
+
+	cmd->vdev_id = idle_roam_params->vdev_id;
+	cmd->enable = idle_roam_params->enable;
+	cmd->band = idle_roam_params->band;
+	cmd->rssi_delta = idle_roam_params->conn_ap_rssi_delta;
+	cmd->min_rssi = idle_roam_params->conn_ap_min_rssi;
+	cmd->idle_time = idle_roam_params->inactive_time;
+	cmd->data_packet_count = idle_roam_params->data_pkt_count;
+	WMI_LOGD("%s: Send WMI_ROAM_IDLE_CONFIG_CMDID vdev_id:%d enable:%d",
+		 __func__, cmd->vdev_id, cmd->enable);
+	WMI_LOGD("%s: band:%d rssi_delta:%d min_rssi:%d idle_time:%d data_pkt:%d",
+		 __func__, cmd->band, cmd->rssi_delta, cmd->min_rssi,
+		 cmd->idle_time, cmd->data_packet_count);
+
+	wmi_mtrace(WMI_ROAM_IDLE_CONFIG_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_ROAM_IDLE_CONFIG_CMDID)) {
+		WMI_LOGE("%s: failed to send WMI_ROAM_IDLE_CONFIG_CMDID",
+			 __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_roam_preauth_status_tlv() - send roam pre-authentication status
+ * @wmi_handle: wmi handle
+ * @params: pre-auth status params
+ *
+ * This function sends the roam pre-authentication status for WPA3 SAE
+ * pre-auth to target.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS
+send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
+			     struct wmi_roam_auth_status_params *params)
+{
+	wmi_roam_preauth_status_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len;
+	uint8_t *buf_ptr;
+
+	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + PMKID_LEN;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	cmd = (wmi_roam_preauth_status_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(
+	    &cmd->tlv_header,
+	    WMITLV_TAG_STRUC_wmi_roam_preauth_status_cmd_fixed_param,
+	    WMITLV_GET_STRUCT_TLVLEN(wmi_roam_preauth_status_cmd_fixed_param));
+
+	cmd->vdev_id = params->vdev_id;
+	cmd->preauth_status = params->preauth_status;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->bssid.bytes,
+				   &cmd->candidate_ap_bssid);
+
+	buf_ptr += sizeof(wmi_roam_preauth_status_cmd_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, PMKID_LEN);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	qdf_mem_copy(buf_ptr, params->pmkid, PMKID_LEN);
+	WMI_LOGD("%s: vdev_id:%d status:%d bssid:%pM", __func__, cmd->vdev_id,
+		 cmd->preauth_status, params->bssid.bytes);
+
+	wmi_mtrace(WMI_ROAM_PREAUTH_STATUS_CMDID, cmd->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+				 WMI_ROAM_PREAUTH_STATUS_CMDID)) {
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	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,
+				struct wmi_disconnect_roam_params *req)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+send_idle_roam_params_tlv(wmi_unified_t wmi_handle,
+			  struct wmi_idle_roam_params *idle_roam_params)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
+			     struct wmi_roam_auth_status_params *params)
+{
+	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
+
+/**
+ * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params
+ * @wmi_handle: wmi handler
+ * @params: pointer to 11k offload params
+ *
+ * Return: 0 for success and non zero for failure
+ */
+static QDF_STATUS
+send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle,
+			 struct wmi_11k_offload_params *params)
+{
+	wmi_11k_offload_report_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS status;
+	uint8_t *buf_ptr;
+	wmi_neighbor_report_11k_offload_tlv_param
+					*neighbor_report_offload_params;
+	wmi_neighbor_report_offload *neighbor_report_offload;
+	uint32_t len = sizeof(*cmd);
+
+	if (params->offload_11k_bitmask &
+	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ)
+		len += WMI_TLV_HDR_SIZE +
+			sizeof(wmi_neighbor_report_11k_offload_tlv_param);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	cmd = (wmi_11k_offload_report_fixed_param *)buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+				wmi_11k_offload_report_fixed_param));
+
+	cmd->vdev_id = params->vdev_id;
+	cmd->offload_11k = params->offload_11k_bitmask;
+
+	if (params->offload_11k_bitmask &
+	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) {
+		buf_ptr += sizeof(wmi_11k_offload_report_fixed_param);
+
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			sizeof(wmi_neighbor_report_11k_offload_tlv_param));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+
+		neighbor_report_offload_params =
+			(wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr;
+		WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header,
+			WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param,
+			WMITLV_GET_STRUCT_TLVLEN(
+				wmi_neighbor_report_11k_offload_tlv_param));
+
+		neighbor_report_offload = &neighbor_report_offload_params->
+			neighbor_rep_ofld_params;
+
+		neighbor_report_offload->time_offset =
+			params->neighbor_report_params.time_offset;
+		neighbor_report_offload->low_rssi_offset =
+			params->neighbor_report_params.low_rssi_offset;
+		neighbor_report_offload->bmiss_count_trigger =
+			params->neighbor_report_params.bmiss_count_trigger;
+		neighbor_report_offload->per_threshold_offset =
+			params->neighbor_report_params.per_threshold_offset;
+		neighbor_report_offload->neighbor_report_cache_timeout =
+			params->neighbor_report_params.
+			neighbor_report_cache_timeout;
+		neighbor_report_offload->max_neighbor_report_req_cap =
+			params->neighbor_report_params.
+			max_neighbor_report_req_cap;
+		neighbor_report_offload->ssid.ssid_len =
+			params->neighbor_report_params.ssid.length;
+		qdf_mem_copy(neighbor_report_offload->ssid.ssid,
+			     &params->neighbor_report_params.ssid.mac_ssid,
+			     neighbor_report_offload->ssid.ssid_len);
+	}
+
+	wmi_mtrace(WMI_11K_OFFLOAD_REPORT_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_11K_OFFLOAD_REPORT_CMDID);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMI_LOGE("%s: failed to send 11k offload command %d",
+			 __func__, status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+/**
+ * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report
+ * command
+ * @wmi_handle: wmi handler
+ * @params: pointer to neighbor report invoke params
+ *
+ * Return: 0 for success and non zero for failure
+ */
+static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(
+		wmi_unified_t wmi_handle,
+		struct wmi_invoke_neighbor_report_params *params)
+{
+	wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd;
+	wmi_buf_t buf;
+	QDF_STATUS status;
+	uint8_t *buf_ptr;
+	uint32_t len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *)buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param,
+		 WMITLV_GET_STRUCT_TLVLEN(
+			wmi_11k_offload_invoke_neighbor_report_fixed_param));
+
+	cmd->vdev_id = params->vdev_id;
+	cmd->flags = params->send_resp_to_host;
+
+	cmd->ssid.ssid_len = params->ssid.length;
+	qdf_mem_copy(cmd->ssid.ssid,
+		     &params->ssid.mac_ssid,
+		     cmd->ssid.ssid_len);
+
+	wmi_mtrace(WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID, cmd->vdev_id, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf, len,
+				      WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMI_LOGE("%s: failed to send invoke neighbor report command %d",
+			 __func__, status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+
+void wmi_roam_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_roam_scan_offload_rssi_thresh_cmd =
+			send_roam_scan_offload_rssi_thresh_cmd_tlv;
+	ops->send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv;
+	ops->send_roam_scan_filter_cmd =
+			send_roam_scan_filter_cmd_tlv;
+	ops->send_roam_scan_offload_mode_cmd =
+			send_roam_scan_offload_mode_cmd_tlv;
+	ops->send_roam_scan_offload_ap_profile_cmd =
+			send_roam_scan_offload_ap_profile_cmd_tlv;
+	ops->send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv;
+	ops->send_roam_scan_offload_scan_period_cmd =
+			send_roam_scan_offload_scan_period_cmd_tlv;
+	ops->send_roam_scan_offload_chan_list_cmd =
+			send_roam_scan_offload_chan_list_cmd_tlv;
+	ops->send_roam_scan_offload_rssi_change_cmd =
+			send_roam_scan_offload_rssi_change_cmd_tlv;
+	ops->send_per_roam_config_cmd = send_per_roam_config_cmd_tlv;
+	ops->send_limit_off_chan_cmd = send_limit_off_chan_cmd_tlv;
+	ops->send_btm_config = send_btm_config_cmd_tlv;
+	ops->send_offload_11k_cmd = send_offload_11k_cmd_tlv;
+	ops->send_invoke_neighbor_report_cmd =
+			send_invoke_neighbor_report_cmd_tlv;
+	ops->send_roam_bss_load_config = send_roam_bss_load_config_tlv;
+	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);
+	wmi_ese_attach_tlv(wmi_handle);
+	wmi_roam_offload_attach_tlv(wmi_handle);
+	wmi_fils_sk_attach_tlv(wmi_handle);
+}
+