diff --git a/Kbuild b/Kbuild index b115c949a9..585bf022cc 100644 --- a/Kbuild +++ b/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) \ diff --git a/components/wmi/inc/wmi_unified_roam_api.h b/components/wmi/inc/wmi_unified_roam_api.h new file mode 100644 index 0000000000..ce019082e2 --- /dev/null +++ b/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 + +#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_ */ diff --git a/components/wmi/inc/wmi_unified_roam_param.h b/components/wmi/inc/wmi_unified_roam_param.h new file mode 100644 index 0000000000..8556cebbf4 --- /dev/null +++ b/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 + +/** + * 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_ */ diff --git a/components/wmi/src/wmi_unified_roam_api.c b/components/wmi/src/wmi_unified_roam_api.c new file mode 100644 index 0000000000..a102eaf2c4 --- /dev/null +++ b/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 +#include +#include +#include +#include + +#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 diff --git a/components/wmi/src/wmi_unified_roam_tlv.c b/components/wmi/src/wmi_unified_roam_tlv.c new file mode 100644 index 0000000000..307a6726c6 --- /dev/null +++ b/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 +#include +#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, + ¶ms->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, + ¶ms->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); +} +