xref: /wlan-driver/qcacld-3.0/components/wmi/src/wmi_unified_roam_tlv.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
6*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
7*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
8*5113495bSYour Name  *
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*5113495bSYour Name  */
17*5113495bSYour Name 
18*5113495bSYour Name /**
19*5113495bSYour Name  * DOC: Implement API's specific to roaming component.
20*5113495bSYour Name  */
21*5113495bSYour Name 
22*5113495bSYour Name #include <wmi_unified_priv.h>
23*5113495bSYour Name #include <wmi_unified_roam_api.h>
24*5113495bSYour Name #include <wmi_unified_roam_param.h>
25*5113495bSYour Name #include "wmi.h"
26*5113495bSYour Name #include "wlan_roam_debug.h"
27*5113495bSYour Name #include "ol_defines.h"
28*5113495bSYour Name #include "wlan_cm_roam_api.h"
29*5113495bSYour Name #include "wlan_mlme_api.h"
30*5113495bSYour Name #include "wlan_crypto_global_api.h"
31*5113495bSYour Name 
32*5113495bSYour Name #define WMI_MAC_TO_PDEV_MAP(x) ((x) + (1))
33*5113495bSYour Name #define WMI_PDEV_TO_MAC_MAP(x) ((x) - (1))
34*5113495bSYour Name 
35*5113495bSYour Name #ifdef FEATURE_LFR_SUBNET_DETECTION
36*5113495bSYour Name /**
37*5113495bSYour Name  * send_set_gateway_params_cmd_tlv() - set gateway parameters
38*5113495bSYour Name  * @wmi_handle: wmi handle
39*5113495bSYour Name  * @req: gateway parameter update request structure
40*5113495bSYour Name  *
41*5113495bSYour Name  * This function reads the incoming @req and fill in the destination
42*5113495bSYour Name  * WMI structure and sends down the gateway configs down to the firmware
43*5113495bSYour Name  *
44*5113495bSYour Name  * Return: QDF_STATUS
45*5113495bSYour Name  */
send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle,struct gateway_update_req_param * req)46*5113495bSYour Name static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle,
47*5113495bSYour Name 				struct gateway_update_req_param *req)
48*5113495bSYour Name {
49*5113495bSYour Name 	wmi_roam_subnet_change_config_fixed_param *cmd;
50*5113495bSYour Name 	wmi_buf_t buf;
51*5113495bSYour Name 	QDF_STATUS ret;
52*5113495bSYour Name 	int len = sizeof(*cmd);
53*5113495bSYour Name 
54*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
55*5113495bSYour Name 	if (!buf)
56*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
57*5113495bSYour Name 
58*5113495bSYour Name 	cmd = (wmi_roam_subnet_change_config_fixed_param *)wmi_buf_data(buf);
59*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
60*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param,
61*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
62*5113495bSYour Name 			wmi_roam_subnet_change_config_fixed_param));
63*5113495bSYour Name 
64*5113495bSYour Name 	cmd->vdev_id = req->vdev_id;
65*5113495bSYour Name 	qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr,
66*5113495bSYour Name 		     QDF_IPV4_ADDR_SIZE);
67*5113495bSYour Name 	qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr,
68*5113495bSYour Name 		     QDF_IPV6_ADDR_SIZE);
69*5113495bSYour Name 	WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes,
70*5113495bSYour Name 				   &cmd->inet_gw_mac_addr);
71*5113495bSYour Name 	cmd->max_retries = req->max_retries;
72*5113495bSYour Name 	cmd->timeout = req->timeout;
73*5113495bSYour Name 	cmd->num_skip_subnet_change_detection_bssid_list = 0;
74*5113495bSYour Name 	cmd->flag = 0;
75*5113495bSYour Name 	if (req->ipv4_addr_type)
76*5113495bSYour Name 		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag);
77*5113495bSYour Name 
78*5113495bSYour Name 	if (req->ipv6_addr_type)
79*5113495bSYour Name 		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag);
80*5113495bSYour Name 
81*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID, cmd->vdev_id, 0);
82*5113495bSYour Name 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
83*5113495bSYour Name 				   WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID);
84*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
85*5113495bSYour Name 		wmi_err("Failed to send gw config parameter to fw, ret: %d",
86*5113495bSYour Name 			ret);
87*5113495bSYour Name 		wmi_buf_free(buf);
88*5113495bSYour Name 	}
89*5113495bSYour Name 
90*5113495bSYour Name 	return ret;
91*5113495bSYour Name }
92*5113495bSYour Name 
wmi_lfr_subnet_detection_attach_tlv(struct wmi_unified * wmi_handle)93*5113495bSYour Name void wmi_lfr_subnet_detection_attach_tlv(struct wmi_unified *wmi_handle)
94*5113495bSYour Name {
95*5113495bSYour Name 	struct wmi_ops *ops = wmi_handle->ops;
96*5113495bSYour Name 
97*5113495bSYour Name 	ops->send_set_gateway_params_cmd = send_set_gateway_params_cmd_tlv;
98*5113495bSYour Name }
99*5113495bSYour Name #endif /* FEATURE_LFR_SUBNET_DETECTION */
100*5113495bSYour Name 
101*5113495bSYour Name #ifdef FEATURE_RSSI_MONITOR
102*5113495bSYour Name /**
103*5113495bSYour Name  * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring
104*5113495bSYour Name  * @wmi_handle: wmi handle
105*5113495bSYour Name  * @req: rssi monitoring request structure
106*5113495bSYour Name  *
107*5113495bSYour Name  * This function reads the incoming @req and fill in the destination
108*5113495bSYour Name  * WMI structure and send down the rssi monitoring configs down to the firmware
109*5113495bSYour Name  *
110*5113495bSYour Name  * Return: 0 on success; error number otherwise
111*5113495bSYour Name  */
send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle,struct rssi_monitor_param * req)112*5113495bSYour Name static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle,
113*5113495bSYour Name 					struct rssi_monitor_param *req)
114*5113495bSYour Name {
115*5113495bSYour Name 	wmi_rssi_breach_monitor_config_fixed_param *cmd;
116*5113495bSYour Name 	wmi_buf_t buf;
117*5113495bSYour Name 	QDF_STATUS ret;
118*5113495bSYour Name 	uint32_t len = sizeof(*cmd);
119*5113495bSYour Name 
120*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
121*5113495bSYour Name 	if (!buf)
122*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
123*5113495bSYour Name 
124*5113495bSYour Name 	cmd = (wmi_rssi_breach_monitor_config_fixed_param *)wmi_buf_data(buf);
125*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
126*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param,
127*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
128*5113495bSYour Name 			wmi_rssi_breach_monitor_config_fixed_param));
129*5113495bSYour Name 
130*5113495bSYour Name 	cmd->vdev_id = req->vdev_id;
131*5113495bSYour Name 	cmd->request_id = req->request_id;
132*5113495bSYour Name 	cmd->lo_rssi_reenable_hysteresis = 0;
133*5113495bSYour Name 	cmd->hi_rssi_reenable_histeresis = 0;
134*5113495bSYour Name 	cmd->min_report_interval = 0;
135*5113495bSYour Name 	cmd->max_num_report = 1;
136*5113495bSYour Name 	if (req->control) {
137*5113495bSYour Name 		/* enable one threshold for each min/max */
138*5113495bSYour Name 		cmd->enabled_bitmap = 0x09;
139*5113495bSYour Name 		cmd->low_rssi_breach_threshold[0] = req->min_rssi;
140*5113495bSYour Name 		cmd->hi_rssi_breach_threshold[0] = req->max_rssi;
141*5113495bSYour Name 	} else {
142*5113495bSYour Name 		cmd->enabled_bitmap = 0;
143*5113495bSYour Name 		cmd->low_rssi_breach_threshold[0] = 0;
144*5113495bSYour Name 		cmd->hi_rssi_breach_threshold[0] = 0;
145*5113495bSYour Name 	}
146*5113495bSYour Name 
147*5113495bSYour Name 	wmi_mtrace(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID, cmd->vdev_id, 0);
148*5113495bSYour Name 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
149*5113495bSYour Name 				   WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID);
150*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
151*5113495bSYour Name 		wmi_err("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID");
152*5113495bSYour Name 		wmi_buf_free(buf);
153*5113495bSYour Name 	}
154*5113495bSYour Name 
155*5113495bSYour Name 	wmi_debug("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW");
156*5113495bSYour Name 
157*5113495bSYour Name 	return ret;
158*5113495bSYour Name }
159*5113495bSYour Name 
wmi_rssi_monitor_attach_tlv(struct wmi_unified * wmi_handle)160*5113495bSYour Name void wmi_rssi_monitor_attach_tlv(struct wmi_unified *wmi_handle)
161*5113495bSYour Name {
162*5113495bSYour Name 	struct wmi_ops *ops = wmi_handle->ops;
163*5113495bSYour Name 
164*5113495bSYour Name 	ops->send_set_rssi_monitoring_cmd = send_set_rssi_monitoring_cmd_tlv;
165*5113495bSYour Name }
166*5113495bSYour Name #endif /* FEATURE_RSSI_MONITOR */
167*5113495bSYour Name 
168*5113495bSYour Name /**
169*5113495bSYour Name  * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload
170*5113495bSYour Name  *                                                rssi threshold
171*5113495bSYour Name  * @wmi_handle: wmi handle
172*5113495bSYour Name  * @roam_req:   Roaming request buffer
173*5113495bSYour Name  *
174*5113495bSYour Name  * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
175*5113495bSYour Name  *
176*5113495bSYour Name  * Return: QDF status
177*5113495bSYour Name  */
send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle,struct wlan_roam_offload_scan_rssi_params * roam_req)178*5113495bSYour Name static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(
179*5113495bSYour Name 			wmi_unified_t wmi_handle,
180*5113495bSYour Name 			struct wlan_roam_offload_scan_rssi_params *roam_req)
181*5113495bSYour Name {
182*5113495bSYour Name 	wmi_buf_t buf = NULL;
183*5113495bSYour Name 	QDF_STATUS status;
184*5113495bSYour Name 	int len;
185*5113495bSYour Name 	uint8_t *buf_ptr;
186*5113495bSYour Name 	wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp;
187*5113495bSYour Name 	wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL;
188*5113495bSYour Name 	wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL;
189*5113495bSYour Name 	wmi_roam_dense_thres_param *dense_thresholds = NULL;
190*5113495bSYour Name 	wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL;
191*5113495bSYour Name 	wmi_roam_data_rssi_roaming_param *data_rssi_param = NULL;
192*5113495bSYour Name 
193*5113495bSYour Name 	len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
194*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
195*5113495bSYour Name 	len += sizeof(wmi_roam_scan_extended_threshold_param);
196*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE;
197*5113495bSYour Name 	len += sizeof(wmi_roam_earlystop_rssi_thres_param);
198*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/
199*5113495bSYour Name 	len += sizeof(wmi_roam_dense_thres_param);
200*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/
201*5113495bSYour Name 	len += sizeof(wmi_roam_bg_scan_roaming_param);
202*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE; /* TLV for data RSSI*/
203*5113495bSYour Name 	len += sizeof(wmi_roam_data_rssi_roaming_param);
204*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
205*5113495bSYour Name 	if (!buf)
206*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
207*5113495bSYour Name 
208*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
209*5113495bSYour Name 	rssi_threshold_fp =
210*5113495bSYour Name 		(wmi_roam_scan_rssi_threshold_fixed_param *)buf_ptr;
211*5113495bSYour Name 	WMITLV_SET_HDR(
212*5113495bSYour Name 		&rssi_threshold_fp->tlv_header,
213*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param,
214*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN
215*5113495bSYour Name 				(wmi_roam_scan_rssi_threshold_fixed_param));
216*5113495bSYour Name 	/* fill in threshold values */
217*5113495bSYour Name 	rssi_threshold_fp->vdev_id = roam_req->vdev_id;
218*5113495bSYour Name 	rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh;
219*5113495bSYour Name 	rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff;
220*5113495bSYour Name 	rssi_threshold_fp->hirssi_scan_max_count =
221*5113495bSYour Name 			roam_req->hi_rssi_scan_max_count;
222*5113495bSYour Name 	rssi_threshold_fp->hirssi_scan_delta =
223*5113495bSYour Name 			roam_req->hi_rssi_scan_rssi_delta;
224*5113495bSYour Name 	rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub;
225*5113495bSYour Name 	rssi_threshold_fp->rssi_thresh_offset_5g =
226*5113495bSYour Name 		roam_req->rssi_thresh_offset_5g;
227*5113495bSYour Name 	rssi_threshold_fp->flags = roam_req->flags;
228*5113495bSYour Name 
229*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
230*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr,
231*5113495bSYour Name 		       WMITLV_TAG_ARRAY_STRUC,
232*5113495bSYour Name 		       sizeof(wmi_roam_scan_extended_threshold_param));
233*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
234*5113495bSYour Name 	ext_thresholds = (wmi_roam_scan_extended_threshold_param *)buf_ptr;
235*5113495bSYour Name 
236*5113495bSYour Name 	ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g;
237*5113495bSYour Name 	if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT)
238*5113495bSYour Name 		ext_thresholds->boost_threshold_5g =
239*5113495bSYour Name 					roam_req->boost_threshold_5g;
240*5113495bSYour Name 
241*5113495bSYour Name 	ext_thresholds->boost_algorithm_5g =
242*5113495bSYour Name 		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
243*5113495bSYour Name 	ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g;
244*5113495bSYour Name 	ext_thresholds->penalty_algorithm_5g =
245*5113495bSYour Name 		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
246*5113495bSYour Name 	ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g;
247*5113495bSYour Name 	ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g;
248*5113495bSYour Name 	ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g;
249*5113495bSYour Name 	ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold;
250*5113495bSYour Name 
251*5113495bSYour Name 	WMITLV_SET_HDR(&ext_thresholds->tlv_header,
252*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param,
253*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
254*5113495bSYour Name 				(wmi_roam_scan_extended_threshold_param));
255*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param);
256*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr,
257*5113495bSYour Name 		       WMITLV_TAG_ARRAY_STRUC,
258*5113495bSYour Name 		       sizeof(wmi_roam_earlystop_rssi_thres_param));
259*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
260*5113495bSYour Name 	early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *)buf_ptr;
261*5113495bSYour Name 	early_stop_thresholds->roam_earlystop_thres_min =
262*5113495bSYour Name 		roam_req->roam_earlystop_thres_min;
263*5113495bSYour Name 	early_stop_thresholds->roam_earlystop_thres_max =
264*5113495bSYour Name 		roam_req->roam_earlystop_thres_max;
265*5113495bSYour Name 	WMITLV_SET_HDR(&early_stop_thresholds->tlv_header,
266*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param,
267*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
268*5113495bSYour Name 				(wmi_roam_earlystop_rssi_thres_param));
269*5113495bSYour Name 
270*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param);
271*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
272*5113495bSYour Name 		       sizeof(wmi_roam_dense_thres_param));
273*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
274*5113495bSYour Name 	dense_thresholds = (wmi_roam_dense_thres_param *)buf_ptr;
275*5113495bSYour Name 	dense_thresholds->roam_dense_rssi_thres_offset =
276*5113495bSYour Name 			roam_req->dense_rssi_thresh_offset;
277*5113495bSYour Name 	dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt;
278*5113495bSYour Name 	dense_thresholds->roam_dense_traffic_thres =
279*5113495bSYour Name 			roam_req->traffic_threshold;
280*5113495bSYour Name 	dense_thresholds->roam_dense_status = roam_req->initial_dense_status;
281*5113495bSYour Name 	WMITLV_SET_HDR(&dense_thresholds->tlv_header,
282*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_dense_thres_param,
283*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_dense_thres_param));
284*5113495bSYour Name 
285*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_dense_thres_param);
286*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
287*5113495bSYour Name 		       sizeof(wmi_roam_bg_scan_roaming_param));
288*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
289*5113495bSYour Name 	bg_scan_params = (wmi_roam_bg_scan_roaming_param *)buf_ptr;
290*5113495bSYour Name 	bg_scan_params->roam_bg_scan_bad_rssi_thresh =
291*5113495bSYour Name 		roam_req->bg_scan_bad_rssi_thresh;
292*5113495bSYour Name 	bg_scan_params->roam_bg_scan_client_bitmap =
293*5113495bSYour Name 		roam_req->bg_scan_client_bitmap;
294*5113495bSYour Name 	bg_scan_params->bad_rssi_thresh_offset_2g =
295*5113495bSYour Name 		roam_req->roam_bad_rssi_thresh_offset_2g;
296*5113495bSYour Name 
297*5113495bSYour Name 	bg_scan_params->flags = 0;
298*5113495bSYour Name 	if (roam_req->roam_bad_rssi_thresh_offset_2g)
299*5113495bSYour Name 		bg_scan_params->flags |= WMI_ROAM_BG_SCAN_FLAGS_2G_TO_5G_ONLY;
300*5113495bSYour Name 	WMITLV_SET_HDR(&bg_scan_params->tlv_header,
301*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param,
302*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
303*5113495bSYour Name 		       (wmi_roam_bg_scan_roaming_param));
304*5113495bSYour Name 
305*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_bg_scan_roaming_param);
306*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
307*5113495bSYour Name 		       sizeof(wmi_roam_data_rssi_roaming_param));
308*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
309*5113495bSYour Name 	data_rssi_param = (wmi_roam_data_rssi_roaming_param *)buf_ptr;
310*5113495bSYour Name 	data_rssi_param->flags =
311*5113495bSYour Name 		roam_req->roam_data_rssi_threshold_triggers;
312*5113495bSYour Name 	data_rssi_param->roam_data_rssi_thres =
313*5113495bSYour Name 		roam_req->roam_data_rssi_threshold;
314*5113495bSYour Name 	data_rssi_param->rx_inactivity_ms =
315*5113495bSYour Name 		roam_req->rx_data_inactivity_time;
316*5113495bSYour Name 	WMITLV_SET_HDR(&data_rssi_param->tlv_header,
317*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_data_rssi_roaming_param,
318*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
319*5113495bSYour Name 		       (wmi_roam_data_rssi_roaming_param));
320*5113495bSYour Name 	wmi_debug("vdev %d Data rssi threshold: %d, triggers: 0x%x, rx time: %d, rssi_thresh:%d",
321*5113495bSYour Name 		  rssi_threshold_fp->vdev_id,
322*5113495bSYour Name 		  data_rssi_param->roam_data_rssi_thres,
323*5113495bSYour Name 		  data_rssi_param->flags,
324*5113495bSYour Name 		  data_rssi_param->rx_inactivity_ms,
325*5113495bSYour Name 		  rssi_threshold_fp->roam_scan_rssi_thresh);
326*5113495bSYour Name 
327*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_SCAN_RSSI_THRESHOLD, NO_SESSION, 0);
328*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf,
329*5113495bSYour Name 				      len, WMI_ROAM_SCAN_RSSI_THRESHOLD);
330*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
331*5113495bSYour Name 		wmi_err("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d",
332*5113495bSYour Name 			status);
333*5113495bSYour Name 		wmi_buf_free(buf);
334*5113495bSYour Name 	}
335*5113495bSYour Name 
336*5113495bSYour Name 	return status;
337*5113495bSYour Name }
338*5113495bSYour Name 
339*5113495bSYour Name /**
340*5113495bSYour Name  * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period
341*5113495bSYour Name  * @wmi_handle: wmi handle
342*5113495bSYour Name  * @param: roam scan parameters to be sent to firmware
343*5113495bSYour Name  *
344*5113495bSYour Name  * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
345*5113495bSYour Name  *
346*5113495bSYour Name  * Return: QDF status
347*5113495bSYour Name  */
348*5113495bSYour Name static QDF_STATUS
send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle,struct wlan_roam_scan_period_params * param)349*5113495bSYour Name send_roam_scan_offload_scan_period_cmd_tlv(
350*5113495bSYour Name 		wmi_unified_t wmi_handle,
351*5113495bSYour Name 		struct wlan_roam_scan_period_params *param)
352*5113495bSYour Name {
353*5113495bSYour Name 	QDF_STATUS status;
354*5113495bSYour Name 	wmi_buf_t buf = NULL;
355*5113495bSYour Name 	int len;
356*5113495bSYour Name 	uint8_t *buf_ptr;
357*5113495bSYour Name 	wmi_roam_scan_period_fixed_param *scan_period_fp;
358*5113495bSYour Name 
359*5113495bSYour Name 	/* Send scan period values */
360*5113495bSYour Name 	len = sizeof(wmi_roam_scan_period_fixed_param);
361*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
362*5113495bSYour Name 	if (!buf)
363*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
364*5113495bSYour Name 
365*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
366*5113495bSYour Name 	scan_period_fp = (wmi_roam_scan_period_fixed_param *)buf_ptr;
367*5113495bSYour Name 	WMITLV_SET_HDR(&scan_period_fp->tlv_header,
368*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param,
369*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
370*5113495bSYour Name 			       (wmi_roam_scan_period_fixed_param));
371*5113495bSYour Name 	/* fill in scan period values */
372*5113495bSYour Name 	scan_period_fp->vdev_id = param->vdev_id;
373*5113495bSYour Name 	scan_period_fp->roam_scan_period = param->scan_period;
374*5113495bSYour Name 	scan_period_fp->roam_scan_age = param->scan_age;
375*5113495bSYour Name 	scan_period_fp->inactivity_time_period =
376*5113495bSYour Name 			param->roam_scan_inactivity_time;
377*5113495bSYour Name 	scan_period_fp->roam_inactive_count =
378*5113495bSYour Name 			param->roam_inactive_data_packet_count;
379*5113495bSYour Name 	/* Firmware expects the full scan period in msec whereas host
380*5113495bSYour Name 	 * provides the same in seconds.
381*5113495bSYour Name 	 * Convert it to msec and send to firmware
382*5113495bSYour Name 	 */
383*5113495bSYour Name 	scan_period_fp->roam_full_scan_period = param->full_scan_period * 1000;
384*5113495bSYour Name 
385*5113495bSYour Name 	wmi_debug("roam_scan_period=%d, roam_scan_age=%d, full_scan_period= %u",
386*5113495bSYour Name 		  scan_period_fp->roam_scan_period,
387*5113495bSYour Name 		  scan_period_fp->roam_scan_age,
388*5113495bSYour Name 		  scan_period_fp->roam_full_scan_period);
389*5113495bSYour Name 
390*5113495bSYour Name 	wmi_debug("inactiviy time:%d inactive cnt:%d",
391*5113495bSYour Name 		  scan_period_fp->inactivity_time_period,
392*5113495bSYour Name 		  scan_period_fp->roam_inactive_count);
393*5113495bSYour Name 
394*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_SCAN_PERIOD, NO_SESSION, 0);
395*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
396*5113495bSYour Name 				      WMI_ROAM_SCAN_PERIOD);
397*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
398*5113495bSYour Name 		wmi_buf_free(buf);
399*5113495bSYour Name 		return status;
400*5113495bSYour Name 	}
401*5113495bSYour Name 
402*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
403*5113495bSYour Name }
404*5113495bSYour Name 
send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle,struct wlan_roam_mawc_params * params)405*5113495bSYour Name static QDF_STATUS send_roam_mawc_params_cmd_tlv(
406*5113495bSYour Name 				wmi_unified_t wmi_handle,
407*5113495bSYour Name 				struct wlan_roam_mawc_params *params)
408*5113495bSYour Name {
409*5113495bSYour Name 	wmi_buf_t buf = NULL;
410*5113495bSYour Name 	QDF_STATUS status;
411*5113495bSYour Name 	int len;
412*5113495bSYour Name 	uint8_t *buf_ptr;
413*5113495bSYour Name 	wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params;
414*5113495bSYour Name 
415*5113495bSYour Name 	len = sizeof(*wmi_roam_mawc_params);
416*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
417*5113495bSYour Name 	if (!buf)
418*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
419*5113495bSYour Name 
420*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
421*5113495bSYour Name 	wmi_roam_mawc_params =
422*5113495bSYour Name 		(wmi_roam_configure_mawc_cmd_fixed_param *)buf_ptr;
423*5113495bSYour Name 	WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header,
424*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param,
425*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
426*5113495bSYour Name 			       (wmi_roam_configure_mawc_cmd_fixed_param));
427*5113495bSYour Name 	wmi_roam_mawc_params->vdev_id = params->vdev_id;
428*5113495bSYour Name 	if (params->enable)
429*5113495bSYour Name 		wmi_roam_mawc_params->enable = 1;
430*5113495bSYour Name 	else
431*5113495bSYour Name 		wmi_roam_mawc_params->enable = 0;
432*5113495bSYour Name 	wmi_roam_mawc_params->traffic_load_threshold =
433*5113495bSYour Name 		params->traffic_load_threshold;
434*5113495bSYour Name 	wmi_roam_mawc_params->best_ap_rssi_threshold =
435*5113495bSYour Name 		params->best_ap_rssi_threshold;
436*5113495bSYour Name 	wmi_roam_mawc_params->rssi_stationary_high_adjust =
437*5113495bSYour Name 		params->rssi_stationary_high_adjust;
438*5113495bSYour Name 	wmi_roam_mawc_params->rssi_stationary_low_adjust =
439*5113495bSYour Name 		params->rssi_stationary_low_adjust;
440*5113495bSYour Name 	wmi_debug("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d",
441*5113495bSYour Name 		wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id,
442*5113495bSYour Name 		wmi_roam_mawc_params->traffic_load_threshold,
443*5113495bSYour Name 		wmi_roam_mawc_params->best_ap_rssi_threshold,
444*5113495bSYour Name 		wmi_roam_mawc_params->rssi_stationary_high_adjust,
445*5113495bSYour Name 		wmi_roam_mawc_params->rssi_stationary_low_adjust);
446*5113495bSYour Name 
447*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_CONFIGURE_MAWC_CMDID, NO_SESSION, 0);
448*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf,
449*5113495bSYour Name 				      len, WMI_ROAM_CONFIGURE_MAWC_CMDID);
450*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
451*5113495bSYour Name 		wmi_err("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d",
452*5113495bSYour Name 			status);
453*5113495bSYour Name 		wmi_buf_free(buf);
454*5113495bSYour Name 		return status;
455*5113495bSYour Name 	}
456*5113495bSYour Name 
457*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
458*5113495bSYour Name }
459*5113495bSYour Name 
460*5113495bSYour Name /**
461*5113495bSYour Name  * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming
462*5113495bSYour Name  * @wmi_handle:     wmi handle
463*5113495bSYour Name  * @roam_req:       Request which contains the filters
464*5113495bSYour Name  *
465*5113495bSYour Name  * There are filters such as allowlist, denylist and preferred
466*5113495bSYour Name  * list that need to be applied to the scan results to form the
467*5113495bSYour Name  * probable candidates for roaming.
468*5113495bSYour Name  *
469*5113495bSYour Name  * Return: Return success upon successfully passing the
470*5113495bSYour Name  *         parameters to the firmware, otherwise failure.
471*5113495bSYour Name  */
send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle,struct roam_scan_filter_params * roam_req)472*5113495bSYour Name static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle,
473*5113495bSYour Name 				struct roam_scan_filter_params *roam_req)
474*5113495bSYour Name {
475*5113495bSYour Name 	wmi_buf_t buf = NULL;
476*5113495bSYour Name 	QDF_STATUS status;
477*5113495bSYour Name 	uint32_t i;
478*5113495bSYour Name 	uint32_t len, blist_len = 0;
479*5113495bSYour Name 	uint8_t *buf_ptr;
480*5113495bSYour Name 	wmi_roam_filter_fixed_param *roam_filter;
481*5113495bSYour Name 	uint8_t *bssid_src_ptr = NULL;
482*5113495bSYour Name 	wmi_mac_addr *bssid_dst_ptr = NULL;
483*5113495bSYour Name 	wmi_ssid *ssid_ptr = NULL;
484*5113495bSYour Name 	uint32_t *bssid_preferred_factor_ptr = NULL;
485*5113495bSYour Name 	wmi_roam_lca_disallow_config_tlv_param *blist_param;
486*5113495bSYour Name 	wmi_roam_rssi_rejection_oce_config_param *rssi_rej;
487*5113495bSYour Name 
488*5113495bSYour Name 	len = sizeof(wmi_roam_filter_fixed_param);
489*5113495bSYour Name 
490*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE;
491*5113495bSYour Name 	if (roam_req->num_bssid_deny_list)
492*5113495bSYour Name 		len += roam_req->num_bssid_deny_list * sizeof(wmi_mac_addr);
493*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE;
494*5113495bSYour Name 	if (roam_req->num_ssid_allow_list)
495*5113495bSYour Name 		len += roam_req->num_ssid_allow_list * sizeof(wmi_ssid);
496*5113495bSYour Name 	len += 2 * WMI_TLV_HDR_SIZE;
497*5113495bSYour Name 	if (roam_req->num_bssid_preferred_list) {
498*5113495bSYour Name 		len += (roam_req->num_bssid_preferred_list *
499*5113495bSYour Name 			sizeof(wmi_mac_addr));
500*5113495bSYour Name 		len += roam_req->num_bssid_preferred_list * sizeof(uint32_t);
501*5113495bSYour Name 	}
502*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE;
503*5113495bSYour Name 	if (roam_req->lca_disallow_config_present) {
504*5113495bSYour Name 		len += sizeof(*blist_param);
505*5113495bSYour Name 		blist_len = sizeof(*blist_param);
506*5113495bSYour Name 	}
507*5113495bSYour Name 
508*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE;
509*5113495bSYour Name 	if (roam_req->num_rssi_rejection_ap)
510*5113495bSYour Name 		len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej);
511*5113495bSYour Name 
512*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
513*5113495bSYour Name 	if (!buf)
514*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
515*5113495bSYour Name 
516*5113495bSYour Name 	buf_ptr = (u_int8_t *)wmi_buf_data(buf);
517*5113495bSYour Name 	roam_filter = (wmi_roam_filter_fixed_param *)buf_ptr;
518*5113495bSYour Name 	WMITLV_SET_HDR(&roam_filter->tlv_header,
519*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param,
520*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param));
521*5113495bSYour Name 	/* fill in fixed values */
522*5113495bSYour Name 	roam_filter->vdev_id = roam_req->vdev_id;
523*5113495bSYour Name 	roam_filter->flags = 0;
524*5113495bSYour Name 	roam_filter->op_bitmap = roam_req->op_bitmap;
525*5113495bSYour Name 	roam_filter->num_bssid_black_list = roam_req->num_bssid_deny_list;
526*5113495bSYour Name 	roam_filter->num_ssid_white_list = roam_req->num_ssid_allow_list;
527*5113495bSYour Name 	roam_filter->num_bssid_preferred_list =
528*5113495bSYour Name 			roam_req->num_bssid_preferred_list;
529*5113495bSYour Name 	roam_filter->num_rssi_rejection_ap =
530*5113495bSYour Name 			roam_req->num_rssi_rejection_ap;
531*5113495bSYour Name 	roam_filter->delta_rssi = roam_req->delta_rssi;
532*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_filter_fixed_param);
533*5113495bSYour Name 
534*5113495bSYour Name 	WMITLV_SET_HDR((buf_ptr),
535*5113495bSYour Name 		WMITLV_TAG_ARRAY_FIXED_STRUC,
536*5113495bSYour Name 		(roam_req->num_bssid_deny_list * sizeof(wmi_mac_addr)));
537*5113495bSYour Name 	bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list;
538*5113495bSYour Name 	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
539*5113495bSYour Name 	for (i = 0; i < roam_req->num_bssid_deny_list; i++) {
540*5113495bSYour Name 		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr);
541*5113495bSYour Name 		bssid_src_ptr += ATH_MAC_LEN;
542*5113495bSYour Name 		bssid_dst_ptr++;
543*5113495bSYour Name 	}
544*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE +
545*5113495bSYour Name 		(roam_req->num_bssid_deny_list * sizeof(wmi_mac_addr));
546*5113495bSYour Name 	WMITLV_SET_HDR((buf_ptr),
547*5113495bSYour Name 		       WMITLV_TAG_ARRAY_FIXED_STRUC,
548*5113495bSYour Name 		       (roam_req->num_ssid_allow_list * sizeof(wmi_ssid)));
549*5113495bSYour Name 	ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE);
550*5113495bSYour Name 	for (i = 0; i < roam_req->num_ssid_allow_list; i++) {
551*5113495bSYour Name 		qdf_mem_copy(&ssid_ptr->ssid,
552*5113495bSYour Name 			&roam_req->ssid_allowed_list[i].ssid,
553*5113495bSYour Name 			roam_req->ssid_allowed_list[i].length);
554*5113495bSYour Name 		ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length;
555*5113495bSYour Name 		ssid_ptr++;
556*5113495bSYour Name 	}
557*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_allow_list *
558*5113495bSYour Name 							sizeof(wmi_ssid));
559*5113495bSYour Name 	WMITLV_SET_HDR((buf_ptr),
560*5113495bSYour Name 		WMITLV_TAG_ARRAY_FIXED_STRUC,
561*5113495bSYour Name 		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)));
562*5113495bSYour Name 	bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored;
563*5113495bSYour Name 	bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
564*5113495bSYour Name 	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
565*5113495bSYour Name 		WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr,
566*5113495bSYour Name 					   (wmi_mac_addr *)bssid_dst_ptr);
567*5113495bSYour Name 		bssid_src_ptr += ATH_MAC_LEN;
568*5113495bSYour Name 		bssid_dst_ptr++;
569*5113495bSYour Name 	}
570*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE +
571*5113495bSYour Name 		(roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr));
572*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
573*5113495bSYour Name 		(roam_req->num_bssid_preferred_list * sizeof(uint32_t)));
574*5113495bSYour Name 	bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
575*5113495bSYour Name 	for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
576*5113495bSYour Name 		*bssid_preferred_factor_ptr =
577*5113495bSYour Name 			roam_req->bssid_favored_factor[i];
578*5113495bSYour Name 		bssid_preferred_factor_ptr++;
579*5113495bSYour Name 	}
580*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE +
581*5113495bSYour Name 		(roam_req->num_bssid_preferred_list * sizeof(uint32_t));
582*5113495bSYour Name 
583*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr,
584*5113495bSYour Name 			WMITLV_TAG_ARRAY_STRUC, blist_len);
585*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
586*5113495bSYour Name 	if (roam_req->lca_disallow_config_present) {
587*5113495bSYour Name 		blist_param =
588*5113495bSYour Name 			(wmi_roam_lca_disallow_config_tlv_param *)buf_ptr;
589*5113495bSYour Name 		WMITLV_SET_HDR(&blist_param->tlv_header,
590*5113495bSYour Name 			WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param,
591*5113495bSYour Name 			WMITLV_GET_STRUCT_TLVLEN(
592*5113495bSYour Name 				wmi_roam_lca_disallow_config_tlv_param));
593*5113495bSYour Name 
594*5113495bSYour Name 		blist_param->disallow_duration = roam_req->disallow_duration;
595*5113495bSYour Name 		blist_param->rssi_channel_penalization =
596*5113495bSYour Name 				roam_req->rssi_channel_penalization;
597*5113495bSYour Name 		blist_param->num_disallowed_aps = roam_req->num_disallowed_aps;
598*5113495bSYour Name 		blist_param->disallow_lca_enable_source_bitmap =
599*5113495bSYour Name 			(WMI_ROAM_LCA_DISALLOW_SOURCE_PER |
600*5113495bSYour Name 			WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND);
601*5113495bSYour Name 		buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param));
602*5113495bSYour Name 	}
603*5113495bSYour Name 
604*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr,
605*5113495bSYour Name 		       WMITLV_TAG_ARRAY_STRUC,
606*5113495bSYour Name 		       (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej)));
607*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
608*5113495bSYour Name 	for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) {
609*5113495bSYour Name 		rssi_rej =
610*5113495bSYour Name 		(wmi_roam_rssi_rejection_oce_config_param *)buf_ptr;
611*5113495bSYour Name 
612*5113495bSYour Name 		WMITLV_SET_HDR(&rssi_rej->tlv_header,
613*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param,
614*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(wmi_roam_rssi_rejection_oce_config_param));
615*5113495bSYour Name 
616*5113495bSYour Name 		WMI_CHAR_ARRAY_TO_MAC_ADDR(
617*5113495bSYour Name 			roam_req->rssi_rejection_ap[i].bssid.bytes,
618*5113495bSYour Name 			&rssi_rej->bssid);
619*5113495bSYour Name 		rssi_rej->remaining_disallow_duration =
620*5113495bSYour Name 			roam_req->rssi_rejection_ap[i].reject_duration;
621*5113495bSYour Name 		rssi_rej->requested_rssi =
622*5113495bSYour Name 			(int32_t)roam_req->rssi_rejection_ap[i].expected_rssi;
623*5113495bSYour Name 		buf_ptr +=
624*5113495bSYour Name 			(sizeof(wmi_roam_rssi_rejection_oce_config_param));
625*5113495bSYour Name 	}
626*5113495bSYour Name 
627*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_FILTER_CMDID, NO_SESSION, 0);
628*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf,
629*5113495bSYour Name 				      len, WMI_ROAM_FILTER_CMDID);
630*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
631*5113495bSYour Name 		wmi_err("cmd WMI_ROAM_FILTER_CMDID returned Error %d",
632*5113495bSYour Name 			status);
633*5113495bSYour Name 		wmi_buf_free(buf);
634*5113495bSYour Name 	}
635*5113495bSYour Name 
636*5113495bSYour Name 	return status;
637*5113495bSYour Name }
638*5113495bSYour Name 
639*5113495bSYour Name #ifdef FEATURE_WLAN_ESE
640*5113495bSYour Name /**
641*5113495bSYour Name  * send_plm_stop_cmd_tlv() - plm stop request
642*5113495bSYour Name  * @wmi_handle: wmi handle
643*5113495bSYour Name  * @plm: plm request parameters
644*5113495bSYour Name  *
645*5113495bSYour Name  * This function request FW to stop PLM.
646*5113495bSYour Name  *
647*5113495bSYour Name  * Return: CDF status
648*5113495bSYour Name  */
send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle,const struct plm_req_params * plm)649*5113495bSYour Name static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle,
650*5113495bSYour Name 			  const struct plm_req_params *plm)
651*5113495bSYour Name {
652*5113495bSYour Name 	wmi_vdev_plmreq_stop_cmd_fixed_param *cmd;
653*5113495bSYour Name 	int32_t len;
654*5113495bSYour Name 	wmi_buf_t buf;
655*5113495bSYour Name 	uint8_t *buf_ptr;
656*5113495bSYour Name 	int ret;
657*5113495bSYour Name 
658*5113495bSYour Name 	len = sizeof(*cmd);
659*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
660*5113495bSYour Name 	if (!buf)
661*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
662*5113495bSYour Name 
663*5113495bSYour Name 	cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *)wmi_buf_data(buf);
664*5113495bSYour Name 
665*5113495bSYour Name 	buf_ptr = (uint8_t *)cmd;
666*5113495bSYour Name 
667*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
668*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param,
669*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
670*5113495bSYour Name 				(wmi_vdev_plmreq_stop_cmd_fixed_param));
671*5113495bSYour Name 
672*5113495bSYour Name 	cmd->vdev_id = plm->vdev_id;
673*5113495bSYour Name 
674*5113495bSYour Name 	cmd->meas_token = plm->meas_token;
675*5113495bSYour Name 	wmi_debug("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token);
676*5113495bSYour Name 
677*5113495bSYour Name 	wmi_mtrace(WMI_VDEV_PLMREQ_STOP_CMDID, cmd->vdev_id, 0);
678*5113495bSYour Name 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
679*5113495bSYour Name 				   WMI_VDEV_PLMREQ_STOP_CMDID);
680*5113495bSYour Name 	if (ret) {
681*5113495bSYour Name 		wmi_err("Failed to send plm stop wmi cmd");
682*5113495bSYour Name 		wmi_buf_free(buf);
683*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
684*5113495bSYour Name 	}
685*5113495bSYour Name 
686*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
687*5113495bSYour Name }
688*5113495bSYour Name 
689*5113495bSYour Name /**
690*5113495bSYour Name  * send_plm_start_cmd_tlv() - plm start request
691*5113495bSYour Name  * @wmi_handle: wmi handle
692*5113495bSYour Name  * @plm: plm request parameters
693*5113495bSYour Name  *
694*5113495bSYour Name  * This function request FW to start PLM.
695*5113495bSYour Name  *
696*5113495bSYour Name  * Return: CDF status
697*5113495bSYour Name  */
send_plm_start_cmd_tlv(wmi_unified_t wmi_handle,const struct plm_req_params * plm)698*5113495bSYour Name static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle,
699*5113495bSYour Name 					 const struct plm_req_params *plm)
700*5113495bSYour Name {
701*5113495bSYour Name 	wmi_vdev_plmreq_start_cmd_fixed_param *cmd;
702*5113495bSYour Name 	uint32_t *channel_list;
703*5113495bSYour Name 	int32_t len;
704*5113495bSYour Name 	wmi_buf_t buf;
705*5113495bSYour Name 	uint8_t *buf_ptr;
706*5113495bSYour Name 	uint8_t count;
707*5113495bSYour Name 	int ret;
708*5113495bSYour Name 
709*5113495bSYour Name 	/* TLV place holder for channel_list */
710*5113495bSYour Name 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
711*5113495bSYour Name 	len += sizeof(uint32_t) * plm->plm_num_ch;
712*5113495bSYour Name 
713*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
714*5113495bSYour Name 	if (!buf)
715*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
716*5113495bSYour Name 
717*5113495bSYour Name 	cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *)wmi_buf_data(buf);
718*5113495bSYour Name 
719*5113495bSYour Name 	buf_ptr = (uint8_t *)cmd;
720*5113495bSYour Name 
721*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
722*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param,
723*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
724*5113495bSYour Name 			       (wmi_vdev_plmreq_start_cmd_fixed_param));
725*5113495bSYour Name 
726*5113495bSYour Name 	cmd->vdev_id = plm->vdev_id;
727*5113495bSYour Name 
728*5113495bSYour Name 	cmd->meas_token = plm->meas_token;
729*5113495bSYour Name 	cmd->dialog_token = plm->diag_token;
730*5113495bSYour Name 	cmd->number_bursts = plm->num_bursts;
731*5113495bSYour Name 	cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int);
732*5113495bSYour Name 	cmd->off_duration = plm->meas_duration;
733*5113495bSYour Name 	cmd->burst_cycle = plm->burst_len;
734*5113495bSYour Name 	cmd->tx_power = plm->desired_tx_pwr;
735*5113495bSYour Name 	WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac);
736*5113495bSYour Name 	cmd->num_chans = plm->plm_num_ch;
737*5113495bSYour Name 
738*5113495bSYour Name 	buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param);
739*5113495bSYour Name 
740*5113495bSYour Name 	wmi_debug("vdev: %d measu token: %d dialog_token: %d number_bursts: %d burst_interval: %d off_duration: %d burst_cycle: %d tx_power: %d Number of channels: %d",
741*5113495bSYour Name 		 cmd->vdev_id, cmd->meas_token, cmd->dialog_token,
742*5113495bSYour Name 		 cmd->number_bursts, cmd->burst_interval, cmd->off_duration,
743*5113495bSYour Name 		 cmd->burst_cycle, cmd->tx_power, cmd->num_chans);
744*5113495bSYour Name 
745*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
746*5113495bSYour Name 		       (cmd->num_chans * sizeof(uint32_t)));
747*5113495bSYour Name 
748*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
749*5113495bSYour Name 	if (cmd->num_chans) {
750*5113495bSYour Name 		channel_list = (uint32_t *)buf_ptr;
751*5113495bSYour Name 		for (count = 0; count < cmd->num_chans; count++) {
752*5113495bSYour Name 			channel_list[count] = plm->plm_ch_freq_list[count];
753*5113495bSYour Name 			wmi_debug("Ch[%d]: %d MHz", count, channel_list[count]);
754*5113495bSYour Name 		}
755*5113495bSYour Name 		buf_ptr += cmd->num_chans * sizeof(uint32_t);
756*5113495bSYour Name 	}
757*5113495bSYour Name 
758*5113495bSYour Name 	wmi_mtrace(WMI_VDEV_PLMREQ_START_CMDID, cmd->vdev_id, 0);
759*5113495bSYour Name 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
760*5113495bSYour Name 				   WMI_VDEV_PLMREQ_START_CMDID);
761*5113495bSYour Name 	if (ret) {
762*5113495bSYour Name 		wmi_err("Failed to send plm start wmi cmd");
763*5113495bSYour Name 		wmi_buf_free(buf);
764*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
765*5113495bSYour Name 	}
766*5113495bSYour Name 
767*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
768*5113495bSYour Name }
769*5113495bSYour Name 
wmi_ese_attach_tlv(wmi_unified_t wmi_handle)770*5113495bSYour Name void wmi_ese_attach_tlv(wmi_unified_t wmi_handle)
771*5113495bSYour Name {
772*5113495bSYour Name 	struct wmi_ops *ops = wmi_handle->ops;
773*5113495bSYour Name 
774*5113495bSYour Name 	ops->send_plm_stop_cmd = send_plm_stop_cmd_tlv;
775*5113495bSYour Name 	ops->send_plm_start_cmd = send_plm_start_cmd_tlv;
776*5113495bSYour Name }
777*5113495bSYour Name #endif /* FEATURE_WLAN_ESE */
778*5113495bSYour Name 
779*5113495bSYour Name /**
780*5113495bSYour Name  * convert_roam_trigger_reason() - Function to convert unified Roam trigger
781*5113495bSYour Name  * enum to TLV specific WMI_ROAM_TRIGGER_REASON_ID
782*5113495bSYour Name  * @trigger_reason: Roam trigger reason
783*5113495bSYour Name  *
784*5113495bSYour Name  * Return: WMI roam trigger reason
785*5113495bSYour Name  */
786*5113495bSYour Name static uint32_t
convert_roam_trigger_reason(enum roam_trigger_reason trigger_reason)787*5113495bSYour Name convert_roam_trigger_reason(enum roam_trigger_reason trigger_reason)
788*5113495bSYour Name {
789*5113495bSYour Name 	switch (trigger_reason) {
790*5113495bSYour Name 	case ROAM_TRIGGER_REASON_NONE:
791*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_NONE;
792*5113495bSYour Name 	case ROAM_TRIGGER_REASON_PER:
793*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_PER;
794*5113495bSYour Name 	case ROAM_TRIGGER_REASON_BMISS:
795*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_BMISS;
796*5113495bSYour Name 	case ROAM_TRIGGER_REASON_LOW_RSSI:
797*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_LOW_RSSI;
798*5113495bSYour Name 	case ROAM_TRIGGER_REASON_HIGH_RSSI:
799*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_HIGH_RSSI;
800*5113495bSYour Name 	case ROAM_TRIGGER_REASON_PERIODIC:
801*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_PERIODIC;
802*5113495bSYour Name 	case ROAM_TRIGGER_REASON_MAWC:
803*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_MAWC;
804*5113495bSYour Name 	case ROAM_TRIGGER_REASON_DENSE:
805*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_DENSE;
806*5113495bSYour Name 	case ROAM_TRIGGER_REASON_BACKGROUND:
807*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_BACKGROUND;
808*5113495bSYour Name 	case ROAM_TRIGGER_REASON_FORCED:
809*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_FORCED;
810*5113495bSYour Name 	case ROAM_TRIGGER_REASON_BTM:
811*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_BTM;
812*5113495bSYour Name 	case ROAM_TRIGGER_REASON_UNIT_TEST:
813*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_UNIT_TEST;
814*5113495bSYour Name 	case ROAM_TRIGGER_REASON_BSS_LOAD:
815*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_BSS_LOAD;
816*5113495bSYour Name 	case ROAM_TRIGGER_REASON_DEAUTH:
817*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_DEAUTH;
818*5113495bSYour Name 	case ROAM_TRIGGER_REASON_IDLE:
819*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_IDLE;
820*5113495bSYour Name 	case ROAM_TRIGGER_REASON_STA_KICKOUT:
821*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_STA_KICKOUT;
822*5113495bSYour Name 	case ROAM_TRIGGER_REASON_ESS_RSSI:
823*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_ESS_RSSI;
824*5113495bSYour Name 	case ROAM_TRIGGER_REASON_WTC_BTM:
825*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_WTC_BTM;
826*5113495bSYour Name 	case ROAM_TRIGGER_REASON_PMK_TIMEOUT:
827*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT;
828*5113495bSYour Name 	case ROAM_TRIGGER_REASON_BTC:
829*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_BTC;
830*5113495bSYour Name 	case ROAM_TRIGGER_REASON_MAX:
831*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_MAX;
832*5113495bSYour Name 	default:
833*5113495bSYour Name 		return WMI_ROAM_TRIGGER_REASON_NONE;
834*5113495bSYour Name 	}
835*5113495bSYour Name }
836*5113495bSYour Name 
837*5113495bSYour Name #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
wmi_get_roam_event_reason_string(uint32_t reason)838*5113495bSYour Name static char *wmi_get_roam_event_reason_string(uint32_t reason)
839*5113495bSYour Name {
840*5113495bSYour Name 	switch (reason) {
841*5113495bSYour Name 	case WMI_ROAM_REASON_INVALID:
842*5113495bSYour Name 		return "Default";
843*5113495bSYour Name 	case WMI_ROAM_REASON_BETTER_AP:
844*5113495bSYour Name 		return "Better AP";
845*5113495bSYour Name 	case WMI_ROAM_REASON_BMISS:
846*5113495bSYour Name 		return "BMISS";
847*5113495bSYour Name 	case WMI_ROAM_REASON_LOW_RSSI:
848*5113495bSYour Name 		return "Low Rssi";
849*5113495bSYour Name 	case WMI_ROAM_REASON_SUITABLE_AP:
850*5113495bSYour Name 		return "Suitable AP";
851*5113495bSYour Name 	case WMI_ROAM_REASON_HO_FAILED:
852*5113495bSYour Name 		return "Hand-off Failed";
853*5113495bSYour Name 	case WMI_ROAM_REASON_INVOKE_ROAM_FAIL:
854*5113495bSYour Name 		return "Roam Invoke failed";
855*5113495bSYour Name 	case WMI_ROAM_REASON_RSO_STATUS:
856*5113495bSYour Name 		return "RSO status";
857*5113495bSYour Name 	case WMI_ROAM_REASON_BTM:
858*5113495bSYour Name 		return "BTM";
859*5113495bSYour Name 	case WMI_ROAM_REASON_DEAUTH:
860*5113495bSYour Name 		return "Deauth";
861*5113495bSYour Name 	default:
862*5113495bSYour Name 		return "Invalid";
863*5113495bSYour Name 	}
864*5113495bSYour Name 
865*5113495bSYour Name 	return "Invalid";
866*5113495bSYour Name }
867*5113495bSYour Name 
868*5113495bSYour Name static enum roam_reason
wmi_convert_fw_reason_to_cm_reason(uint32_t reason)869*5113495bSYour Name wmi_convert_fw_reason_to_cm_reason(uint32_t reason)
870*5113495bSYour Name {
871*5113495bSYour Name 	switch (reason) {
872*5113495bSYour Name 	case WMI_ROAM_REASON_INVALID:
873*5113495bSYour Name 		return ROAM_REASON_INVALID;
874*5113495bSYour Name 	case WMI_ROAM_REASON_BETTER_AP:
875*5113495bSYour Name 		return ROAM_REASON_BETTER_AP;
876*5113495bSYour Name 	case WMI_ROAM_REASON_BMISS:
877*5113495bSYour Name 		return ROAM_REASON_BMISS;
878*5113495bSYour Name 	case WMI_ROAM_REASON_LOW_RSSI:
879*5113495bSYour Name 		return ROAM_REASON_LOW_RSSI;
880*5113495bSYour Name 	case WMI_ROAM_REASON_SUITABLE_AP:
881*5113495bSYour Name 		return ROAM_REASON_SUITABLE_AP;
882*5113495bSYour Name 	case WMI_ROAM_REASON_HO_FAILED:
883*5113495bSYour Name 		return ROAM_REASON_HO_FAILED;
884*5113495bSYour Name 	case WMI_ROAM_REASON_INVOKE_ROAM_FAIL:
885*5113495bSYour Name 		return ROAM_REASON_INVOKE_ROAM_FAIL;
886*5113495bSYour Name 	case WMI_ROAM_REASON_RSO_STATUS:
887*5113495bSYour Name 		return ROAM_REASON_RSO_STATUS;
888*5113495bSYour Name 	case WMI_ROAM_REASON_BTM:
889*5113495bSYour Name 		return ROAM_REASON_BTM;
890*5113495bSYour Name 	case WMI_ROAM_REASON_DEAUTH:
891*5113495bSYour Name 		return ROAM_REASON_DEAUTH;
892*5113495bSYour Name 	default:
893*5113495bSYour Name 		return ROAM_REASON_INVALID;
894*5113495bSYour Name 	}
895*5113495bSYour Name 
896*5113495bSYour Name 	return ROAM_REASON_INVALID;
897*5113495bSYour Name }
898*5113495bSYour Name 
899*5113495bSYour Name static enum cm_roam_notif
wmi_convert_fw_notif_to_cm_notif(uint32_t fw_notif)900*5113495bSYour Name wmi_convert_fw_notif_to_cm_notif(uint32_t fw_notif)
901*5113495bSYour Name {
902*5113495bSYour Name 	switch (fw_notif) {
903*5113495bSYour Name 	case WMI_ROAM_NOTIF_ROAM_START:
904*5113495bSYour Name 		return CM_ROAM_NOTIF_ROAM_START;
905*5113495bSYour Name 	case WMI_ROAM_NOTIF_ROAM_ABORT:
906*5113495bSYour Name 		return CM_ROAM_NOTIF_ROAM_ABORT;
907*5113495bSYour Name 	case WMI_ROAM_NOTIF_ROAM_REASSOC:
908*5113495bSYour Name 		return CM_ROAM_NOTIF_ROAM_REASSOC;
909*5113495bSYour Name 	case WMI_ROAM_NOTIF_SCAN_MODE_SUCCESS:
910*5113495bSYour Name 		return CM_ROAM_NOTIF_SCAN_MODE_SUCCESS;
911*5113495bSYour Name 	case WMI_ROAM_NOTIF_SCAN_MODE_FAIL:
912*5113495bSYour Name 		return CM_ROAM_NOTIF_SCAN_MODE_FAIL;
913*5113495bSYour Name 	case WMI_ROAM_NOTIF_DISCONNECT:
914*5113495bSYour Name 		return CM_ROAM_NOTIF_DISCONNECT;
915*5113495bSYour Name 	case WMI_ROAM_NOTIF_SUBNET_CHANGED:
916*5113495bSYour Name 		return CM_ROAM_NOTIF_SUBNET_CHANGED;
917*5113495bSYour Name 	case WMI_ROAM_NOTIF_SCAN_START:
918*5113495bSYour Name 		return CM_ROAM_NOTIF_SCAN_START;
919*5113495bSYour Name 	case WMI_ROAM_NOTIF_DEAUTH_RECV:
920*5113495bSYour Name 		return CM_ROAM_NOTIF_DEAUTH_RECV;
921*5113495bSYour Name 	case WMI_ROAM_NOTIF_DISASSOC_RECV:
922*5113495bSYour Name 		return CM_ROAM_NOTIF_DISASSOC_RECV;
923*5113495bSYour Name 	case WMI_ROAM_NOTIF_SCAN_MODE_SUCCESS_WITH_HO_FAIL:
924*5113495bSYour Name 		return CM_ROAM_NOTIF_HO_FAIL;
925*5113495bSYour Name 	case WMI_ROAM_NOTIF_SCAN_END:
926*5113495bSYour Name 		return CM_ROAM_NOTIF_SCAN_END;
927*5113495bSYour Name 	default:
928*5113495bSYour Name 		return CM_ROAM_NOTIF_INVALID;
929*5113495bSYour Name 	}
930*5113495bSYour Name 
931*5113495bSYour Name 	return CM_ROAM_NOTIF_INVALID;
932*5113495bSYour Name }
933*5113495bSYour Name 
934*5113495bSYour Name static void
wmi_extract_pdev_hw_mode_trans_ind(wmi_pdev_hw_mode_transition_event_fixed_param * fixed_param,wmi_pdev_set_hw_mode_response_vdev_mac_entry * vdev_mac_entry,struct cm_hw_mode_trans_ind * hw_mode_trans_ind)935*5113495bSYour Name wmi_extract_pdev_hw_mode_trans_ind(
936*5113495bSYour Name 	wmi_pdev_hw_mode_transition_event_fixed_param *fixed_param,
937*5113495bSYour Name 	wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry,
938*5113495bSYour Name 	struct cm_hw_mode_trans_ind *hw_mode_trans_ind)
939*5113495bSYour Name {
940*5113495bSYour Name 	uint32_t i;
941*5113495bSYour Name 
942*5113495bSYour Name 	if (fixed_param->num_vdev_mac_entries > MAX_VDEV_SUPPORTED) {
943*5113495bSYour Name 		wmi_err("Number of Vdev mac entries %d exceeded max vdev supported %d",
944*5113495bSYour Name 			fixed_param->num_vdev_mac_entries,
945*5113495bSYour Name 			MAX_VDEV_SUPPORTED);
946*5113495bSYour Name 		return;
947*5113495bSYour Name 	}
948*5113495bSYour Name 	hw_mode_trans_ind->old_hw_mode_index = fixed_param->old_hw_mode_index;
949*5113495bSYour Name 	hw_mode_trans_ind->new_hw_mode_index = fixed_param->new_hw_mode_index;
950*5113495bSYour Name 	hw_mode_trans_ind->num_vdev_mac_entries =
951*5113495bSYour Name 					fixed_param->num_vdev_mac_entries;
952*5113495bSYour Name 	wmi_debug("old_hw_mode_index:%d new_hw_mode_index:%d entries=%d",
953*5113495bSYour Name 		  fixed_param->old_hw_mode_index,
954*5113495bSYour Name 		  fixed_param->new_hw_mode_index,
955*5113495bSYour Name 		  fixed_param->num_vdev_mac_entries);
956*5113495bSYour Name 
957*5113495bSYour Name 	if (!vdev_mac_entry) {
958*5113495bSYour Name 		wmi_err("Invalid vdev_mac_entry");
959*5113495bSYour Name 		return;
960*5113495bSYour Name 	}
961*5113495bSYour Name 
962*5113495bSYour Name 	/* Store the vdev-mac map in WMA and send to policy manager */
963*5113495bSYour Name 	for (i = 0; i < fixed_param->num_vdev_mac_entries; i++) {
964*5113495bSYour Name 		uint32_t vdev_id, mac_id, pdev_id;
965*5113495bSYour Name 
966*5113495bSYour Name 		vdev_id = vdev_mac_entry[i].vdev_id;
967*5113495bSYour Name 		pdev_id = vdev_mac_entry[i].pdev_id;
968*5113495bSYour Name 
969*5113495bSYour Name 		if (pdev_id == OL_TXRX_PDEV_ID) {
970*5113495bSYour Name 			wmi_err("soc level id received for mac id");
971*5113495bSYour Name 			return;
972*5113495bSYour Name 		}
973*5113495bSYour Name 		if (vdev_id >= WLAN_MAX_VDEVS) {
974*5113495bSYour Name 			wmi_err("vdev_id: %d is invalid, max_bssid: %d",
975*5113495bSYour Name 				vdev_id, WLAN_MAX_VDEVS);
976*5113495bSYour Name 			return;
977*5113495bSYour Name 		}
978*5113495bSYour Name 
979*5113495bSYour Name 		mac_id = WMI_PDEV_TO_MAC_MAP(vdev_mac_entry[i].pdev_id);
980*5113495bSYour Name 
981*5113495bSYour Name 		hw_mode_trans_ind->vdev_mac_map[i].vdev_id = vdev_id;
982*5113495bSYour Name 		hw_mode_trans_ind->vdev_mac_map[i].mac_id = mac_id;
983*5113495bSYour Name 
984*5113495bSYour Name 		wmi_debug("vdev_id:%d mac_id:%d", vdev_id, mac_id);
985*5113495bSYour Name 	}
986*5113495bSYour Name }
987*5113495bSYour Name 
988*5113495bSYour Name /**
989*5113495bSYour Name  * extract_roam_event_tlv() - Extract the roam event
990*5113495bSYour Name  * @wmi_handle: wmi handle
991*5113495bSYour Name  * @evt_buf: Pointer to the event buffer
992*5113495bSYour Name  * @len: Data length
993*5113495bSYour Name  * @roam_event: Roam event data
994*5113495bSYour Name  */
995*5113495bSYour Name static QDF_STATUS
extract_roam_event_tlv(wmi_unified_t wmi_handle,void * evt_buf,uint32_t len,struct roam_offload_roam_event * roam_event)996*5113495bSYour Name extract_roam_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, uint32_t len,
997*5113495bSYour Name 		       struct roam_offload_roam_event *roam_event)
998*5113495bSYour Name {
999*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1000*5113495bSYour Name 	wmi_roam_event_fixed_param *wmi_event = NULL;
1001*5113495bSYour Name 	WMI_ROAM_EVENTID_param_tlvs *param_buf = NULL;
1002*5113495bSYour Name 	struct cm_hw_mode_trans_ind *hw_mode_trans_ind;
1003*5113495bSYour Name 	wmi_pdev_hw_mode_transition_event_fixed_param *hw_mode_trans_param;
1004*5113495bSYour Name 
1005*5113495bSYour Name 	if (!evt_buf) {
1006*5113495bSYour Name 		wmi_debug("Empty roam_sync_event param buf");
1007*5113495bSYour Name 		status = QDF_STATUS_E_FAILURE;
1008*5113495bSYour Name 		goto end;
1009*5113495bSYour Name 	}
1010*5113495bSYour Name 
1011*5113495bSYour Name 	param_buf = (WMI_ROAM_EVENTID_param_tlvs *)evt_buf;
1012*5113495bSYour Name 	if (!param_buf) {
1013*5113495bSYour Name 		wmi_debug("received null buf from target");
1014*5113495bSYour Name 		status = QDF_STATUS_E_FAILURE;
1015*5113495bSYour Name 		goto end;
1016*5113495bSYour Name 	}
1017*5113495bSYour Name 
1018*5113495bSYour Name 	wmi_event = param_buf->fixed_param;
1019*5113495bSYour Name 	if (!wmi_event) {
1020*5113495bSYour Name 		wmi_debug("received null event data from target");
1021*5113495bSYour Name 		status = QDF_STATUS_E_FAILURE;
1022*5113495bSYour Name 		goto end;
1023*5113495bSYour Name 	}
1024*5113495bSYour Name 	roam_event->vdev_id = wmi_event->vdev_id;
1025*5113495bSYour Name 
1026*5113495bSYour Name 	if (roam_event->vdev_id >= WLAN_MAX_VDEVS) {
1027*5113495bSYour Name 		wmi_err("Invalid vdev id from firmware: %u",
1028*5113495bSYour Name 			roam_event->vdev_id);
1029*5113495bSYour Name 		return -EINVAL;
1030*5113495bSYour Name 	}
1031*5113495bSYour Name 	hw_mode_trans_param = param_buf->hw_mode_transition_fixed_param;
1032*5113495bSYour Name 	if (hw_mode_trans_param &&
1033*5113495bSYour Name 	    hw_mode_trans_param->num_vdev_mac_entries >
1034*5113495bSYour Name 	    param_buf->num_wmi_pdev_set_hw_mode_response_vdev_mac_mapping) {
1035*5113495bSYour Name 		wmi_debug("invalid vdev mac entries %d %d",
1036*5113495bSYour Name 			  hw_mode_trans_param->num_vdev_mac_entries,
1037*5113495bSYour Name 			  param_buf->num_wmi_pdev_set_hw_mode_response_vdev_mac_mapping);
1038*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1039*5113495bSYour Name 	}
1040*5113495bSYour Name 
1041*5113495bSYour Name 	roam_event->reason =
1042*5113495bSYour Name 			wmi_convert_fw_reason_to_cm_reason(wmi_event->reason);
1043*5113495bSYour Name 	roam_event->rssi = wmi_event->rssi;
1044*5113495bSYour Name 	roam_event->notif = wmi_convert_fw_notif_to_cm_notif(wmi_event->notif);
1045*5113495bSYour Name 	roam_event->notif_params = wmi_event->notif_params;
1046*5113495bSYour Name 	roam_event->notif_params1 = wmi_event->notif_params1;
1047*5113495bSYour Name 
1048*5113495bSYour Name 	wlan_roam_debug_log(roam_event->vdev_id, DEBUG_ROAM_EVENT,
1049*5113495bSYour Name 			    DEBUG_INVALID_PEER_ID, NULL, NULL,
1050*5113495bSYour Name 			    roam_event->reason,
1051*5113495bSYour Name 			    (roam_event->reason == WMI_ROAM_REASON_INVALID) ?
1052*5113495bSYour Name 			    roam_event->notif : roam_event->rssi);
1053*5113495bSYour Name 
1054*5113495bSYour Name 	DPTRACE(qdf_dp_trace_record_event(QDF_DP_TRACE_EVENT_RECORD,
1055*5113495bSYour Name 					  roam_event->vdev_id,
1056*5113495bSYour Name 					  QDF_TRACE_DEFAULT_PDEV_ID,
1057*5113495bSYour Name 					  QDF_PROTO_TYPE_EVENT,
1058*5113495bSYour Name 					  QDF_ROAM_EVENTID));
1059*5113495bSYour Name 
1060*5113495bSYour Name 	wmi_debug("FW_ROAM_EVT: Reason:%s[%d], Notif %x for vdevid %x, rssi %d, params %d, params1 %d",
1061*5113495bSYour Name 		  wmi_get_roam_event_reason_string(roam_event->reason),
1062*5113495bSYour Name 		  roam_event->reason,
1063*5113495bSYour Name 		  roam_event->notif, roam_event->vdev_id, roam_event->rssi,
1064*5113495bSYour Name 		  roam_event->notif_params, roam_event->notif_params1);
1065*5113495bSYour Name 
1066*5113495bSYour Name 	if (param_buf->hw_mode_transition_fixed_param) {
1067*5113495bSYour Name 		hw_mode_trans_ind = qdf_mem_malloc(sizeof(*hw_mode_trans_ind));
1068*5113495bSYour Name 		if (!hw_mode_trans_ind) {
1069*5113495bSYour Name 			status = QDF_STATUS_E_NOMEM;
1070*5113495bSYour Name 			goto end;
1071*5113495bSYour Name 		}
1072*5113495bSYour Name 		wmi_extract_pdev_hw_mode_trans_ind(
1073*5113495bSYour Name 		    param_buf->hw_mode_transition_fixed_param,
1074*5113495bSYour Name 		    param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping,
1075*5113495bSYour Name 		    hw_mode_trans_ind);
1076*5113495bSYour Name 		roam_event->hw_mode_trans_ind = hw_mode_trans_ind;
1077*5113495bSYour Name 	}
1078*5113495bSYour Name 
1079*5113495bSYour Name 	if (wmi_event->notif_params1)
1080*5113495bSYour Name 		roam_event->deauth_disassoc_frame =
1081*5113495bSYour Name 			param_buf->deauth_disassoc_frame;
1082*5113495bSYour Name end:
1083*5113495bSYour Name 	return status;
1084*5113495bSYour Name }
1085*5113495bSYour Name #endif /* WLAN_FEATURE_HOST_ROAM || WLAN_FEATURE_ROAM_OFFLOAD */
1086*5113495bSYour Name 
1087*5113495bSYour Name #ifdef WLAN_FEATURE_ROAM_OFFLOAD
1088*5113495bSYour Name /* send_set_ric_req_cmd_tlv() - set ric request element
1089*5113495bSYour Name  * @wmi_handle: wmi handle
1090*5113495bSYour Name  * @msg: message
1091*5113495bSYour Name  * @is_add_ts: is addts required
1092*5113495bSYour Name  *
1093*5113495bSYour Name  * This function sets ric request element for 11r roaming.
1094*5113495bSYour Name  *
1095*5113495bSYour Name  * Return: CDF status
1096*5113495bSYour Name  */
send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle,void * msg,uint8_t is_add_ts)1097*5113495bSYour Name static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle,
1098*5113495bSYour Name 			void *msg, uint8_t is_add_ts)
1099*5113495bSYour Name {
1100*5113495bSYour Name 	wmi_ric_request_fixed_param *cmd;
1101*5113495bSYour Name 	wmi_ric_tspec *tspec_param;
1102*5113495bSYour Name 	wmi_buf_t buf;
1103*5113495bSYour Name 	uint8_t *buf_ptr;
1104*5113495bSYour Name 	struct mac_tspec_ie *tspec_ie = NULL;
1105*5113495bSYour Name 	int32_t len = sizeof(wmi_ric_request_fixed_param) +
1106*5113495bSYour Name 		      WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec);
1107*5113495bSYour Name 
1108*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
1109*5113495bSYour Name 	if (!buf)
1110*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
1111*5113495bSYour Name 
1112*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
1113*5113495bSYour Name 
1114*5113495bSYour Name 	cmd = (wmi_ric_request_fixed_param *)buf_ptr;
1115*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
1116*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_ric_request_fixed_param,
1117*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param));
1118*5113495bSYour Name 	if (is_add_ts)
1119*5113495bSYour Name 		cmd->vdev_id = ((struct add_ts_param *)msg)->vdev_id;
1120*5113495bSYour Name 	else
1121*5113495bSYour Name 		cmd->vdev_id = ((struct del_ts_params *)msg)->sessionId;
1122*5113495bSYour Name 	cmd->num_ric_request = 1;
1123*5113495bSYour Name 	cmd->is_add_ric = is_add_ts;
1124*5113495bSYour Name 
1125*5113495bSYour Name 	buf_ptr += sizeof(wmi_ric_request_fixed_param);
1126*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec));
1127*5113495bSYour Name 
1128*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
1129*5113495bSYour Name 	tspec_param = (wmi_ric_tspec *)buf_ptr;
1130*5113495bSYour Name 	WMITLV_SET_HDR(&tspec_param->tlv_header,
1131*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_ric_tspec,
1132*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec));
1133*5113495bSYour Name 
1134*5113495bSYour Name 	if (is_add_ts)
1135*5113495bSYour Name 		tspec_ie = &(((struct add_ts_param *)msg)->tspec);
1136*5113495bSYour Name 	else
1137*5113495bSYour Name 		tspec_ie = &(((struct del_ts_params *)msg)->delTsInfo.tspec);
1138*5113495bSYour Name 	if (tspec_ie) {
1139*5113495bSYour Name 		/* Fill the tsinfo in the format expected by firmware */
1140*5113495bSYour Name #ifndef ANI_LITTLE_BIT_ENDIAN
1141*5113495bSYour Name 		qdf_mem_copy(((uint8_t *)&tspec_param->ts_info) + 1,
1142*5113495bSYour Name 			     ((uint8_t *)&tspec_ie->tsinfo) + 1, 2);
1143*5113495bSYour Name #else
1144*5113495bSYour Name 		qdf_mem_copy(((uint8_t *)&tspec_param->ts_info),
1145*5113495bSYour Name 			     ((uint8_t *)&tspec_ie->tsinfo) + 1, 2);
1146*5113495bSYour Name #endif /* ANI_LITTLE_BIT_ENDIAN */
1147*5113495bSYour Name 
1148*5113495bSYour Name 		tspec_param->nominal_msdu_size = tspec_ie->nomMsduSz;
1149*5113495bSYour Name 		tspec_param->maximum_msdu_size = tspec_ie->maxMsduSz;
1150*5113495bSYour Name 		tspec_param->min_service_interval = tspec_ie->minSvcInterval;
1151*5113495bSYour Name 		tspec_param->max_service_interval = tspec_ie->maxSvcInterval;
1152*5113495bSYour Name 		tspec_param->inactivity_interval = tspec_ie->inactInterval;
1153*5113495bSYour Name 		tspec_param->suspension_interval = tspec_ie->suspendInterval;
1154*5113495bSYour Name 		tspec_param->svc_start_time = tspec_ie->svcStartTime;
1155*5113495bSYour Name 		tspec_param->min_data_rate = tspec_ie->minDataRate;
1156*5113495bSYour Name 		tspec_param->mean_data_rate = tspec_ie->meanDataRate;
1157*5113495bSYour Name 		tspec_param->peak_data_rate = tspec_ie->peakDataRate;
1158*5113495bSYour Name 		tspec_param->max_burst_size = tspec_ie->maxBurstSz;
1159*5113495bSYour Name 		tspec_param->delay_bound = tspec_ie->delayBound;
1160*5113495bSYour Name 		tspec_param->min_phy_rate = tspec_ie->minPhyRate;
1161*5113495bSYour Name 		tspec_param->surplus_bw_allowance = tspec_ie->surplusBw;
1162*5113495bSYour Name 		tspec_param->medium_time = 0;
1163*5113495bSYour Name 	}
1164*5113495bSYour Name 	wmi_debug("Set RIC Req is_add_ts: %d", is_add_ts);
1165*5113495bSYour Name 
1166*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_SET_RIC_REQUEST_CMDID, cmd->vdev_id, 0);
1167*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1168*5113495bSYour Name 				 WMI_ROAM_SET_RIC_REQUEST_CMDID)) {
1169*5113495bSYour Name 		wmi_err("Failed to send vdev Set RIC Req command");
1170*5113495bSYour Name 		if (is_add_ts)
1171*5113495bSYour Name 			((struct add_ts_param *)msg)->status =
1172*5113495bSYour Name 					    QDF_STATUS_E_FAILURE;
1173*5113495bSYour Name 		wmi_buf_free(buf);
1174*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1175*5113495bSYour Name 	}
1176*5113495bSYour Name 
1177*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1178*5113495bSYour Name }
1179*5113495bSYour Name 
1180*5113495bSYour Name /**
1181*5113495bSYour Name  * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to
1182*5113495bSYour Name  * fw.
1183*5113495bSYour Name  * @wmi_handle: wmi handle
1184*5113495bSYour Name  * @vdev_id: vdev id
1185*5113495bSYour Name  *
1186*5113495bSYour Name  * This function sends roam synch complete event to fw.
1187*5113495bSYour Name  *
1188*5113495bSYour Name  * Return: QDF STATUS
1189*5113495bSYour Name  */
1190*5113495bSYour Name static QDF_STATUS
send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle,uint8_t vdev_id)1191*5113495bSYour Name send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle,
1192*5113495bSYour Name 					 uint8_t vdev_id)
1193*5113495bSYour Name {
1194*5113495bSYour Name 	wmi_roam_synch_complete_fixed_param *cmd;
1195*5113495bSYour Name 	wmi_buf_t wmi_buf;
1196*5113495bSYour Name 	uint8_t *buf_ptr;
1197*5113495bSYour Name 	uint16_t len;
1198*5113495bSYour Name 	len = sizeof(wmi_roam_synch_complete_fixed_param);
1199*5113495bSYour Name 
1200*5113495bSYour Name 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
1201*5113495bSYour Name 	if (!wmi_buf)
1202*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
1203*5113495bSYour Name 
1204*5113495bSYour Name 	cmd = (wmi_roam_synch_complete_fixed_param *)wmi_buf_data(wmi_buf);
1205*5113495bSYour Name 	buf_ptr = (uint8_t *)cmd;
1206*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
1207*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param,
1208*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
1209*5113495bSYour Name 			       (wmi_roam_synch_complete_fixed_param));
1210*5113495bSYour Name 	cmd->vdev_id = vdev_id;
1211*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_SYNCH_COMPLETE, cmd->vdev_id, 0);
1212*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
1213*5113495bSYour Name 				 WMI_ROAM_SYNCH_COMPLETE)) {
1214*5113495bSYour Name 		wmi_err("Failed to send roam synch confirmation");
1215*5113495bSYour Name 		wmi_buf_free(wmi_buf);
1216*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1217*5113495bSYour Name 	}
1218*5113495bSYour Name 
1219*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1220*5113495bSYour Name }
1221*5113495bSYour Name 
1222*5113495bSYour Name /**
1223*5113495bSYour Name  * send_roam_invoke_cmd_tlv() - send roam invoke command to fw.
1224*5113495bSYour Name  * @wmi_handle: wma handle
1225*5113495bSYour Name  * @roaminvoke: roam invoke command
1226*5113495bSYour Name  *
1227*5113495bSYour Name  * Send roam invoke command to fw for fastreassoc.
1228*5113495bSYour Name  *
1229*5113495bSYour Name  * Return: CDF STATUS
1230*5113495bSYour Name  */
send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,struct roam_invoke_req * roaminvoke)1231*5113495bSYour Name static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,
1232*5113495bSYour Name 		struct roam_invoke_req *roaminvoke)
1233*5113495bSYour Name {
1234*5113495bSYour Name 	wmi_roam_invoke_cmd_fixed_param *cmd;
1235*5113495bSYour Name 	wmi_buf_t wmi_buf;
1236*5113495bSYour Name 	u_int8_t *buf_ptr;
1237*5113495bSYour Name 	u_int16_t len, args_tlv_len;
1238*5113495bSYour Name 	uint32_t *channel_list;
1239*5113495bSYour Name 	wmi_mac_addr *bssid_list;
1240*5113495bSYour Name 	wmi_tlv_buf_len_param *buf_len_tlv;
1241*5113495bSYour Name 
1242*5113495bSYour Name 	args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) +
1243*5113495bSYour Name 			sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) +
1244*5113495bSYour Name 			roundup(roaminvoke->frame_len, sizeof(uint32_t));
1245*5113495bSYour Name 	len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len;
1246*5113495bSYour Name 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
1247*5113495bSYour Name 	if (!wmi_buf)
1248*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
1249*5113495bSYour Name 
1250*5113495bSYour Name 	cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf);
1251*5113495bSYour Name 	buf_ptr = (u_int8_t *)cmd;
1252*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
1253*5113495bSYour Name 	WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param,
1254*5113495bSYour Name 	WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param));
1255*5113495bSYour Name 	cmd->vdev_id = roaminvoke->vdev_id;
1256*5113495bSYour Name 	cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE);
1257*5113495bSYour Name 	if (roaminvoke->is_same_bssid)
1258*5113495bSYour Name 		cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP);
1259*5113495bSYour Name 
1260*5113495bSYour Name 	if (roaminvoke->frame_len) {
1261*5113495bSYour Name 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP;
1262*5113495bSYour Name 		/* packing 1 beacon/probe_rsp frame with WMI cmd */
1263*5113495bSYour Name 		cmd->num_buf = 1;
1264*5113495bSYour Name 	} else {
1265*5113495bSYour Name 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH;
1266*5113495bSYour Name 		cmd->num_buf = 0;
1267*5113495bSYour Name 	}
1268*5113495bSYour Name 
1269*5113495bSYour Name 	cmd->roam_ap_sel_mode = 0;
1270*5113495bSYour Name 	cmd->roam_delay = 0;
1271*5113495bSYour Name 	cmd->num_chan = 1;
1272*5113495bSYour Name 	cmd->num_bssid = 1;
1273*5113495bSYour Name 
1274*5113495bSYour Name 	if (roaminvoke->forced_roaming) {
1275*5113495bSYour Name 		cmd->num_chan = 0;
1276*5113495bSYour Name 		cmd->num_bssid = 0;
1277*5113495bSYour Name 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_CACHE_MAP;
1278*5113495bSYour Name 		cmd->flags |=
1279*5113495bSYour Name 			(1 << WMI_ROAM_INVOKE_FLAG_FULL_SCAN_IF_NO_CANDIDATE);
1280*5113495bSYour Name 		cmd->reason = ROAM_INVOKE_REASON_NUD_FAILURE;
1281*5113495bSYour Name 	} else if (qdf_is_macaddr_broadcast(&roaminvoke->target_bssid)) {
1282*5113495bSYour Name 		cmd->num_chan = 0;
1283*5113495bSYour Name 		cmd->num_bssid = 0;
1284*5113495bSYour Name 		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_CACHE_MAP;
1285*5113495bSYour Name 		cmd->flags |=
1286*5113495bSYour Name 			(1 << WMI_ROAM_INVOKE_FLAG_FULL_SCAN_IF_NO_CANDIDATE) |
1287*5113495bSYour Name 			(1 << WMI_ROAM_INVOKE_FLAG_SELECT_CANDIDATE_CONSIDER_SCORE);
1288*5113495bSYour Name 		cmd->reason = ROAM_INVOKE_REASON_USER_SPACE;
1289*5113495bSYour Name 	} else {
1290*5113495bSYour Name 		cmd->reason = ROAM_INVOKE_REASON_USER_SPACE;
1291*5113495bSYour Name 	}
1292*5113495bSYour Name 
1293*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param);
1294*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
1295*5113495bSYour Name 		       (sizeof(u_int32_t)));
1296*5113495bSYour Name 	channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
1297*5113495bSYour Name 	*channel_list = roaminvoke->ch_freq;
1298*5113495bSYour Name 	buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE;
1299*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
1300*5113495bSYour Name 		       (sizeof(wmi_mac_addr)));
1301*5113495bSYour Name 	bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
1302*5113495bSYour Name 	WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->target_bssid.bytes, bssid_list);
1303*5113495bSYour Name 
1304*5113495bSYour Name 	/* move to next tlv i.e. bcn_prb_buf_list */
1305*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr);
1306*5113495bSYour Name 
1307*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
1308*5113495bSYour Name 		       sizeof(wmi_tlv_buf_len_param));
1309*5113495bSYour Name 
1310*5113495bSYour Name 	buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE);
1311*5113495bSYour Name 	WMITLV_SET_HDR(&buf_len_tlv->tlv_header,
1312*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_tlv_buf_len_param,
1313*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param));
1314*5113495bSYour Name 	buf_len_tlv->buf_len = roaminvoke->frame_len;
1315*5113495bSYour Name 
1316*5113495bSYour Name 	/* move to next tlv i.e. bcn_prb_frm */
1317*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param);
1318*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
1319*5113495bSYour Name 		       roundup(roaminvoke->frame_len, sizeof(uint32_t)));
1320*5113495bSYour Name 
1321*5113495bSYour Name 	/* copy frame after the header */
1322*5113495bSYour Name 	qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
1323*5113495bSYour Name 		     roaminvoke->frame_buf,
1324*5113495bSYour Name 		     roaminvoke->frame_len);
1325*5113495bSYour Name 
1326*5113495bSYour Name 	wmi_debug("flag:%d, MODE:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d, ch_freq:%d, is_same_bss:%d",
1327*5113495bSYour Name 		  cmd->flags, cmd->roam_scan_mode,
1328*5113495bSYour Name 		  cmd->roam_ap_sel_mode, cmd->roam_delay,
1329*5113495bSYour Name 		  cmd->num_chan, cmd->num_bssid, roaminvoke->ch_freq,
1330*5113495bSYour Name 		  roaminvoke->is_same_bssid);
1331*5113495bSYour Name 
1332*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_INVOKE_CMDID, cmd->vdev_id, 0);
1333*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
1334*5113495bSYour Name 				 WMI_ROAM_INVOKE_CMDID)) {
1335*5113495bSYour Name 		wmi_err("Failed to send roam invoke command");
1336*5113495bSYour Name 		wmi_buf_free(wmi_buf);
1337*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1338*5113495bSYour Name 	}
1339*5113495bSYour Name 
1340*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1341*5113495bSYour Name }
1342*5113495bSYour Name 
1343*5113495bSYour Name /**
1344*5113495bSYour Name  * convert_control_roam_trigger_reason_bitmap() - Convert roam trigger bitmap
1345*5113495bSYour Name  *
1346*5113495bSYour Name  * @trigger_reason_bitmap: Roam trigger reason bitmap received from upper layers
1347*5113495bSYour Name  *
1348*5113495bSYour Name  * Converts the controlled roam trigger reason bitmap of
1349*5113495bSYour Name  * type @roam_control_trigger_reason to firmware trigger
1350*5113495bSYour Name  * reason bitmap as defined in
1351*5113495bSYour Name  * trigger_reason_bitmask @wmi_roam_enable_disable_trigger_reason_fixed_param
1352*5113495bSYour Name  *
1353*5113495bSYour Name  * Return: trigger_reason_bitmask as defined in
1354*5113495bSYour Name  *	   wmi_roam_enable_disable_trigger_reason_fixed_param
1355*5113495bSYour Name  */
1356*5113495bSYour Name static uint32_t
convert_control_roam_trigger_reason_bitmap(uint32_t trigger_reason_bitmap)1357*5113495bSYour Name convert_control_roam_trigger_reason_bitmap(uint32_t trigger_reason_bitmap)
1358*5113495bSYour Name {
1359*5113495bSYour Name 	uint32_t fw_trigger_bitmap = 0, all_bitmap;
1360*5113495bSYour Name 
1361*5113495bSYour Name 	/* Enable the complete trigger bitmap when all bits are set in
1362*5113495bSYour Name 	 * the control config bitmap
1363*5113495bSYour Name 	 */
1364*5113495bSYour Name 	all_bitmap = BIT(ROAM_TRIGGER_REASON_MAX) - 1;
1365*5113495bSYour Name 	if (trigger_reason_bitmap == all_bitmap)
1366*5113495bSYour Name 		return BIT(WMI_ROAM_TRIGGER_EXT_REASON_MAX) - 1;
1367*5113495bSYour Name 
1368*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_NONE))
1369*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_NONE);
1370*5113495bSYour Name 
1371*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PER))
1372*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PER);
1373*5113495bSYour Name 
1374*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BMISS))
1375*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BMISS);
1376*5113495bSYour Name 
1377*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_LOW_RSSI))
1378*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_LOW_RSSI);
1379*5113495bSYour Name 
1380*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_HIGH_RSSI))
1381*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_HIGH_RSSI);
1382*5113495bSYour Name 
1383*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PERIODIC))
1384*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PERIODIC);
1385*5113495bSYour Name 
1386*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_MAWC))
1387*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_MAWC);
1388*5113495bSYour Name 
1389*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DENSE))
1390*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DENSE);
1391*5113495bSYour Name 
1392*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BACKGROUND))
1393*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BACKGROUND);
1394*5113495bSYour Name 
1395*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_FORCED))
1396*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_FORCED);
1397*5113495bSYour Name 
1398*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BTM))
1399*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BTM);
1400*5113495bSYour Name 
1401*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_UNIT_TEST))
1402*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_UNIT_TEST);
1403*5113495bSYour Name 
1404*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BSS_LOAD))
1405*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BSS_LOAD);
1406*5113495bSYour Name 
1407*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DEAUTH))
1408*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DEAUTH);
1409*5113495bSYour Name 
1410*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_IDLE))
1411*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_IDLE);
1412*5113495bSYour Name 
1413*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_STA_KICKOUT))
1414*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_STA_KICKOUT);
1415*5113495bSYour Name 
1416*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_ESS_RSSI))
1417*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_ESS_RSSI);
1418*5113495bSYour Name 
1419*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_WTC_BTM))
1420*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_WTC_BTM);
1421*5113495bSYour Name 
1422*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PMK_TIMEOUT))
1423*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT);
1424*5113495bSYour Name 
1425*5113495bSYour Name 	if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BTC))
1426*5113495bSYour Name 		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BTC);
1427*5113495bSYour Name 
1428*5113495bSYour Name 	return fw_trigger_bitmap;
1429*5113495bSYour Name }
1430*5113495bSYour Name 
1431*5113495bSYour Name /**
1432*5113495bSYour Name  * get_internal_mandatory_roam_triggers() - Internal triggers to be added
1433*5113495bSYour Name  *
1434*5113495bSYour Name  * Return: the bitmap of mandatory triggers to be sent to firmware but not given
1435*5113495bSYour Name  * by user.
1436*5113495bSYour Name  */
1437*5113495bSYour Name static uint32_t
get_internal_mandatory_roam_triggers(void)1438*5113495bSYour Name get_internal_mandatory_roam_triggers(void)
1439*5113495bSYour Name {
1440*5113495bSYour Name 	return BIT(WMI_ROAM_TRIGGER_REASON_FORCED);
1441*5113495bSYour Name }
1442*5113495bSYour Name 
1443*5113495bSYour Name /**
1444*5113495bSYour Name  * convert_roam_trigger_scan_mode() - Function to convert unified Roam trigger
1445*5113495bSYour Name  * scan mode enum to TLV specific ROAM_TRIGGER_SCAN_MODE
1446*5113495bSYour Name  * @scan_freq_scheme: scan freq scheme coming from userspace
1447*5113495bSYour Name  *
1448*5113495bSYour Name  * Return: ROAM_TRIGGER_SCAN_MODE
1449*5113495bSYour Name  */
1450*5113495bSYour Name static WMI_ROAM_TRIGGER_SCAN_MODE
convert_roam_trigger_scan_mode(enum roam_scan_freq_scheme scan_freq_scheme)1451*5113495bSYour Name convert_roam_trigger_scan_mode(enum roam_scan_freq_scheme scan_freq_scheme)
1452*5113495bSYour Name {
1453*5113495bSYour Name 	switch (scan_freq_scheme) {
1454*5113495bSYour Name 	case ROAM_SCAN_FREQ_SCHEME_NO_SCAN:
1455*5113495bSYour Name 		return ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION;
1456*5113495bSYour Name 	case ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN:
1457*5113495bSYour Name 		return ROAM_TRIGGER_SCAN_MODE_PARTIAL;
1458*5113495bSYour Name 	case ROAM_SCAN_FREQ_SCHEME_FULL_SCAN:
1459*5113495bSYour Name 		return ROAM_TRIGGER_SCAN_MODE_FULL;
1460*5113495bSYour Name 	default:
1461*5113495bSYour Name 		return ROAM_TRIGGER_SCAN_MODE_NONE;
1462*5113495bSYour Name 	}
1463*5113495bSYour Name }
1464*5113495bSYour Name 
1465*5113495bSYour Name /**
1466*5113495bSYour Name  * wmi_fill_default_roam_trigger_parameters() - Fill the default parameters
1467*5113495bSYour Name  * for wmi_configure_roam_trigger_parameters tlv.
1468*5113495bSYour Name  * @roam_trigger_params: pointer to wmi_configure_roam_trigger_parameters tlv
1469*5113495bSYour Name  * to be filled.
1470*5113495bSYour Name  * @roam_trigger: Roam trigger reason
1471*5113495bSYour Name  *
1472*5113495bSYour Name  * Return: None
1473*5113495bSYour Name  */
wmi_fill_default_roam_trigger_parameters(wmi_configure_roam_trigger_parameters * roam_trigger_params,uint32_t roam_trigger)1474*5113495bSYour Name static void wmi_fill_default_roam_trigger_parameters(
1475*5113495bSYour Name 		wmi_configure_roam_trigger_parameters *roam_trigger_params,
1476*5113495bSYour Name 		uint32_t roam_trigger)
1477*5113495bSYour Name {
1478*5113495bSYour Name 	WMITLV_SET_HDR(&roam_trigger_params->tlv_header,
1479*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_configure_roam_trigger_parameters,
1480*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(wmi_configure_roam_trigger_parameters));
1481*5113495bSYour Name 
1482*5113495bSYour Name 	roam_trigger_params->trigger_reason = roam_trigger;
1483*5113495bSYour Name 	roam_trigger_params->enable = 1;
1484*5113495bSYour Name 	roam_trigger_params->scan_mode = ROAM_TRIGGER_SCAN_MODE_NONE;
1485*5113495bSYour Name 	roam_trigger_params->trigger_rssi_threshold =
1486*5113495bSYour Name 			ROAM_MAX_CFG_VALUE;
1487*5113495bSYour Name 	roam_trigger_params->cand_ap_min_rssi_threshold =
1488*5113495bSYour Name 			ROAM_MAX_CFG_VALUE;
1489*5113495bSYour Name 	roam_trigger_params->cand_ap_min_rssi_threshold_5g =
1490*5113495bSYour Name 			ROAM_MAX_CFG_VALUE;
1491*5113495bSYour Name 	roam_trigger_params->cand_ap_min_rssi_threshold_6g =
1492*5113495bSYour Name 			ROAM_MAX_CFG_VALUE;
1493*5113495bSYour Name 	roam_trigger_params->roam_score_delta_percentage =
1494*5113495bSYour Name 			ROAM_MAX_CFG_VALUE;
1495*5113495bSYour Name 	roam_trigger_params->reason_code = ROAM_MAX_CFG_VALUE;
1496*5113495bSYour Name }
1497*5113495bSYour Name 
wmi_fill_score_delta_params(wmi_configure_roam_trigger_parameters * roam_trigger_params,struct wlan_roam_triggers * triggers,uint8_t trig_index)1498*5113495bSYour Name static void wmi_fill_score_delta_params(
1499*5113495bSYour Name 		wmi_configure_roam_trigger_parameters *roam_trigger_params,
1500*5113495bSYour Name 		struct wlan_roam_triggers *triggers,
1501*5113495bSYour Name 		uint8_t trig_index)
1502*5113495bSYour Name {
1503*5113495bSYour Name 	enum roam_trigger_reason trig_reason;
1504*5113495bSYour Name 
1505*5113495bSYour Name 	if (trig_index >= NUM_OF_ROAM_TRIGGERS)
1506*5113495bSYour Name 		return;
1507*5113495bSYour Name 
1508*5113495bSYour Name 	trig_reason =
1509*5113495bSYour Name 		triggers->score_delta_param[trig_index].trigger_reason;
1510*5113495bSYour Name 	wmi_fill_default_roam_trigger_parameters(
1511*5113495bSYour Name 		roam_trigger_params,
1512*5113495bSYour Name 		convert_roam_trigger_reason(trig_reason));
1513*5113495bSYour Name 	roam_trigger_params->roam_score_delta_percentage =
1514*5113495bSYour Name 		triggers->score_delta_param[trig_index].roam_score_delta;
1515*5113495bSYour Name 
1516*5113495bSYour Name 	wmi_debug("RSO_CFG: Score delta per: %d converted trig_reason: %d",
1517*5113495bSYour Name 		  roam_trigger_params->roam_score_delta_percentage,
1518*5113495bSYour Name 		  convert_roam_trigger_reason(trig_reason));
1519*5113495bSYour Name 
1520*5113495bSYour Name }
1521*5113495bSYour Name 
wmi_fill_min_rssi_params(wmi_configure_roam_trigger_parameters * roam_trigger_params,struct wlan_roam_triggers * triggers,uint8_t trig_index)1522*5113495bSYour Name static void wmi_fill_min_rssi_params(
1523*5113495bSYour Name 		wmi_configure_roam_trigger_parameters *roam_trigger_params,
1524*5113495bSYour Name 		struct wlan_roam_triggers *triggers,
1525*5113495bSYour Name 		uint8_t trig_index)
1526*5113495bSYour Name {
1527*5113495bSYour Name 	enum roam_trigger_reason trig_reason;
1528*5113495bSYour Name 
1529*5113495bSYour Name 	if (trig_index >= NUM_OF_ROAM_MIN_RSSI)
1530*5113495bSYour Name 		return;
1531*5113495bSYour Name 
1532*5113495bSYour Name 	trig_reason =
1533*5113495bSYour Name 		triggers->min_rssi_params[trig_index].trigger_reason;
1534*5113495bSYour Name 	wmi_fill_default_roam_trigger_parameters(
1535*5113495bSYour Name 		roam_trigger_params,
1536*5113495bSYour Name 		convert_roam_trigger_reason(trig_reason));
1537*5113495bSYour Name 	roam_trigger_params->cand_ap_min_rssi_threshold =
1538*5113495bSYour Name 		triggers->min_rssi_params[trig_index].min_rssi;
1539*5113495bSYour Name 	roam_trigger_params->cand_ap_min_rssi_threshold_5g =
1540*5113495bSYour Name 		triggers->min_rssi_params[trig_index].min_rssi;
1541*5113495bSYour Name 	roam_trigger_params->cand_ap_min_rssi_threshold_6g =
1542*5113495bSYour Name 		triggers->min_rssi_params[trig_index].min_rssi;
1543*5113495bSYour Name 
1544*5113495bSYour Name 	wmi_debug("RSO_CFG: Min rssi thresh: %d converted trig_reason: %d",
1545*5113495bSYour Name 		  roam_trigger_params->cand_ap_min_rssi_threshold,
1546*5113495bSYour Name 		  convert_roam_trigger_reason(trig_reason));
1547*5113495bSYour Name }
1548*5113495bSYour Name 
1549*5113495bSYour Name /**
1550*5113495bSYour Name  * send_set_roam_trigger_cmd_tlv() - send set roam triggers to fw
1551*5113495bSYour Name  * @wmi_handle: wmi handle
1552*5113495bSYour Name  * @triggers: roam trigger bitmap to be enabled
1553*5113495bSYour Name  *
1554*5113495bSYour Name  * Send WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID to fw.
1555*5113495bSYour Name  *
1556*5113495bSYour Name  * Return: QDF_STATUS
1557*5113495bSYour Name  */
send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle,struct wlan_roam_triggers * triggers)1558*5113495bSYour Name static QDF_STATUS send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle,
1559*5113495bSYour Name 					struct wlan_roam_triggers *triggers)
1560*5113495bSYour Name {
1561*5113495bSYour Name 	wmi_buf_t buf;
1562*5113495bSYour Name 	wmi_roam_enable_disable_trigger_reason_fixed_param *cmd;
1563*5113495bSYour Name 	uint32_t len = sizeof(*cmd);
1564*5113495bSYour Name 	int ret;
1565*5113495bSYour Name 	uint8_t *buf_ptr;
1566*5113495bSYour Name 	wmi_configure_roam_trigger_parameters
1567*5113495bSYour Name 					*roam_trigger_parameters;
1568*5113495bSYour Name 	uint32_t num_triggers_enabled = 0;
1569*5113495bSYour Name 	uint32_t roam_scan_scheme_bitmap = triggers->roam_scan_scheme_bitmap;
1570*5113495bSYour Name 	uint32_t total_tlv_len = 0;
1571*5113495bSYour Name 
1572*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_PER) & roam_scan_scheme_bitmap)
1573*5113495bSYour Name 		num_triggers_enabled++;
1574*5113495bSYour Name 
1575*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_BTC) & roam_scan_scheme_bitmap)
1576*5113495bSYour Name 		num_triggers_enabled++;
1577*5113495bSYour Name 
1578*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_BMISS) & roam_scan_scheme_bitmap)
1579*5113495bSYour Name 		num_triggers_enabled++;
1580*5113495bSYour Name 
1581*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_LOW_RSSI) & roam_scan_scheme_bitmap)
1582*5113495bSYour Name 		num_triggers_enabled++;
1583*5113495bSYour Name 
1584*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_BTM) & roam_scan_scheme_bitmap)
1585*5113495bSYour Name 		num_triggers_enabled++;
1586*5113495bSYour Name 
1587*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_BSS_LOAD) & roam_scan_scheme_bitmap)
1588*5113495bSYour Name 		num_triggers_enabled++;
1589*5113495bSYour Name 
1590*5113495bSYour Name 	if (wmi_service_enabled(wmi_handle,
1591*5113495bSYour Name 			wmi_service_configure_roam_trigger_param_support))
1592*5113495bSYour Name 		total_tlv_len += (NUM_OF_ROAM_TRIGGERS + NUM_OF_ROAM_MIN_RSSI) *
1593*5113495bSYour Name 			sizeof(wmi_configure_roam_trigger_parameters);
1594*5113495bSYour Name 
1595*5113495bSYour Name 	total_tlv_len += 2 * sizeof(wmi_configure_roam_trigger_parameters) +
1596*5113495bSYour Name 			num_triggers_enabled *
1597*5113495bSYour Name 			sizeof(wmi_configure_roam_trigger_parameters);
1598*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE + total_tlv_len;
1599*5113495bSYour Name 
1600*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
1601*5113495bSYour Name 	if (!buf) {
1602*5113495bSYour Name 		wmi_err("Failed to allocate wmi buffer");
1603*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
1604*5113495bSYour Name 	}
1605*5113495bSYour Name 
1606*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
1607*5113495bSYour Name 
1608*5113495bSYour Name 	cmd = (wmi_roam_enable_disable_trigger_reason_fixed_param *)
1609*5113495bSYour Name 					wmi_buf_data(buf);
1610*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
1611*5113495bSYour Name 	WMITLV_TAG_STRUC_wmi_roam_enable_disable_trigger_reason_fixed_param,
1612*5113495bSYour Name 	WMITLV_GET_STRUCT_TLVLEN(wmi_roam_enable_disable_trigger_reason_fixed_param));
1613*5113495bSYour Name 
1614*5113495bSYour Name 	cmd->vdev_id = triggers->vdev_id;
1615*5113495bSYour Name 	cmd->trigger_reason_bitmask =
1616*5113495bSYour Name 	   convert_control_roam_trigger_reason_bitmap(triggers->trigger_bitmap);
1617*5113495bSYour Name 	wmi_debug("RSO_CFG: Received trigger bitmap: 0x%x converted trigger_bitmap: 0x%x",
1618*5113495bSYour Name 		  triggers->trigger_bitmap, cmd->trigger_reason_bitmask);
1619*5113495bSYour Name 	cmd->trigger_reason_bitmask |= get_internal_mandatory_roam_triggers();
1620*5113495bSYour Name 	wmi_debug("RSO_CFG: vdev id: %d final trigger_bitmap: 0x%x roam_scan_scheme:0x%x num_triggers_enabled:%d",
1621*5113495bSYour Name 		  cmd->vdev_id, cmd->trigger_reason_bitmask,
1622*5113495bSYour Name 		  roam_scan_scheme_bitmap, num_triggers_enabled);
1623*5113495bSYour Name 
1624*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_enable_disable_trigger_reason_fixed_param);
1625*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, total_tlv_len);
1626*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
1627*5113495bSYour Name 
1628*5113495bSYour Name 	roam_trigger_parameters =
1629*5113495bSYour Name 		(wmi_configure_roam_trigger_parameters *)buf_ptr;
1630*5113495bSYour Name 
1631*5113495bSYour Name 	WMITLV_SET_HDR(&roam_trigger_parameters->tlv_header,
1632*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_configure_roam_trigger_parameters,
1633*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
1634*5113495bSYour Name 			wmi_configure_roam_trigger_parameters));
1635*5113495bSYour Name 	roam_trigger_parameters->trigger_reason =
1636*5113495bSYour Name 			WMI_ROAM_TRIGGER_REASON_WTC_BTM;
1637*5113495bSYour Name 	if (triggers->vendor_btm_param.user_roam_reason == 0)
1638*5113495bSYour Name 		roam_trigger_parameters->enable = 1;
1639*5113495bSYour Name 	roam_trigger_parameters->scan_mode = convert_roam_trigger_scan_mode(
1640*5113495bSYour Name 				triggers->vendor_btm_param.scan_freq_scheme);
1641*5113495bSYour Name 	roam_trigger_parameters->trigger_rssi_threshold =
1642*5113495bSYour Name 		triggers->vendor_btm_param.connected_rssi_threshold;
1643*5113495bSYour Name 	roam_trigger_parameters->cand_ap_min_rssi_threshold =
1644*5113495bSYour Name 		triggers->vendor_btm_param.candidate_rssi_threshold_2g;
1645*5113495bSYour Name 	roam_trigger_parameters->cand_ap_min_rssi_threshold_5g =
1646*5113495bSYour Name 		triggers->vendor_btm_param.candidate_rssi_threshold_5g;
1647*5113495bSYour Name 	roam_trigger_parameters->cand_ap_min_rssi_threshold_6g =
1648*5113495bSYour Name 		triggers->vendor_btm_param.candidate_rssi_threshold_6g;
1649*5113495bSYour Name 	roam_trigger_parameters->roam_score_delta_percentage =
1650*5113495bSYour Name 			triggers->roam_score_delta;
1651*5113495bSYour Name 	roam_trigger_parameters->reason_code =
1652*5113495bSYour Name 			triggers->vendor_btm_param.user_roam_reason;
1653*5113495bSYour Name 
1654*5113495bSYour Name 	roam_trigger_parameters++;
1655*5113495bSYour Name 
1656*5113495bSYour Name 	if (wmi_service_enabled(wmi_handle,
1657*5113495bSYour Name 			wmi_service_configure_roam_trigger_param_support)) {
1658*5113495bSYour Name 		wmi_fill_score_delta_params(roam_trigger_parameters,
1659*5113495bSYour Name 					    triggers,
1660*5113495bSYour Name 					    IDLE_ROAM_TRIGGER);
1661*5113495bSYour Name 		if (cmd->trigger_reason_bitmask &
1662*5113495bSYour Name 		    BIT(WMI_ROAM_TRIGGER_REASON_IDLE))
1663*5113495bSYour Name 			roam_trigger_parameters->enable = 1;
1664*5113495bSYour Name 		else
1665*5113495bSYour Name 			roam_trigger_parameters->enable = 0;
1666*5113495bSYour Name 
1667*5113495bSYour Name 		roam_trigger_parameters++;
1668*5113495bSYour Name 
1669*5113495bSYour Name 		wmi_fill_score_delta_params(roam_trigger_parameters,
1670*5113495bSYour Name 					    triggers,
1671*5113495bSYour Name 					    BTM_ROAM_TRIGGER);
1672*5113495bSYour Name 		roam_trigger_parameters++;
1673*5113495bSYour Name 
1674*5113495bSYour Name 		wmi_fill_min_rssi_params(roam_trigger_parameters,
1675*5113495bSYour Name 					 triggers,
1676*5113495bSYour Name 					 DEAUTH_MIN_RSSI);
1677*5113495bSYour Name 		roam_trigger_parameters++;
1678*5113495bSYour Name 
1679*5113495bSYour Name 		wmi_fill_min_rssi_params(roam_trigger_parameters,
1680*5113495bSYour Name 					 triggers,
1681*5113495bSYour Name 					 BMISS_MIN_RSSI);
1682*5113495bSYour Name 		roam_trigger_parameters++;
1683*5113495bSYour Name 
1684*5113495bSYour Name 		wmi_fill_min_rssi_params(roam_trigger_parameters,
1685*5113495bSYour Name 					 triggers,
1686*5113495bSYour Name 					 MIN_RSSI_2G_TO_5G_ROAM);
1687*5113495bSYour Name 		roam_trigger_parameters++;
1688*5113495bSYour Name 	}
1689*5113495bSYour Name 
1690*5113495bSYour Name 	wmi_fill_default_roam_trigger_parameters(
1691*5113495bSYour Name 				roam_trigger_parameters,
1692*5113495bSYour Name 				WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT);
1693*5113495bSYour Name 
1694*5113495bSYour Name 	if (cmd->trigger_reason_bitmask &
1695*5113495bSYour Name 	    BIT(WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT))
1696*5113495bSYour Name 		roam_trigger_parameters->enable = 1;
1697*5113495bSYour Name 	else
1698*5113495bSYour Name 		roam_trigger_parameters->enable = 0;
1699*5113495bSYour Name 
1700*5113495bSYour Name 	roam_trigger_parameters->roam_score_delta_percentage = 0;
1701*5113495bSYour Name 	roam_trigger_parameters++;
1702*5113495bSYour Name 
1703*5113495bSYour Name 	if (num_triggers_enabled == 0)
1704*5113495bSYour Name 		goto send;
1705*5113495bSYour Name 
1706*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_PER) & roam_scan_scheme_bitmap) {
1707*5113495bSYour Name 		wmi_fill_default_roam_trigger_parameters(
1708*5113495bSYour Name 				roam_trigger_parameters,
1709*5113495bSYour Name 				WMI_ROAM_TRIGGER_REASON_PER);
1710*5113495bSYour Name 		roam_trigger_parameters->scan_mode =
1711*5113495bSYour Name 			ROAM_TRIGGER_SCAN_MODE_PARTIAL;
1712*5113495bSYour Name 
1713*5113495bSYour Name 		roam_trigger_parameters++;
1714*5113495bSYour Name 	}
1715*5113495bSYour Name 
1716*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_BTC) & roam_scan_scheme_bitmap) {
1717*5113495bSYour Name 		wmi_fill_default_roam_trigger_parameters(
1718*5113495bSYour Name 				roam_trigger_parameters,
1719*5113495bSYour Name 				WMI_ROAM_TRIGGER_REASON_BTC);
1720*5113495bSYour Name 		roam_trigger_parameters->scan_mode =
1721*5113495bSYour Name 			ROAM_TRIGGER_SCAN_MODE_PARTIAL;
1722*5113495bSYour Name 
1723*5113495bSYour Name 		roam_trigger_parameters++;
1724*5113495bSYour Name 	}
1725*5113495bSYour Name 
1726*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_BMISS) & roam_scan_scheme_bitmap) {
1727*5113495bSYour Name 		wmi_fill_default_roam_trigger_parameters(
1728*5113495bSYour Name 				roam_trigger_parameters,
1729*5113495bSYour Name 				WMI_ROAM_TRIGGER_REASON_BMISS);
1730*5113495bSYour Name 		roam_trigger_parameters->scan_mode =
1731*5113495bSYour Name 				ROAM_TRIGGER_SCAN_MODE_PARTIAL;
1732*5113495bSYour Name 
1733*5113495bSYour Name 		roam_trigger_parameters++;
1734*5113495bSYour Name 	}
1735*5113495bSYour Name 
1736*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_LOW_RSSI) & roam_scan_scheme_bitmap) {
1737*5113495bSYour Name 		wmi_fill_default_roam_trigger_parameters(
1738*5113495bSYour Name 				roam_trigger_parameters,
1739*5113495bSYour Name 				WMI_ROAM_TRIGGER_REASON_LOW_RSSI);
1740*5113495bSYour Name 		roam_trigger_parameters->scan_mode =
1741*5113495bSYour Name 				ROAM_TRIGGER_SCAN_MODE_PARTIAL;
1742*5113495bSYour Name 
1743*5113495bSYour Name 		roam_trigger_parameters++;
1744*5113495bSYour Name 	}
1745*5113495bSYour Name 
1746*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_BTM) & roam_scan_scheme_bitmap) {
1747*5113495bSYour Name 		wmi_fill_default_roam_trigger_parameters(
1748*5113495bSYour Name 				roam_trigger_parameters,
1749*5113495bSYour Name 				WMI_ROAM_TRIGGER_REASON_BTM);
1750*5113495bSYour Name 		roam_trigger_parameters->scan_mode =
1751*5113495bSYour Name 				ROAM_TRIGGER_SCAN_MODE_PARTIAL;
1752*5113495bSYour Name 
1753*5113495bSYour Name 		roam_trigger_parameters++;
1754*5113495bSYour Name 	}
1755*5113495bSYour Name 
1756*5113495bSYour Name 	if (BIT(ROAM_TRIGGER_REASON_BSS_LOAD) & roam_scan_scheme_bitmap) {
1757*5113495bSYour Name 		wmi_fill_default_roam_trigger_parameters(
1758*5113495bSYour Name 				roam_trigger_parameters,
1759*5113495bSYour Name 				WMI_ROAM_TRIGGER_REASON_BSS_LOAD);
1760*5113495bSYour Name 		roam_trigger_parameters->scan_mode =
1761*5113495bSYour Name 				ROAM_TRIGGER_SCAN_MODE_PARTIAL;
1762*5113495bSYour Name 
1763*5113495bSYour Name 		roam_trigger_parameters++;
1764*5113495bSYour Name 	}
1765*5113495bSYour Name 
1766*5113495bSYour Name send:
1767*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID,
1768*5113495bSYour Name 		   triggers->vdev_id, 0);
1769*5113495bSYour Name 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1770*5113495bSYour Name 				WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID);
1771*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
1772*5113495bSYour Name 		wmi_err("Failed to send set roam triggers command ret = %d",
1773*5113495bSYour Name 			ret);
1774*5113495bSYour Name 		wmi_buf_free(buf);
1775*5113495bSYour Name 	}
1776*5113495bSYour Name 	return ret;
1777*5113495bSYour Name }
1778*5113495bSYour Name 
1779*5113495bSYour Name /**
1780*5113495bSYour Name  * send_vdev_set_pcl_cmd_tlv() - Send WMI_VDEV_SET_PCL_CMDID to FW
1781*5113495bSYour Name  * @wmi_handle: wmi handle
1782*5113495bSYour Name  * @params: Set VDEV PCL params
1783*5113495bSYour Name  *
1784*5113495bSYour Name  * WMI_VDEV_SET_PCL_CMDID provides the Preferred Channel List (PCL) to WLAN
1785*5113495bSYour Name  * firmware. The roaming module is the consumer of this information
1786*5113495bSYour Name  * in the WLAN firmware. The channel list will be used when a VDEV needs
1787*5113495bSYour Name  * to migrate to a new channel without host driver involvement. An example of
1788*5113495bSYour Name  * this behavior is Legacy Fast Roaming (LFR 3.0).
1789*5113495bSYour Name  *
1790*5113495bSYour Name  * WMI_VDEV_SET_PCL_CMDID will carry only the weight list and not the actual
1791*5113495bSYour Name  * channel list. The weights corresponds to the channels sent in
1792*5113495bSYour Name  * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
1793*5113495bSYour Name  * weightage compared to the non PCL channels.
1794*5113495bSYour Name  *
1795*5113495bSYour Name  * When roaming is enabled on STA 1, PDEV pcl will be sent. When STA2 is
1796*5113495bSYour Name  * up, VDEV pcl will be sent on STA 1 after calculating pcl again applying
1797*5113495bSYour Name  * the bandmask and VDEV pcl will be sent for STA2. When one of the STA
1798*5113495bSYour Name  * is disconnected, PDEV pcl will be sent on the other STA again.
1799*5113495bSYour Name  *
1800*5113495bSYour Name  * Return: Success if the cmd is sent successfully to the firmware
1801*5113495bSYour Name  */
1802*5113495bSYour Name static QDF_STATUS
send_vdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,struct set_pcl_cmd_params * params)1803*5113495bSYour Name send_vdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,
1804*5113495bSYour Name 			  struct set_pcl_cmd_params *params)
1805*5113495bSYour Name {
1806*5113495bSYour Name 	wmi_vdev_set_pcl_cmd_fixed_param *cmd;
1807*5113495bSYour Name 	wmi_buf_t buf;
1808*5113495bSYour Name 	uint8_t *buf_ptr;
1809*5113495bSYour Name 	uint32_t *ch_weight, i;
1810*5113495bSYour Name 	size_t len;
1811*5113495bSYour Name 	uint32_t chan_len;
1812*5113495bSYour Name 
1813*5113495bSYour Name 	chan_len = params->weights->saved_num_chan;
1814*5113495bSYour Name 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t));
1815*5113495bSYour Name 
1816*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
1817*5113495bSYour Name 	if (!buf)
1818*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
1819*5113495bSYour Name 
1820*5113495bSYour Name 	cmd = (wmi_vdev_set_pcl_cmd_fixed_param *)wmi_buf_data(buf);
1821*5113495bSYour Name 	buf_ptr = (uint8_t *)cmd;
1822*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
1823*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_vdev_set_pcl_cmd_fixed_param,
1824*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_pcl_cmd_fixed_param));
1825*5113495bSYour Name 	cmd->vdev_id = params->vdev_id;
1826*5113495bSYour Name 	buf_ptr += sizeof(wmi_vdev_set_pcl_cmd_fixed_param);
1827*5113495bSYour Name 
1828*5113495bSYour Name 	/* Channel weights uint32 Array TLV */
1829*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
1830*5113495bSYour Name 		       (chan_len * sizeof(uint32_t)));
1831*5113495bSYour Name 	ch_weight = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
1832*5113495bSYour Name 	for (i = 0; i < chan_len; i++)
1833*5113495bSYour Name 		ch_weight[i] = params->weights->weighed_valid_list[i];
1834*5113495bSYour Name 
1835*5113495bSYour Name 	wmi_mtrace(WMI_VDEV_SET_PCL_CMDID, params->vdev_id, 0);
1836*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
1837*5113495bSYour Name 				 WMI_VDEV_SET_PCL_CMDID)) {
1838*5113495bSYour Name 		wmi_err("Failed to send WMI_VDEV_SET_PCL_CMDID");
1839*5113495bSYour Name 		wmi_buf_free(buf);
1840*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1841*5113495bSYour Name 	}
1842*5113495bSYour Name 
1843*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1844*5113495bSYour Name }
1845*5113495bSYour Name 
1846*5113495bSYour Name /**
1847*5113495bSYour Name  * extract_roam_btm_response_stats_tlv() - Extract the btm rsp stats
1848*5113495bSYour Name  * from the WMI_ROAM_STATS_EVENTID
1849*5113495bSYour Name  * @wmi_handle: wmi handle
1850*5113495bSYour Name  * @evt_buf:    Pointer to the event buffer
1851*5113495bSYour Name  * @dst:        Pointer to destination structure to fill data
1852*5113495bSYour Name  * @idx:        TLV id
1853*5113495bSYour Name  */
1854*5113495bSYour Name static QDF_STATUS
extract_roam_btm_response_stats_tlv(wmi_unified_t wmi_handle,void * evt_buf,struct roam_btm_response_data * dst,uint8_t idx)1855*5113495bSYour Name extract_roam_btm_response_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
1856*5113495bSYour Name 				    struct roam_btm_response_data *dst,
1857*5113495bSYour Name 				    uint8_t idx)
1858*5113495bSYour Name {
1859*5113495bSYour Name 	WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
1860*5113495bSYour Name 	wmi_roam_btm_response_info *src_data = NULL;
1861*5113495bSYour Name 
1862*5113495bSYour Name 	param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
1863*5113495bSYour Name 
1864*5113495bSYour Name 	if (!param_buf || !param_buf->roam_btm_response_info ||
1865*5113495bSYour Name 	    !param_buf->num_roam_btm_response_info ||
1866*5113495bSYour Name 	    idx >= param_buf->num_roam_btm_response_info) {
1867*5113495bSYour Name 		wmi_debug("Empty btm response param buf");
1868*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1869*5113495bSYour Name 	}
1870*5113495bSYour Name 
1871*5113495bSYour Name 	src_data = &param_buf->roam_btm_response_info[idx];
1872*5113495bSYour Name 	if (!src_data->timestamp)
1873*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1874*5113495bSYour Name 
1875*5113495bSYour Name 	dst->present = true;
1876*5113495bSYour Name 	dst->btm_status = src_data->btm_status;
1877*5113495bSYour Name 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->target_bssid,
1878*5113495bSYour Name 				   dst->target_bssid.bytes);
1879*5113495bSYour Name 	dst->vsie_reason = src_data->vsie_reason;
1880*5113495bSYour Name 	dst->timestamp = src_data->timestamp;
1881*5113495bSYour Name 	dst->btm_resp_dialog_token = src_data->btm_resp_dialog_token;
1882*5113495bSYour Name 	dst->btm_delay = src_data->btm_resp_bss_termination_delay;
1883*5113495bSYour Name 	dst->band = WMI_ROAM_BTM_RESP_MLO_BAND_INFO_GET(src_data->info);
1884*5113495bSYour Name 	if (dst->band != WMI_MLO_BAND_NO_MLO)
1885*5113495bSYour Name 		dst->is_mlo = true;
1886*5113495bSYour Name 
1887*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1888*5113495bSYour Name }
1889*5113495bSYour Name 
1890*5113495bSYour Name /**
1891*5113495bSYour Name  * extract_roam_initial_info_tlv() - Extract the roam initial info
1892*5113495bSYour Name  * from the WMI_ROAM_STATS_EVENTID
1893*5113495bSYour Name  * @wmi_handle: wmi handle
1894*5113495bSYour Name  * @evt_buf:    Pointer to the event buffer
1895*5113495bSYour Name  * @dst:        Pointer to destination structure to fill data
1896*5113495bSYour Name  * @idx:        TLV id
1897*5113495bSYour Name  */
1898*5113495bSYour Name static QDF_STATUS
extract_roam_initial_info_tlv(wmi_unified_t wmi_handle,void * evt_buf,struct roam_initial_data * dst,uint8_t idx)1899*5113495bSYour Name extract_roam_initial_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
1900*5113495bSYour Name 			      struct roam_initial_data *dst, uint8_t idx)
1901*5113495bSYour Name {
1902*5113495bSYour Name 	WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
1903*5113495bSYour Name 	wmi_roam_initial_info *src_data = NULL;
1904*5113495bSYour Name 
1905*5113495bSYour Name 	param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
1906*5113495bSYour Name 
1907*5113495bSYour Name 	if (!param_buf || !param_buf->roam_initial_info ||
1908*5113495bSYour Name 	    !param_buf->num_roam_initial_info ||
1909*5113495bSYour Name 	    idx >= param_buf->num_roam_initial_info) {
1910*5113495bSYour Name 		wmi_debug("Empty roam_initial_info param buf");
1911*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1912*5113495bSYour Name 	}
1913*5113495bSYour Name 
1914*5113495bSYour Name 	src_data = &param_buf->roam_initial_info[idx];
1915*5113495bSYour Name 
1916*5113495bSYour Name 	dst->present = true;
1917*5113495bSYour Name 	dst->roam_full_scan_count = src_data->roam_full_scan_count;
1918*5113495bSYour Name 	dst->rssi_th = src_data->rssi_th;
1919*5113495bSYour Name 	dst->cu_th = src_data->cu_th;
1920*5113495bSYour Name 	dst->fw_cancel_timer_bitmap = src_data->timer_canceled;
1921*5113495bSYour Name 
1922*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1923*5113495bSYour Name }
1924*5113495bSYour Name 
1925*5113495bSYour Name /**
1926*5113495bSYour Name  * extract_roam_msg_info_tlv() - Extract the roam message info
1927*5113495bSYour Name  * from the WMI_ROAM_STATS_EVENTID
1928*5113495bSYour Name  * @wmi_handle: wmi handle
1929*5113495bSYour Name  * @evt_buf:    Pointer to the event buffer
1930*5113495bSYour Name  * @dst:        Pointer to destination structure to fill data
1931*5113495bSYour Name  * @idx:        TLV id
1932*5113495bSYour Name  */
1933*5113495bSYour Name static QDF_STATUS
extract_roam_msg_info_tlv(wmi_unified_t wmi_handle,void * evt_buf,struct roam_msg_info * dst,uint8_t idx)1934*5113495bSYour Name extract_roam_msg_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
1935*5113495bSYour Name 			  struct roam_msg_info *dst, uint8_t idx)
1936*5113495bSYour Name {
1937*5113495bSYour Name 	WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
1938*5113495bSYour Name 	wmi_roam_msg_info *src_data = NULL;
1939*5113495bSYour Name 
1940*5113495bSYour Name 	param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
1941*5113495bSYour Name 
1942*5113495bSYour Name 	if (!param_buf || !param_buf->roam_msg_info ||
1943*5113495bSYour Name 	    !param_buf->num_roam_msg_info ||
1944*5113495bSYour Name 	    idx >= param_buf->num_roam_msg_info)
1945*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1946*5113495bSYour Name 
1947*5113495bSYour Name 	src_data = &param_buf->roam_msg_info[idx];
1948*5113495bSYour Name 
1949*5113495bSYour Name 	dst->present = true;
1950*5113495bSYour Name 	dst->timestamp = src_data->timestamp;
1951*5113495bSYour Name 	dst->msg_id = src_data->msg_id;
1952*5113495bSYour Name 	dst->msg_param1 = src_data->msg_param1;
1953*5113495bSYour Name 	dst->msg_param2 = src_data->msg_param2;
1954*5113495bSYour Name 
1955*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1956*5113495bSYour Name }
1957*5113495bSYour Name 
1958*5113495bSYour Name static enum wlan_roam_frame_subtype
wmi_get_converted_roam_eapol_subtype(WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE eapol_subtype)1959*5113495bSYour Name wmi_get_converted_roam_eapol_subtype(
1960*5113495bSYour Name 		WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE eapol_subtype)
1961*5113495bSYour Name {
1962*5113495bSYour Name 	switch (eapol_subtype) {
1963*5113495bSYour Name 	case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_M1:
1964*5113495bSYour Name 		return ROAM_FRAME_SUBTYPE_M1;
1965*5113495bSYour Name 	case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_M2:
1966*5113495bSYour Name 		return ROAM_FRAME_SUBTYPE_M2;
1967*5113495bSYour Name 	case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_M3:
1968*5113495bSYour Name 		return ROAM_FRAME_SUBTYPE_M3;
1969*5113495bSYour Name 	case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_M4:
1970*5113495bSYour Name 		return ROAM_FRAME_SUBTYPE_M4;
1971*5113495bSYour Name 	case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_GTK_M1:
1972*5113495bSYour Name 		return ROAM_FRAME_SUBTYPE_GTK_M1;
1973*5113495bSYour Name 	case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_GTK_M2:
1974*5113495bSYour Name 		return ROAM_FRAME_SUBTYPE_GTK_M2;
1975*5113495bSYour Name 	default:
1976*5113495bSYour Name 		break;
1977*5113495bSYour Name 	}
1978*5113495bSYour Name 
1979*5113495bSYour Name 	return 0;
1980*5113495bSYour Name }
1981*5113495bSYour Name 
1982*5113495bSYour Name static enum qdf_dp_tx_rx_status
wmi_get_converted_tx_status(WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS roam_tx_status)1983*5113495bSYour Name wmi_get_converted_tx_status(
1984*5113495bSYour Name 		WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS roam_tx_status)
1985*5113495bSYour Name {
1986*5113495bSYour Name 	switch (roam_tx_status) {
1987*5113495bSYour Name 	case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_ACK:
1988*5113495bSYour Name 		return QDF_TX_RX_STATUS_OK;
1989*5113495bSYour Name 	case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_NO_ACK:
1990*5113495bSYour Name 		return QDF_TX_RX_STATUS_NO_ACK;
1991*5113495bSYour Name 	case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_FAIL:
1992*5113495bSYour Name 		return QDF_TX_RX_STATUS_DROP;
1993*5113495bSYour Name 	default:
1994*5113495bSYour Name 		break;
1995*5113495bSYour Name 	}
1996*5113495bSYour Name 
1997*5113495bSYour Name 	return QDF_TX_RX_STATUS_INVALID;
1998*5113495bSYour Name }
1999*5113495bSYour Name 
2000*5113495bSYour Name #define WLAN_FC0_SUBTYPE_SHIFT              4
2001*5113495bSYour Name #define WLAN_FRAME_INFO_TYPE_OFFSET         0
2002*5113495bSYour Name #define WLAN_FRAME_INFO_SUBTYPE_OFFSET      2
2003*5113495bSYour Name #define WLAN_FRAME_INFO_RESP_OFFSET         6
2004*5113495bSYour Name #define WLAN_FRAME_INFO_AUTH_ALG_OFFSET     7
2005*5113495bSYour Name #define WLAN_FRAME_INFO_SEQ_NUM_OFFSET      16
2006*5113495bSYour Name 
2007*5113495bSYour Name /**
2008*5113495bSYour Name  * extract_roam_frame_info_tlv() - Extract the frame exchanges during roaming
2009*5113495bSYour Name  * info from the WMI_ROAM_STATS_EVENTID
2010*5113495bSYour Name  * @wmi_handle: wmi handle
2011*5113495bSYour Name  * @evt_buf:    Pointer to the event buffer
2012*5113495bSYour Name  * @dst:        Pointer to destination structure to fill data
2013*5113495bSYour Name  * @frame_idx:  TLV id
2014*5113495bSYour Name  * @num_frames: Number of Frame TLVs to be extracted
2015*5113495bSYour Name  */
2016*5113495bSYour Name static QDF_STATUS
extract_roam_frame_info_tlv(wmi_unified_t wmi_handle,void * evt_buf,struct roam_frame_stats * dst,uint8_t frame_idx,uint8_t num_frames)2017*5113495bSYour Name extract_roam_frame_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
2018*5113495bSYour Name 			    struct roam_frame_stats *dst, uint8_t frame_idx,
2019*5113495bSYour Name 			    uint8_t num_frames)
2020*5113495bSYour Name {
2021*5113495bSYour Name 	WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
2022*5113495bSYour Name 	wmi_roam_frame_info *src_data = NULL;
2023*5113495bSYour Name 	struct roam_frame_info *dst_buf;
2024*5113495bSYour Name 	uint8_t i, subtype;
2025*5113495bSYour Name 
2026*5113495bSYour Name 	param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
2027*5113495bSYour Name 
2028*5113495bSYour Name 	if (!param_buf || !param_buf->roam_frame_info ||
2029*5113495bSYour Name 	    !param_buf->num_roam_frame_info ||
2030*5113495bSYour Name 	    (frame_idx + num_frames) > param_buf->num_roam_frame_info) {
2031*5113495bSYour Name 		wmi_err("Empty roam_frame_info param buf frame_idx:%d num_frames:%d",
2032*5113495bSYour Name 			frame_idx, num_frames);
2033*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2034*5113495bSYour Name 	}
2035*5113495bSYour Name 
2036*5113495bSYour Name 	src_data = &param_buf->roam_frame_info[frame_idx];
2037*5113495bSYour Name 
2038*5113495bSYour Name 	if (num_frames > WLAN_ROAM_MAX_FRAME_INFO)
2039*5113495bSYour Name 		num_frames = WLAN_ROAM_MAX_FRAME_INFO;
2040*5113495bSYour Name 
2041*5113495bSYour Name 	dst->num_frame = num_frames;
2042*5113495bSYour Name 	dst_buf = dst->frame_info;
2043*5113495bSYour Name 	for (i = 0; i < num_frames; i++) {
2044*5113495bSYour Name 		dst_buf->timestamp = src_data->timestamp;
2045*5113495bSYour Name 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid,
2046*5113495bSYour Name 					   dst_buf->bssid.bytes);
2047*5113495bSYour Name 		dst_buf->type = WMI_GET_BITS(src_data->frame_info,
2048*5113495bSYour Name 					     WLAN_FRAME_INFO_TYPE_OFFSET, 2);
2049*5113495bSYour Name 
2050*5113495bSYour Name 		subtype = WMI_GET_BITS(src_data->frame_info,
2051*5113495bSYour Name 				       WLAN_FRAME_INFO_SUBTYPE_OFFSET, 4);
2052*5113495bSYour Name 		if (dst_buf->type == WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT) {
2053*5113495bSYour Name 			dst_buf->type = ROAM_FRAME_INFO_FRAME_TYPE_EXT;
2054*5113495bSYour Name 			dst_buf->subtype =
2055*5113495bSYour Name 				wmi_get_converted_roam_eapol_subtype(subtype);
2056*5113495bSYour Name 		} else {
2057*5113495bSYour Name 			dst_buf->subtype = subtype << WLAN_FC0_SUBTYPE_SHIFT;
2058*5113495bSYour Name 		}
2059*5113495bSYour Name 
2060*5113495bSYour Name 		dst_buf->is_rsp = WMI_GET_BITS(src_data->frame_info,
2061*5113495bSYour Name 					       WLAN_FRAME_INFO_RESP_OFFSET, 1);
2062*5113495bSYour Name 		dst_buf->seq_num = WMI_GET_BITS(src_data->frame_info,
2063*5113495bSYour Name 						WLAN_FRAME_INFO_SEQ_NUM_OFFSET,
2064*5113495bSYour Name 						16);
2065*5113495bSYour Name 		dst_buf->status_code = src_data->status_code;
2066*5113495bSYour Name 		if (dst_buf->type != WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT &&
2067*5113495bSYour Name 		    dst_buf->subtype == MGMT_SUBTYPE_AUTH)
2068*5113495bSYour Name 			dst_buf->auth_algo =
2069*5113495bSYour Name 				WMI_GET_BITS(src_data->frame_info,
2070*5113495bSYour Name 					     WLAN_FRAME_INFO_AUTH_ALG_OFFSET,
2071*5113495bSYour Name 					     4);
2072*5113495bSYour Name 
2073*5113495bSYour Name 		if (!dst_buf->is_rsp) {
2074*5113495bSYour Name 			dst_buf->tx_status = wmi_get_converted_tx_status(
2075*5113495bSYour Name 							src_data->status_code);
2076*5113495bSYour Name 			/* wmi_roam_frame_info->status_code sent from the fw
2077*5113495bSYour Name 			 * denotes the tx_status of the transmitted frames.
2078*5113495bSYour Name 			 * To Do: Need a separate field for status code or
2079*5113495bSYour Name 			 * use existing field of wmi_roam_frame_info tlv
2080*5113495bSYour Name 			 * to send the tx status of transmitted frame from the
2081*5113495bSYour Name 			 * FW.
2082*5113495bSYour Name 			 */
2083*5113495bSYour Name 			dst_buf->status_code = 0;
2084*5113495bSYour Name 		}
2085*5113495bSYour Name 
2086*5113495bSYour Name 		dst_buf->retry_count = src_data->retry_count;
2087*5113495bSYour Name 		dst_buf->rssi = (-1) * src_data->rssi_dbm_abs;
2088*5113495bSYour Name 		dst_buf->assoc_id =
2089*5113495bSYour Name 			WMI_GET_ASSOC_ID(src_data->frame_info_ext);
2090*5113495bSYour Name 
2091*5113495bSYour Name 		dst_buf->band =
2092*5113495bSYour Name 			WMI_GET_MLO_BITMAP_BAND_INFO(src_data->frame_info_ext);
2093*5113495bSYour Name 
2094*5113495bSYour Name 		dst_buf++;
2095*5113495bSYour Name 		src_data++;
2096*5113495bSYour Name 	}
2097*5113495bSYour Name 
2098*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2099*5113495bSYour Name }
2100*5113495bSYour Name 
2101*5113495bSYour Name /**
2102*5113495bSYour Name  * wmi_fill_data_synch_frame_event() - Fill the the roam sync data buffer using
2103*5113495bSYour Name  * synch frame event data
2104*5113495bSYour Name  * @rso_cfg: Source buffer
2105*5113495bSYour Name  * @roam_sync_ind: Buffer to be filled
2106*5113495bSYour Name  *
2107*5113495bSYour Name  * Firmware sends all the required information required for roam
2108*5113495bSYour Name  * synch propagation as TLV's and stored in param_buf. These
2109*5113495bSYour Name  * parameters are parsed and filled into the roam synch indication
2110*5113495bSYour Name  * buffer which will be used at different layers for propagation.
2111*5113495bSYour Name  *
2112*5113495bSYour Name  * Return: None
2113*5113495bSYour Name  */
2114*5113495bSYour Name static void
wmi_fill_data_synch_frame_event(struct rso_config * rso_cfg,struct roam_offload_synch_ind * roam_sync_ind)2115*5113495bSYour Name wmi_fill_data_synch_frame_event(struct rso_config *rso_cfg,
2116*5113495bSYour Name 				struct roam_offload_synch_ind *roam_sync_ind)
2117*5113495bSYour Name {
2118*5113495bSYour Name 	uint8_t *bcn_probersp_ptr, *link_bcn_probersp_ptr;
2119*5113495bSYour Name 	uint8_t *reassoc_rsp_ptr;
2120*5113495bSYour Name 	uint8_t *reassoc_req_ptr;
2121*5113495bSYour Name 
2122*5113495bSYour Name 	/* Beacon/Probe Rsp data */
2123*5113495bSYour Name 	roam_sync_ind->beacon_probe_resp_offset =
2124*5113495bSYour Name 		sizeof(struct roam_offload_synch_ind);
2125*5113495bSYour Name 	bcn_probersp_ptr = (uint8_t *)roam_sync_ind +
2126*5113495bSYour Name 		roam_sync_ind->beacon_probe_resp_offset;
2127*5113495bSYour Name 	roam_sync_ind->beacon_probe_resp_length =
2128*5113495bSYour Name 		rso_cfg->roam_sync_frame_ind.bcn_probe_rsp_len;
2129*5113495bSYour Name 	qdf_mem_copy(bcn_probersp_ptr,
2130*5113495bSYour Name 		     rso_cfg->roam_sync_frame_ind.bcn_probe_rsp,
2131*5113495bSYour Name 		     roam_sync_ind->beacon_probe_resp_length);
2132*5113495bSYour Name 	qdf_mem_free(rso_cfg->roam_sync_frame_ind.bcn_probe_rsp);
2133*5113495bSYour Name 	rso_cfg->roam_sync_frame_ind.bcn_probe_rsp = NULL;
2134*5113495bSYour Name 
2135*5113495bSYour Name 	/* Link beacon/probe rsp data */
2136*5113495bSYour Name 	if (rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp) {
2137*5113495bSYour Name 		roam_sync_ind->link_beacon_probe_resp_offset =
2138*5113495bSYour Name 			sizeof(struct roam_offload_synch_ind) +
2139*5113495bSYour Name 			roam_sync_ind->beacon_probe_resp_length;
2140*5113495bSYour Name 		roam_sync_ind->link_beacon_probe_resp_length =
2141*5113495bSYour Name 			rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp_len;
2142*5113495bSYour Name 		roam_sync_ind->is_link_beacon =
2143*5113495bSYour Name 			rso_cfg->roam_sync_frame_ind.is_link_beacon;
2144*5113495bSYour Name 		link_bcn_probersp_ptr = (uint8_t *)roam_sync_ind +
2145*5113495bSYour Name 				  roam_sync_ind->link_beacon_probe_resp_offset;
2146*5113495bSYour Name 		qdf_mem_copy(link_bcn_probersp_ptr,
2147*5113495bSYour Name 			     rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp,
2148*5113495bSYour Name 			     roam_sync_ind->link_beacon_probe_resp_length);
2149*5113495bSYour Name 		qdf_mem_free(rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp);
2150*5113495bSYour Name 		rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp = NULL;
2151*5113495bSYour Name 	}
2152*5113495bSYour Name 
2153*5113495bSYour Name 	/* ReAssoc Rsp data */
2154*5113495bSYour Name 	roam_sync_ind->reassoc_resp_offset =
2155*5113495bSYour Name 		sizeof(struct roam_offload_synch_ind) +
2156*5113495bSYour Name 		roam_sync_ind->beacon_probe_resp_length +
2157*5113495bSYour Name 		roam_sync_ind->link_beacon_probe_resp_length;
2158*5113495bSYour Name 	roam_sync_ind->reassoc_resp_length =
2159*5113495bSYour Name 		rso_cfg->roam_sync_frame_ind.reassoc_rsp_len;
2160*5113495bSYour Name 	reassoc_rsp_ptr = (uint8_t *)roam_sync_ind +
2161*5113495bSYour Name 			  roam_sync_ind->reassoc_resp_offset;
2162*5113495bSYour Name 	qdf_mem_copy(reassoc_rsp_ptr,
2163*5113495bSYour Name 		     rso_cfg->roam_sync_frame_ind.reassoc_rsp,
2164*5113495bSYour Name 		     roam_sync_ind->reassoc_resp_length);
2165*5113495bSYour Name 	qdf_mem_free(rso_cfg->roam_sync_frame_ind.reassoc_rsp);
2166*5113495bSYour Name 	rso_cfg->roam_sync_frame_ind.reassoc_rsp = NULL;
2167*5113495bSYour Name 
2168*5113495bSYour Name 	/* ReAssoc Req data */
2169*5113495bSYour Name 	roam_sync_ind->reassoc_req_offset =
2170*5113495bSYour Name 		sizeof(struct roam_offload_synch_ind) +
2171*5113495bSYour Name 		roam_sync_ind->beacon_probe_resp_length +
2172*5113495bSYour Name 		roam_sync_ind->link_beacon_probe_resp_length +
2173*5113495bSYour Name 		roam_sync_ind->reassoc_resp_length;
2174*5113495bSYour Name 	roam_sync_ind->reassoc_req_length =
2175*5113495bSYour Name 		rso_cfg->roam_sync_frame_ind.reassoc_req_len;
2176*5113495bSYour Name 	reassoc_req_ptr = (uint8_t *)roam_sync_ind +
2177*5113495bSYour Name 			  roam_sync_ind->reassoc_req_offset;
2178*5113495bSYour Name 	qdf_mem_copy(reassoc_req_ptr,
2179*5113495bSYour Name 		     rso_cfg->roam_sync_frame_ind.reassoc_req,
2180*5113495bSYour Name 		     roam_sync_ind->reassoc_req_length);
2181*5113495bSYour Name 	qdf_mem_free(rso_cfg->roam_sync_frame_ind.reassoc_req);
2182*5113495bSYour Name 	rso_cfg->roam_sync_frame_ind.reassoc_req = NULL;
2183*5113495bSYour Name }
2184*5113495bSYour Name 
2185*5113495bSYour Name /**
2186*5113495bSYour Name  * wmi_fill_data_synch_event() - Fill the the roam sync data buffer
2187*5113495bSYour Name  * using synch event data
2188*5113495bSYour Name  * @roam_sync_ind: Buffer to be filled
2189*5113495bSYour Name  * @param_buf: Source buffer
2190*5113495bSYour Name  *
2191*5113495bSYour Name  * Firmware sends all the required information required for roam
2192*5113495bSYour Name  * synch propagation as TLV's and stored in param_buf. These
2193*5113495bSYour Name  * parameters are parsed and filled into the roam synch indication
2194*5113495bSYour Name  * buffer which will be used at different layers for propagation.
2195*5113495bSYour Name  *
2196*5113495bSYour Name  * Return: None
2197*5113495bSYour Name  */
2198*5113495bSYour Name static void
wmi_fill_data_synch_event(struct roam_offload_synch_ind * roam_sync_ind,WMI_ROAM_SYNCH_EVENTID_param_tlvs * param_buf)2199*5113495bSYour Name wmi_fill_data_synch_event(struct roam_offload_synch_ind *roam_sync_ind,
2200*5113495bSYour Name 			  WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf)
2201*5113495bSYour Name {
2202*5113495bSYour Name 	uint8_t *bcn_probersp_ptr;
2203*5113495bSYour Name 	uint8_t *reassoc_rsp_ptr;
2204*5113495bSYour Name 	uint8_t *reassoc_req_ptr;
2205*5113495bSYour Name 	wmi_roam_synch_event_fixed_param *synch_event;
2206*5113495bSYour Name 
2207*5113495bSYour Name 	synch_event = param_buf->fixed_param;
2208*5113495bSYour Name 
2209*5113495bSYour Name 	/* Beacon/Probe Rsp data */
2210*5113495bSYour Name 	roam_sync_ind->beacon_probe_resp_offset =
2211*5113495bSYour Name 		sizeof(struct roam_offload_synch_ind);
2212*5113495bSYour Name 	bcn_probersp_ptr = (uint8_t *)roam_sync_ind +
2213*5113495bSYour Name 		roam_sync_ind->beacon_probe_resp_offset;
2214*5113495bSYour Name 	roam_sync_ind->beacon_probe_resp_length =
2215*5113495bSYour Name 		synch_event->bcn_probe_rsp_len;
2216*5113495bSYour Name 	qdf_mem_copy(bcn_probersp_ptr, param_buf->bcn_probe_rsp_frame,
2217*5113495bSYour Name 		     roam_sync_ind->beacon_probe_resp_length);
2218*5113495bSYour Name 	/*
2219*5113495bSYour Name 	 * Firmware doesn't support link beacon/Probe Rsp data in roam sync
2220*5113495bSYour Name 	 * event. It's always sent in sync_frame event
2221*5113495bSYour Name 	 */
2222*5113495bSYour Name 	/* ReAssoc Rsp data */
2223*5113495bSYour Name 	roam_sync_ind->reassoc_resp_offset =
2224*5113495bSYour Name 		sizeof(struct roam_offload_synch_ind) +
2225*5113495bSYour Name 		roam_sync_ind->beacon_probe_resp_length;
2226*5113495bSYour Name 	roam_sync_ind->reassoc_resp_length = synch_event->reassoc_rsp_len;
2227*5113495bSYour Name 	reassoc_rsp_ptr = (uint8_t *)roam_sync_ind +
2228*5113495bSYour Name 			  roam_sync_ind->reassoc_resp_offset;
2229*5113495bSYour Name 	qdf_mem_copy(reassoc_rsp_ptr,
2230*5113495bSYour Name 		     param_buf->reassoc_rsp_frame,
2231*5113495bSYour Name 		     roam_sync_ind->reassoc_resp_length);
2232*5113495bSYour Name 
2233*5113495bSYour Name 	/* ReAssoc Req data */
2234*5113495bSYour Name 	roam_sync_ind->reassoc_req_offset =
2235*5113495bSYour Name 		sizeof(struct roam_offload_synch_ind) +
2236*5113495bSYour Name 		roam_sync_ind->beacon_probe_resp_length +
2237*5113495bSYour Name 		roam_sync_ind->reassoc_resp_length;
2238*5113495bSYour Name 	roam_sync_ind->reassoc_req_length = synch_event->reassoc_req_len;
2239*5113495bSYour Name 	reassoc_req_ptr = (uint8_t *)roam_sync_ind +
2240*5113495bSYour Name 			  roam_sync_ind->reassoc_req_offset;
2241*5113495bSYour Name 	qdf_mem_copy(reassoc_req_ptr, param_buf->reassoc_req_frame,
2242*5113495bSYour Name 		     roam_sync_ind->reassoc_req_length);
2243*5113495bSYour Name }
2244*5113495bSYour Name 
2245*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
2246*5113495bSYour Name #define STANDBY_VDEV_ID (0xFFFFFFFF)
2247*5113495bSYour Name static QDF_STATUS
wmi_fill_roam_mlo_info(wmi_unified_t wmi_handle,WMI_ROAM_SYNCH_EVENTID_param_tlvs * param_buf,struct roam_offload_synch_ind * roam_sync_ind)2248*5113495bSYour Name wmi_fill_roam_mlo_info(wmi_unified_t wmi_handle,
2249*5113495bSYour Name 		       WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
2250*5113495bSYour Name 		       struct roam_offload_synch_ind *roam_sync_ind)
2251*5113495bSYour Name {
2252*5113495bSYour Name 	uint8_t i, mlo_max_allowed_links;
2253*5113495bSYour Name 	wmi_roam_ml_setup_links_param *setup_links;
2254*5113495bSYour Name 	wmi_roam_ml_key_material_param *ml_key_param;
2255*5113495bSYour Name 	struct ml_setup_link_param *link;
2256*5113495bSYour Name 	struct ml_key_material_param *key;
2257*5113495bSYour Name 
2258*5113495bSYour Name 	mlo_max_allowed_links =
2259*5113495bSYour Name 		wlan_mlme_get_sta_mlo_conn_max_num(wmi_handle->soc->wmi_psoc);
2260*5113495bSYour Name 	if (param_buf->num_setup_links_param) {
2261*5113495bSYour Name 		if (param_buf->num_setup_links_param > mlo_max_allowed_links ||
2262*5113495bSYour Name 		    param_buf->num_setup_links_param > WLAN_MAX_ML_BSS_LINKS) {
2263*5113495bSYour Name 			wmi_err("Number of links %d exceeded max vdev supported %d",
2264*5113495bSYour Name 				param_buf->num_setup_links_param,
2265*5113495bSYour Name 				mlo_max_allowed_links);
2266*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2267*5113495bSYour Name 		}
2268*5113495bSYour Name 
2269*5113495bSYour Name 		roam_sync_ind->num_setup_links =
2270*5113495bSYour Name 				param_buf->num_setup_links_param;
2271*5113495bSYour Name 		setup_links = param_buf->setup_links_param;
2272*5113495bSYour Name 
2273*5113495bSYour Name 		for (i = 0; i < roam_sync_ind->num_setup_links; i++) {
2274*5113495bSYour Name 			link = &roam_sync_ind->ml_link[i];
2275*5113495bSYour Name 			link->link_id = setup_links->link_id;
2276*5113495bSYour Name 
2277*5113495bSYour Name 			/*
2278*5113495bSYour Name 			 * setup_links->vdev_id == UINT32_MAX for standby link
2279*5113495bSYour Name 			 */
2280*5113495bSYour Name 			link->vdev_id = WLAN_INVALID_VDEV_ID;
2281*5113495bSYour Name 			if (setup_links->vdev_id != STANDBY_VDEV_ID)
2282*5113495bSYour Name 				link->vdev_id = setup_links->vdev_id;
2283*5113495bSYour Name 
2284*5113495bSYour Name 			link->channel = setup_links->channel;
2285*5113495bSYour Name 			link->flags = setup_links->flags;
2286*5113495bSYour Name 
2287*5113495bSYour Name 			WMI_MAC_ADDR_TO_CHAR_ARRAY(&setup_links->link_addr,
2288*5113495bSYour Name 						   link->link_addr.bytes);
2289*5113495bSYour Name 			WMI_MAC_ADDR_TO_CHAR_ARRAY(&setup_links->self_link_addr,
2290*5113495bSYour Name 						   link->self_link_addr.bytes);
2291*5113495bSYour Name 			wmi_debug("link_id: %u vdev_id: %u flags: 0x%x addr: " QDF_MAC_ADDR_FMT " self_addr:" QDF_MAC_ADDR_FMT,
2292*5113495bSYour Name 				  link->link_id, link->vdev_id,
2293*5113495bSYour Name 				  link->flags,
2294*5113495bSYour Name 				  QDF_MAC_ADDR_REF(link->link_addr.bytes),
2295*5113495bSYour Name 				  QDF_MAC_ADDR_REF(link->self_link_addr.bytes));
2296*5113495bSYour Name 			wmi_debug("channel: %u mhz center_freq1: %u center_freq2: %u",
2297*5113495bSYour Name 				  link->channel.mhz,
2298*5113495bSYour Name 				  link->channel.band_center_freq1,
2299*5113495bSYour Name 				  link->channel.band_center_freq2);
2300*5113495bSYour Name 			setup_links++;
2301*5113495bSYour Name 		}
2302*5113495bSYour Name 	}
2303*5113495bSYour Name 
2304*5113495bSYour Name 	if (!param_buf->num_ml_key_material)
2305*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2306*5113495bSYour Name 
2307*5113495bSYour Name 	if (param_buf->num_ml_key_material > WLAN_MAX_ML_BSS_LINKS)
2308*5113495bSYour Name 		param_buf->num_ml_key_material = WLAN_MAX_ML_BSS_LINKS;
2309*5113495bSYour Name 
2310*5113495bSYour Name 	roam_sync_ind->num_ml_key_material = param_buf->num_ml_key_material;
2311*5113495bSYour Name 	ml_key_param = param_buf->ml_key_material;
2312*5113495bSYour Name 
2313*5113495bSYour Name 	for (i = 0; i < roam_sync_ind->num_ml_key_material; i++) {
2314*5113495bSYour Name 		key = &roam_sync_ind->ml_key[i];
2315*5113495bSYour Name 		key->link_id = ml_key_param->link_id;
2316*5113495bSYour Name 		key->key_idx = ml_key_param->key_ix;
2317*5113495bSYour Name 		key->key_cipher = ml_key_param->key_cipher;
2318*5113495bSYour Name 		qdf_mem_copy(key->pn, ml_key_param->pn,
2319*5113495bSYour Name 			     WMI_MAX_PN_LEN);
2320*5113495bSYour Name 		qdf_mem_copy(key->key_buff, ml_key_param->key_buff,
2321*5113495bSYour Name 			     WMI_MAX_KEY_LEN);
2322*5113495bSYour Name 		wmi_debug("link_id: %u key_idx: %u key_cipher: %u",
2323*5113495bSYour Name 			  key->link_id, key->key_idx, key->key_cipher);
2324*5113495bSYour Name 		ml_key_param++;
2325*5113495bSYour Name 	}
2326*5113495bSYour Name 
2327*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2328*5113495bSYour Name }
2329*5113495bSYour Name #else
2330*5113495bSYour Name static QDF_STATUS
wmi_fill_roam_mlo_info(wmi_unified_t wmi_handle,WMI_ROAM_SYNCH_EVENTID_param_tlvs * param_buf,struct roam_offload_synch_ind * roam_sync_ind)2331*5113495bSYour Name wmi_fill_roam_mlo_info(wmi_unified_t wmi_handle,
2332*5113495bSYour Name 		       WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
2333*5113495bSYour Name 		       struct roam_offload_synch_ind *roam_sync_ind)
2334*5113495bSYour Name {
2335*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2336*5113495bSYour Name }
2337*5113495bSYour Name #endif
2338*5113495bSYour Name 
2339*5113495bSYour Name static QDF_STATUS
wmi_fill_roam_sync_buffer(wmi_unified_t wmi_handle,struct wlan_objmgr_vdev * vdev,struct rso_config * rso_cfg,struct roam_offload_synch_ind * roam_sync_ind,WMI_ROAM_SYNCH_EVENTID_param_tlvs * param_buf)2340*5113495bSYour Name wmi_fill_roam_sync_buffer(wmi_unified_t wmi_handle,
2341*5113495bSYour Name 			  struct wlan_objmgr_vdev *vdev,
2342*5113495bSYour Name 			  struct rso_config *rso_cfg,
2343*5113495bSYour Name 			  struct roam_offload_synch_ind *roam_sync_ind,
2344*5113495bSYour Name 			  WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf)
2345*5113495bSYour Name {
2346*5113495bSYour Name 	wmi_roam_synch_event_fixed_param *synch_event;
2347*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2348*5113495bSYour Name 	wmi_channel *chan = NULL;
2349*5113495bSYour Name 	wmi_key_material *key;
2350*5113495bSYour Name 	wmi_key_material_ext *key_ext;
2351*5113495bSYour Name 	wmi_roam_fils_synch_tlv_param *fils_info;
2352*5113495bSYour Name 	wmi_roam_pmk_cache_synch_tlv_param *pmk_cache_info;
2353*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2354*5113495bSYour Name 	uint8_t kck_len;
2355*5113495bSYour Name 	uint8_t kek_len;
2356*5113495bSYour Name 	struct roam_scan_candidate_frame roam_candidate = {0};
2357*5113495bSYour Name 
2358*5113495bSYour Name 	synch_event = param_buf->fixed_param;
2359*5113495bSYour Name 	roam_sync_ind->roamed_vdev_id = synch_event->vdev_id;
2360*5113495bSYour Name 	roam_sync_ind->auth_status = synch_event->auth_status;
2361*5113495bSYour Name 	roam_sync_ind->roam_reason = synch_event->roam_reason;
2362*5113495bSYour Name 	roam_sync_ind->rssi = -1 * synch_event->rssi;
2363*5113495bSYour Name 	roam_sync_ind->is_beacon = synch_event->is_beacon;
2364*5113495bSYour Name 
2365*5113495bSYour Name 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&synch_event->bssid,
2366*5113495bSYour Name 				   roam_sync_ind->bssid.bytes);
2367*5113495bSYour Name 	wmi_debug("roamed_vdev_id %d auth_status %d roam_reason %d rssi %d is_beacon %d",
2368*5113495bSYour Name 		  roam_sync_ind->roamed_vdev_id,
2369*5113495bSYour Name 		  roam_sync_ind->auth_status,
2370*5113495bSYour Name 		  roam_sync_ind->roam_reason,
2371*5113495bSYour Name 		  roam_sync_ind->rssi,
2372*5113495bSYour Name 		  roam_sync_ind->is_beacon);
2373*5113495bSYour Name 
2374*5113495bSYour Name 	cdp_update_roaming_peer_in_vdev(soc, synch_event->vdev_id,
2375*5113495bSYour Name 					roam_sync_ind->bssid.bytes,
2376*5113495bSYour Name 					synch_event->auth_status);
2377*5113495bSYour Name 	/*
2378*5113495bSYour Name 	 * If lengths of bcn_probe_rsp, reassoc_req and reassoc_rsp are zero in
2379*5113495bSYour Name 	 * synch_event driver would have received bcn_probe_rsp, reassoc_req
2380*5113495bSYour Name 	 * and reassoc_rsp via the event WMI_ROAM_SYNCH_FRAME_EVENTID
2381*5113495bSYour Name 	 */
2382*5113495bSYour Name 	if ((!synch_event->bcn_probe_rsp_len) &&
2383*5113495bSYour Name 	    (!synch_event->reassoc_req_len) &&
2384*5113495bSYour Name 	    (!synch_event->reassoc_rsp_len)) {
2385*5113495bSYour Name 		if (!rso_cfg->roam_sync_frame_ind.bcn_probe_rsp) {
2386*5113495bSYour Name 			wmi_err("LFR3: bcn_probe_rsp is NULL");
2387*5113495bSYour Name 			QDF_ASSERT(rso_cfg->roam_sync_frame_ind.bcn_probe_rsp);
2388*5113495bSYour Name 			wlan_cm_free_roam_synch_frame_ind(rso_cfg);
2389*5113495bSYour Name 			return status;
2390*5113495bSYour Name 		}
2391*5113495bSYour Name 
2392*5113495bSYour Name 		if (!rso_cfg->roam_sync_frame_ind.reassoc_rsp) {
2393*5113495bSYour Name 			wmi_err("LFR3: reassoc_rsp is NULL");
2394*5113495bSYour Name 			QDF_ASSERT(rso_cfg->roam_sync_frame_ind.reassoc_rsp);
2395*5113495bSYour Name 			wlan_cm_free_roam_synch_frame_ind(rso_cfg);
2396*5113495bSYour Name 			return status;
2397*5113495bSYour Name 		}
2398*5113495bSYour Name 		if (!rso_cfg->roam_sync_frame_ind.reassoc_req) {
2399*5113495bSYour Name 			wmi_err("LFR3: reassoc_req is NULL");
2400*5113495bSYour Name 			QDF_ASSERT(rso_cfg->roam_sync_frame_ind.reassoc_req);
2401*5113495bSYour Name 			wlan_cm_free_roam_synch_frame_ind(rso_cfg);
2402*5113495bSYour Name 			return status;
2403*5113495bSYour Name 		}
2404*5113495bSYour Name 		wmi_fill_data_synch_frame_event(rso_cfg, roam_sync_ind);
2405*5113495bSYour Name 	} else {
2406*5113495bSYour Name 		wmi_fill_data_synch_event(roam_sync_ind, param_buf);
2407*5113495bSYour Name 
2408*5113495bSYour Name 		roam_candidate.vdev_id = roam_sync_ind->roamed_vdev_id;
2409*5113495bSYour Name 		roam_candidate.frame_length =
2410*5113495bSYour Name 				roam_sync_ind->beacon_probe_resp_length;
2411*5113495bSYour Name 		roam_candidate.frame = (uint8_t *)roam_sync_ind +
2412*5113495bSYour Name 				       roam_sync_ind->beacon_probe_resp_offset;
2413*5113495bSYour Name 		roam_candidate.rssi = roam_sync_ind->rssi;
2414*5113495bSYour Name 		roam_candidate.roam_offload_candidate_frm = false;
2415*5113495bSYour Name 		wlan_cm_add_all_link_probe_rsp_to_scan_db(wlan_vdev_get_psoc(vdev),
2416*5113495bSYour Name 							  &roam_candidate);
2417*5113495bSYour Name 	}
2418*5113495bSYour Name 	chan = param_buf->chan;
2419*5113495bSYour Name 	if (chan) {
2420*5113495bSYour Name 		roam_sync_ind->chan_freq = chan->mhz;
2421*5113495bSYour Name 		roam_sync_ind->phy_mode =
2422*5113495bSYour Name 			wlan_cm_fw_to_host_phymode(WMI_GET_CHANNEL_MODE(chan));
2423*5113495bSYour Name 		roam_sync_ind->chan = *chan;
2424*5113495bSYour Name 	} else {
2425*5113495bSYour Name 		roam_sync_ind->phy_mode = WLAN_PHYMODE_AUTO;
2426*5113495bSYour Name 	}
2427*5113495bSYour Name 
2428*5113495bSYour Name 	key = param_buf->key;
2429*5113495bSYour Name 	key_ext = param_buf->key_ext;
2430*5113495bSYour Name 	if (key) {
2431*5113495bSYour Name 		roam_sync_ind->kck_len = KCK_KEY_LEN;
2432*5113495bSYour Name 		qdf_mem_copy(roam_sync_ind->kck, key->kck,
2433*5113495bSYour Name 			     KCK_KEY_LEN);
2434*5113495bSYour Name 		roam_sync_ind->kek_len = KEK_KEY_LEN;
2435*5113495bSYour Name 		qdf_mem_copy(roam_sync_ind->kek, key->kek,
2436*5113495bSYour Name 			     KEK_KEY_LEN);
2437*5113495bSYour Name 		qdf_mem_copy(roam_sync_ind->replay_ctr,
2438*5113495bSYour Name 			     key->replay_counter, REPLAY_CTR_LEN);
2439*5113495bSYour Name 	} else if (key_ext) {
2440*5113495bSYour Name 		/*
2441*5113495bSYour Name 		 * key_ext carries key materials whose size
2442*5113495bSYour Name 		 * is greater than conventional 16bytes.
2443*5113495bSYour Name 		 */
2444*5113495bSYour Name 		kck_len = key_ext->kck_len ?
2445*5113495bSYour Name 				key_ext->kck_len : KCK_192BIT_KEY_LEN;
2446*5113495bSYour Name 		kek_len = key_ext->kek_len ?
2447*5113495bSYour Name 				key_ext->kek_len : KEK_256BIT_KEY_LEN;
2448*5113495bSYour Name 
2449*5113495bSYour Name 		roam_sync_ind->kck_len = kck_len;
2450*5113495bSYour Name 		qdf_mem_copy(roam_sync_ind->kck,
2451*5113495bSYour Name 			     key_ext->key_buffer, kck_len);
2452*5113495bSYour Name 
2453*5113495bSYour Name 		roam_sync_ind->kek_len = kek_len;
2454*5113495bSYour Name 		qdf_mem_copy(roam_sync_ind->kek,
2455*5113495bSYour Name 			     (key_ext->key_buffer + kck_len),
2456*5113495bSYour Name 			     kek_len);
2457*5113495bSYour Name 
2458*5113495bSYour Name 		qdf_mem_copy(roam_sync_ind->replay_ctr,
2459*5113495bSYour Name 			     (key_ext->key_buffer + kek_len + kck_len),
2460*5113495bSYour Name 			     REPLAY_CTR_LEN);
2461*5113495bSYour Name 	}
2462*5113495bSYour Name 
2463*5113495bSYour Name 	wmi_debug("ROAM_SYNC kek_len %d kck_len %d",
2464*5113495bSYour Name 		  roam_sync_ind->kek_len,
2465*5113495bSYour Name 		  roam_sync_ind->kck_len);
2466*5113495bSYour Name 
2467*5113495bSYour Name 	if (param_buf->hw_mode_transition_fixed_param) {
2468*5113495bSYour Name 		wmi_extract_pdev_hw_mode_trans_ind(
2469*5113495bSYour Name 		    param_buf->hw_mode_transition_fixed_param,
2470*5113495bSYour Name 		    param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping,
2471*5113495bSYour Name 		    &roam_sync_ind->hw_mode_trans_ind);
2472*5113495bSYour Name 		roam_sync_ind->hw_mode_trans_present = true;
2473*5113495bSYour Name 	} else {
2474*5113495bSYour Name 		wmi_debug("hw_mode transition fixed param is NULL");
2475*5113495bSYour Name 	}
2476*5113495bSYour Name 
2477*5113495bSYour Name 	fils_info = param_buf->roam_fils_synch_info;
2478*5113495bSYour Name 	if (fils_info) {
2479*5113495bSYour Name 		if ((fils_info->kek_len > MAX_KEK_LENGTH) ||
2480*5113495bSYour Name 		    (fils_info->pmk_len > MAX_PMK_LEN)) {
2481*5113495bSYour Name 			wmi_err("Invalid kek_len %d or pmk_len %d",
2482*5113495bSYour Name 				fils_info->kek_len,
2483*5113495bSYour Name 				fils_info->pmk_len);
2484*5113495bSYour Name 			wlan_cm_free_roam_synch_frame_ind(rso_cfg);
2485*5113495bSYour Name 			return status;
2486*5113495bSYour Name 		}
2487*5113495bSYour Name 
2488*5113495bSYour Name 		roam_sync_ind->kek_len = fils_info->kek_len;
2489*5113495bSYour Name 		qdf_mem_copy(roam_sync_ind->kek, fils_info->kek,
2490*5113495bSYour Name 			     fils_info->kek_len);
2491*5113495bSYour Name 
2492*5113495bSYour Name 		roam_sync_ind->pmk_len = fils_info->pmk_len;
2493*5113495bSYour Name 		qdf_mem_copy(roam_sync_ind->pmk, fils_info->pmk,
2494*5113495bSYour Name 			     fils_info->pmk_len);
2495*5113495bSYour Name 
2496*5113495bSYour Name 		qdf_mem_copy(roam_sync_ind->pmkid, fils_info->pmkid,
2497*5113495bSYour Name 			     PMKID_LEN);
2498*5113495bSYour Name 
2499*5113495bSYour Name 		roam_sync_ind->update_erp_next_seq_num =
2500*5113495bSYour Name 				fils_info->update_erp_next_seq_num;
2501*5113495bSYour Name 		roam_sync_ind->next_erp_seq_num =
2502*5113495bSYour Name 				fils_info->next_erp_seq_num;
2503*5113495bSYour Name 
2504*5113495bSYour Name 		wmi_debug("Update ERP Seq Num %d, Next ERP Seq Num %d KEK len %d",
2505*5113495bSYour Name 			  roam_sync_ind->update_erp_next_seq_num,
2506*5113495bSYour Name 			  roam_sync_ind->next_erp_seq_num,
2507*5113495bSYour Name 			  roam_sync_ind->kek_len);
2508*5113495bSYour Name 	}
2509*5113495bSYour Name 
2510*5113495bSYour Name 	pmk_cache_info = param_buf->roam_pmk_cache_synch_info;
2511*5113495bSYour Name 	if (pmk_cache_info && (pmk_cache_info->pmk_len)) {
2512*5113495bSYour Name 		if (pmk_cache_info->pmk_len > MAX_PMK_LEN) {
2513*5113495bSYour Name 			wmi_err("Invalid pmk_len %d",
2514*5113495bSYour Name 				pmk_cache_info->pmk_len);
2515*5113495bSYour Name 			wlan_cm_free_roam_synch_frame_ind(rso_cfg);
2516*5113495bSYour Name 			return status;
2517*5113495bSYour Name 		}
2518*5113495bSYour Name 
2519*5113495bSYour Name 		roam_sync_ind->pmk_len = pmk_cache_info->pmk_len;
2520*5113495bSYour Name 		qdf_mem_copy(roam_sync_ind->pmk,
2521*5113495bSYour Name 			     pmk_cache_info->pmk, pmk_cache_info->pmk_len);
2522*5113495bSYour Name 		qdf_mem_copy(roam_sync_ind->pmkid,
2523*5113495bSYour Name 			     pmk_cache_info->pmkid, PMKID_LEN);
2524*5113495bSYour Name 	}
2525*5113495bSYour Name 
2526*5113495bSYour Name 	status = wmi_fill_roam_mlo_info(wmi_handle, param_buf, roam_sync_ind);
2527*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
2528*5113495bSYour Name 		wmi_err("Failed to fill roam mlo info");
2529*5113495bSYour Name 		return status;
2530*5113495bSYour Name 	}
2531*5113495bSYour Name 	wlan_cm_free_roam_synch_frame_ind(rso_cfg);
2532*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2533*5113495bSYour Name }
2534*5113495bSYour Name 
2535*5113495bSYour Name /**
2536*5113495bSYour Name  * extract_roam_sync_event_tlv() - Extract the roam sync event
2537*5113495bSYour Name  * from the wmi_roam_synch_event_id
2538*5113495bSYour Name  * @wmi_handle: wmi handle
2539*5113495bSYour Name  * @evt_buf:    Pointer to the event buffer
2540*5113495bSYour Name  * @len:        Data length
2541*5113495bSYour Name  * @roam_sync_ind: Ptr to roam offload sync struct
2542*5113495bSYour Name  */
2543*5113495bSYour Name static QDF_STATUS
extract_roam_sync_event_tlv(wmi_unified_t wmi_handle,void * evt_buf,uint32_t len,struct roam_offload_synch_ind ** roam_sync_ind)2544*5113495bSYour Name extract_roam_sync_event_tlv(wmi_unified_t wmi_handle, void *evt_buf,
2545*5113495bSYour Name 			    uint32_t len,
2546*5113495bSYour Name 			    struct roam_offload_synch_ind **roam_sync_ind)
2547*5113495bSYour Name {
2548*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2549*5113495bSYour Name 	wmi_roam_synch_event_fixed_param *synch_event = NULL;
2550*5113495bSYour Name 	WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf = NULL;
2551*5113495bSYour Name 	struct roam_offload_synch_ind *roam_sync = NULL;
2552*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev = NULL;
2553*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = NULL;
2554*5113495bSYour Name 	struct rso_config *rso_cfg;
2555*5113495bSYour Name 	uint32_t roam_synch_data_len;
2556*5113495bSYour Name 	uint32_t bcn_probe_rsp_len, link_bcn_probe_rsp_len;
2557*5113495bSYour Name 	uint32_t reassoc_rsp_len;
2558*5113495bSYour Name 	uint32_t reassoc_req_len;
2559*5113495bSYour Name 	wmi_pdev_hw_mode_transition_event_fixed_param *hw_mode_trans_param;
2560*5113495bSYour Name 
2561*5113495bSYour Name 	if (!evt_buf) {
2562*5113495bSYour Name 		wmi_debug("Empty roam_sync_event param buf");
2563*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2564*5113495bSYour Name 	}
2565*5113495bSYour Name 
2566*5113495bSYour Name 	param_buf = (WMI_ROAM_SYNCH_EVENTID_param_tlvs *)evt_buf;
2567*5113495bSYour Name 	if (!param_buf) {
2568*5113495bSYour Name 		wmi_debug("received null buf from target");
2569*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2570*5113495bSYour Name 	}
2571*5113495bSYour Name 
2572*5113495bSYour Name 	synch_event = param_buf->fixed_param;
2573*5113495bSYour Name 	if (!synch_event) {
2574*5113495bSYour Name 		wmi_debug("received null event data from target");
2575*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2576*5113495bSYour Name 	}
2577*5113495bSYour Name 	hw_mode_trans_param = param_buf->hw_mode_transition_fixed_param;
2578*5113495bSYour Name 	if (hw_mode_trans_param &&
2579*5113495bSYour Name 	    hw_mode_trans_param->num_vdev_mac_entries >
2580*5113495bSYour Name 	    param_buf->num_wmi_pdev_set_hw_mode_response_vdev_mac_mapping) {
2581*5113495bSYour Name 		wmi_debug("invalid vdev mac entries %d %d in roam sync",
2582*5113495bSYour Name 			  hw_mode_trans_param->num_vdev_mac_entries,
2583*5113495bSYour Name 			  param_buf->num_wmi_pdev_set_hw_mode_response_vdev_mac_mapping);
2584*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2585*5113495bSYour Name 	}
2586*5113495bSYour Name 
2587*5113495bSYour Name 	if (synch_event->vdev_id >= WLAN_MAX_VDEVS) {
2588*5113495bSYour Name 		wmi_err("received invalid vdev_id %d",
2589*5113495bSYour Name 			synch_event->vdev_id);
2590*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2591*5113495bSYour Name 	}
2592*5113495bSYour Name 
2593*5113495bSYour Name 	psoc = wmi_handle->soc->wmi_psoc;
2594*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, synch_event->vdev_id,
2595*5113495bSYour Name 						    WLAN_MLME_SB_ID);
2596*5113495bSYour Name 	if (!vdev) {
2597*5113495bSYour Name 		wmi_err("For vdev:%d object is NULL", synch_event->vdev_id);
2598*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2599*5113495bSYour Name 	}
2600*5113495bSYour Name 
2601*5113495bSYour Name 	if (synch_event->bcn_probe_rsp_len >
2602*5113495bSYour Name 		param_buf->num_bcn_probe_rsp_frame ||
2603*5113495bSYour Name 		synch_event->reassoc_req_len >
2604*5113495bSYour Name 		param_buf->num_reassoc_req_frame ||
2605*5113495bSYour Name 		synch_event->reassoc_rsp_len >
2606*5113495bSYour Name 		param_buf->num_reassoc_rsp_frame) {
2607*5113495bSYour Name 		wmi_debug("Invalid sync payload: LEN bcn:%d, req:%d, rsp:%d, vdev:%d",
2608*5113495bSYour Name 			  synch_event->bcn_probe_rsp_len,
2609*5113495bSYour Name 			  synch_event->reassoc_req_len,
2610*5113495bSYour Name 			  synch_event->reassoc_rsp_len,
2611*5113495bSYour Name 			  synch_event->vdev_id);
2612*5113495bSYour Name 		status = QDF_STATUS_E_FAILURE;
2613*5113495bSYour Name 		goto abort_roam;
2614*5113495bSYour Name 	}
2615*5113495bSYour Name 
2616*5113495bSYour Name 	rso_cfg = wlan_cm_get_rso_config(vdev);
2617*5113495bSYour Name 	if (!rso_cfg) {
2618*5113495bSYour Name 		status = QDF_STATUS_E_FAILURE;
2619*5113495bSYour Name 		goto abort_roam;
2620*5113495bSYour Name 	}
2621*5113495bSYour Name 
2622*5113495bSYour Name 	/*
2623*5113495bSYour Name 	 * All below length fields are unsigned and hence positive numbers.
2624*5113495bSYour Name 	 * Maximum number during the addition would be (3 * MAX_LIMIT(UINT32) +
2625*5113495bSYour Name 	 * few fixed fields).
2626*5113495bSYour Name 	 */
2627*5113495bSYour Name 	wmi_debug("synch payload: LEN bcn:%d, req:%d, rsp:%d",
2628*5113495bSYour Name 		  synch_event->bcn_probe_rsp_len,
2629*5113495bSYour Name 		  synch_event->reassoc_req_len,
2630*5113495bSYour Name 		  synch_event->reassoc_rsp_len);
2631*5113495bSYour Name 
2632*5113495bSYour Name 	/*
2633*5113495bSYour Name 	 * If lengths of bcn_probe_rsp, reassoc_req and reassoc_rsp are zero in
2634*5113495bSYour Name 	 * synch_event driver would have received bcn_probe_rsp, reassoc_req
2635*5113495bSYour Name 	 * and reassoc_rsp via the event WMI_ROAM_SYNCH_FRAME_EVENTID
2636*5113495bSYour Name 	 */
2637*5113495bSYour Name 	if ((!synch_event->bcn_probe_rsp_len) &&
2638*5113495bSYour Name 	    (!synch_event->reassoc_req_len) &&
2639*5113495bSYour Name 	    (!synch_event->reassoc_rsp_len)) {
2640*5113495bSYour Name 		bcn_probe_rsp_len =
2641*5113495bSYour Name 			rso_cfg->roam_sync_frame_ind.bcn_probe_rsp_len;
2642*5113495bSYour Name 		link_bcn_probe_rsp_len =
2643*5113495bSYour Name 			rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp_len;
2644*5113495bSYour Name 		reassoc_req_len = rso_cfg->roam_sync_frame_ind.reassoc_req_len;
2645*5113495bSYour Name 		reassoc_rsp_len = rso_cfg->roam_sync_frame_ind.reassoc_rsp_len;
2646*5113495bSYour Name 
2647*5113495bSYour Name 		roam_synch_data_len =
2648*5113495bSYour Name 			bcn_probe_rsp_len + link_bcn_probe_rsp_len +
2649*5113495bSYour Name 			reassoc_rsp_len + reassoc_req_len +
2650*5113495bSYour Name 			sizeof(struct roam_offload_synch_ind);
2651*5113495bSYour Name 
2652*5113495bSYour Name 		wmi_debug("Updated synch payload: LEN bcn:%d, link bcn: %d req:%d, rsp:%d",
2653*5113495bSYour Name 			  bcn_probe_rsp_len,
2654*5113495bSYour Name 			  link_bcn_probe_rsp_len,
2655*5113495bSYour Name 			  reassoc_req_len,
2656*5113495bSYour Name 			  reassoc_rsp_len);
2657*5113495bSYour Name 	} else {
2658*5113495bSYour Name 		bcn_probe_rsp_len = synch_event->bcn_probe_rsp_len;
2659*5113495bSYour Name 		reassoc_req_len = synch_event->reassoc_req_len;
2660*5113495bSYour Name 		reassoc_rsp_len = synch_event->reassoc_rsp_len;
2661*5113495bSYour Name 
2662*5113495bSYour Name 		roam_synch_data_len = bcn_probe_rsp_len +
2663*5113495bSYour Name 			reassoc_rsp_len + reassoc_req_len;
2664*5113495bSYour Name 		roam_synch_data_len += sizeof(struct roam_offload_synch_ind);
2665*5113495bSYour Name 	}
2666*5113495bSYour Name 
2667*5113495bSYour Name 	roam_sync = qdf_mem_malloc(roam_synch_data_len);
2668*5113495bSYour Name 	if (!roam_sync) {
2669*5113495bSYour Name 		QDF_ASSERT(roam_sync);
2670*5113495bSYour Name 		status = QDF_STATUS_E_NOMEM;
2671*5113495bSYour Name 		goto abort_roam;
2672*5113495bSYour Name 	}
2673*5113495bSYour Name 
2674*5113495bSYour Name 	*roam_sync_ind = roam_sync;
2675*5113495bSYour Name 	status = wmi_fill_roam_sync_buffer(wmi_handle, vdev, rso_cfg,
2676*5113495bSYour Name 					   roam_sync, param_buf);
2677*5113495bSYour Name 
2678*5113495bSYour Name abort_roam:
2679*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
2680*5113495bSYour Name 		wmi_err("%d Failed to extract roam sync ind", status);
2681*5113495bSYour Name 		wlan_cm_roam_state_change(wlan_vdev_get_pdev(vdev),
2682*5113495bSYour Name 					  synch_event->vdev_id,
2683*5113495bSYour Name 					  WLAN_ROAM_RSO_STOPPED,
2684*5113495bSYour Name 					  REASON_ROAM_SYNCH_FAILED);
2685*5113495bSYour Name 	}
2686*5113495bSYour Name 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID);
2687*5113495bSYour Name 	return status;
2688*5113495bSYour Name }
2689*5113495bSYour Name 
2690*5113495bSYour Name /**
2691*5113495bSYour Name  * extract_roam_sync_frame_event_tlv() - Extract the roam sync frame event
2692*5113495bSYour Name  * from the wmi_roam_synch_event_id
2693*5113495bSYour Name  * @wmi_handle: wmi handle
2694*5113495bSYour Name  * @event: Pointer to the event buffer
2695*5113495bSYour Name  * @len: event buffer length
2696*5113495bSYour Name  * @frame_ptr: wmi sync frame event ptr
2697*5113495bSYour Name  */
2698*5113495bSYour Name static QDF_STATUS
extract_roam_sync_frame_event_tlv(wmi_unified_t wmi_handle,void * event,uint32_t len,struct roam_synch_frame_ind * frame_ptr)2699*5113495bSYour Name extract_roam_sync_frame_event_tlv(wmi_unified_t wmi_handle, void *event,
2700*5113495bSYour Name 				  uint32_t len,
2701*5113495bSYour Name 				  struct roam_synch_frame_ind *frame_ptr)
2702*5113495bSYour Name {
2703*5113495bSYour Name 	WMI_ROAM_SYNCH_FRAME_EVENTID_param_tlvs *param_buf = NULL;
2704*5113495bSYour Name 	struct roam_synch_frame_ind *frame_ind;
2705*5113495bSYour Name 	wmi_roam_synch_frame_event_fixed_param *frame_evt;
2706*5113495bSYour Name 
2707*5113495bSYour Name 	if (!event) {
2708*5113495bSYour Name 		wmi_err("Event param null");
2709*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
2710*5113495bSYour Name 	}
2711*5113495bSYour Name 
2712*5113495bSYour Name 	param_buf = (WMI_ROAM_SYNCH_FRAME_EVENTID_param_tlvs *)event;
2713*5113495bSYour Name 	if (!param_buf) {
2714*5113495bSYour Name 		wmi_err("received null buf from target");
2715*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
2716*5113495bSYour Name 	}
2717*5113495bSYour Name 
2718*5113495bSYour Name 	frame_evt = param_buf->fixed_param;
2719*5113495bSYour Name 	if (!frame_evt) {
2720*5113495bSYour Name 		wmi_err("received null event data from target");
2721*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
2722*5113495bSYour Name 	}
2723*5113495bSYour Name 
2724*5113495bSYour Name 	if (frame_evt->vdev_id >= WLAN_MAX_VDEVS) {
2725*5113495bSYour Name 		wmi_err("received invalid vdev_id %d", frame_evt->vdev_id);
2726*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2727*5113495bSYour Name 	}
2728*5113495bSYour Name 
2729*5113495bSYour Name 	/*
2730*5113495bSYour Name 	 * Firmware can send more than one roam synch frame event to host
2731*5113495bSYour Name 	 * driver. So Bcn_prb_rsp_len/reassoc_req_len/reassoc_rsp_len can be 0
2732*5113495bSYour Name 	 * in some of the events.
2733*5113495bSYour Name 	 */
2734*5113495bSYour Name 	if (frame_evt->bcn_probe_rsp_len > param_buf->num_bcn_probe_rsp_frame ||
2735*5113495bSYour Name 	    frame_evt->reassoc_req_len > param_buf->num_reassoc_req_frame ||
2736*5113495bSYour Name 	    frame_evt->reassoc_rsp_len > param_buf->num_reassoc_rsp_frame ||
2737*5113495bSYour Name 	    (frame_evt->bcn_probe_rsp_len &&
2738*5113495bSYour Name 	     frame_evt->bcn_probe_rsp_len < sizeof(struct wlan_frame_hdr)) ||
2739*5113495bSYour Name 	    (frame_evt->reassoc_req_len &&
2740*5113495bSYour Name 	     frame_evt->reassoc_req_len < sizeof(struct wlan_frame_hdr)) ||
2741*5113495bSYour Name 	    (frame_evt->reassoc_rsp_len &&
2742*5113495bSYour Name 	     frame_evt->reassoc_rsp_len < sizeof(struct wlan_frame_hdr))) {
2743*5113495bSYour Name 		wmi_err("fixed/actual len err: bcn:%d/%d req:%d/%d rsp:%d/%d",
2744*5113495bSYour Name 			frame_evt->bcn_probe_rsp_len,
2745*5113495bSYour Name 			param_buf->num_bcn_probe_rsp_frame,
2746*5113495bSYour Name 			frame_evt->reassoc_req_len,
2747*5113495bSYour Name 			param_buf->num_reassoc_req_frame,
2748*5113495bSYour Name 			frame_evt->reassoc_rsp_len,
2749*5113495bSYour Name 			param_buf->num_reassoc_rsp_frame);
2750*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2751*5113495bSYour Name 	}
2752*5113495bSYour Name 
2753*5113495bSYour Name 	frame_ind = frame_ptr;
2754*5113495bSYour Name 	frame_ind->vdev_id = frame_evt->vdev_id;
2755*5113495bSYour Name 
2756*5113495bSYour Name 	wmi_debug("synch frame payload: LEN %s bcn:%d, req:%d, rsp:%d",
2757*5113495bSYour Name 		  frame_evt->reassoc_rsp_len ? "Assoc" : "Link",
2758*5113495bSYour Name 		  frame_evt->bcn_probe_rsp_len,
2759*5113495bSYour Name 		  frame_evt->reassoc_req_len,
2760*5113495bSYour Name 		  frame_evt->reassoc_rsp_len);
2761*5113495bSYour Name 
2762*5113495bSYour Name 	if (frame_evt->bcn_probe_rsp_len &&
2763*5113495bSYour Name 	    frame_evt->reassoc_rsp_len) {
2764*5113495bSYour Name 		frame_ind->bcn_probe_rsp_len = frame_evt->bcn_probe_rsp_len;
2765*5113495bSYour Name 
2766*5113495bSYour Name 		frame_ind->is_beacon = frame_evt->is_beacon;
2767*5113495bSYour Name 
2768*5113495bSYour Name 		frame_ind->bcn_probe_rsp =
2769*5113495bSYour Name 			qdf_mem_malloc(frame_ind->bcn_probe_rsp_len);
2770*5113495bSYour Name 		if (!frame_ind->bcn_probe_rsp) {
2771*5113495bSYour Name 			QDF_ASSERT(frame_ind->bcn_probe_rsp);
2772*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
2773*5113495bSYour Name 		}
2774*5113495bSYour Name 		qdf_mem_copy(frame_ind->bcn_probe_rsp,
2775*5113495bSYour Name 			     param_buf->bcn_probe_rsp_frame,
2776*5113495bSYour Name 			     frame_ind->bcn_probe_rsp_len);
2777*5113495bSYour Name 	} else if (frame_evt->bcn_probe_rsp_len) {
2778*5113495bSYour Name 		frame_ind->link_bcn_probe_rsp_len =
2779*5113495bSYour Name 			frame_evt->bcn_probe_rsp_len;
2780*5113495bSYour Name 
2781*5113495bSYour Name 		frame_ind->is_link_beacon = frame_evt->is_beacon;
2782*5113495bSYour Name 
2783*5113495bSYour Name 		if (frame_ind->link_bcn_probe_rsp)
2784*5113495bSYour Name 			qdf_mem_free(frame_ind->bcn_probe_rsp);
2785*5113495bSYour Name 
2786*5113495bSYour Name 		frame_ind->link_bcn_probe_rsp =
2787*5113495bSYour Name 			qdf_mem_malloc(frame_ind->link_bcn_probe_rsp_len);
2788*5113495bSYour Name 		if (!frame_ind->link_bcn_probe_rsp) {
2789*5113495bSYour Name 			QDF_ASSERT(frame_ind->link_bcn_probe_rsp);
2790*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
2791*5113495bSYour Name 		}
2792*5113495bSYour Name 		qdf_mem_copy(frame_ind->link_bcn_probe_rsp,
2793*5113495bSYour Name 			     param_buf->bcn_probe_rsp_frame,
2794*5113495bSYour Name 			     frame_ind->link_bcn_probe_rsp_len);
2795*5113495bSYour Name 	}
2796*5113495bSYour Name 
2797*5113495bSYour Name 	if (frame_evt->reassoc_req_len) {
2798*5113495bSYour Name 		frame_ind->reassoc_req_len = frame_evt->reassoc_req_len;
2799*5113495bSYour Name 
2800*5113495bSYour Name 		frame_ind->reassoc_req =
2801*5113495bSYour Name 			qdf_mem_malloc(frame_ind->reassoc_req_len);
2802*5113495bSYour Name 		if (!frame_ind->reassoc_req) {
2803*5113495bSYour Name 			QDF_ASSERT(frame_ind->reassoc_req);
2804*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
2805*5113495bSYour Name 		}
2806*5113495bSYour Name 		qdf_mem_copy(frame_ind->reassoc_req,
2807*5113495bSYour Name 			     param_buf->reassoc_req_frame,
2808*5113495bSYour Name 			     frame_ind->reassoc_req_len);
2809*5113495bSYour Name 	}
2810*5113495bSYour Name 
2811*5113495bSYour Name 	if (frame_evt->reassoc_rsp_len) {
2812*5113495bSYour Name 		frame_ind->reassoc_rsp_len = frame_evt->reassoc_rsp_len;
2813*5113495bSYour Name 
2814*5113495bSYour Name 		frame_ind->reassoc_rsp =
2815*5113495bSYour Name 			qdf_mem_malloc(frame_ind->reassoc_rsp_len);
2816*5113495bSYour Name 		if (!frame_ind->reassoc_rsp) {
2817*5113495bSYour Name 			QDF_ASSERT(frame_ind->reassoc_rsp);
2818*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
2819*5113495bSYour Name 		}
2820*5113495bSYour Name 		qdf_mem_copy(frame_ind->reassoc_rsp,
2821*5113495bSYour Name 			     param_buf->reassoc_rsp_frame,
2822*5113495bSYour Name 			     frame_ind->reassoc_rsp_len);
2823*5113495bSYour Name 	}
2824*5113495bSYour Name 
2825*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2826*5113495bSYour Name }
2827*5113495bSYour Name 
wmi_get_reject_reason(uint32_t reason)2828*5113495bSYour Name static enum dlm_reject_ap_reason wmi_get_reject_reason(uint32_t reason)
2829*5113495bSYour Name {
2830*5113495bSYour Name 	switch (reason) {
2831*5113495bSYour Name 	case WMI_BL_REASON_NUD_FAILURE:
2832*5113495bSYour Name 		return REASON_NUD_FAILURE;
2833*5113495bSYour Name 	case WMI_BL_REASON_STA_KICKOUT:
2834*5113495bSYour Name 		return REASON_STA_KICKOUT;
2835*5113495bSYour Name 	case WMI_BL_REASON_ROAM_HO_FAILURE:
2836*5113495bSYour Name 		return REASON_ROAM_HO_FAILURE;
2837*5113495bSYour Name 	case WMI_BL_REASON_ASSOC_REJECT_POOR_RSSI:
2838*5113495bSYour Name 		return REASON_ASSOC_REJECT_POOR_RSSI;
2839*5113495bSYour Name 	case WMI_BL_REASON_ASSOC_REJECT_OCE:
2840*5113495bSYour Name 		return REASON_ASSOC_REJECT_OCE;
2841*5113495bSYour Name 	case WMI_BL_REASON_USERSPACE_BL:
2842*5113495bSYour Name 		return REASON_USERSPACE_BL;
2843*5113495bSYour Name 	case WMI_BL_REASON_USERSPACE_AVOID_LIST:
2844*5113495bSYour Name 		return REASON_USERSPACE_AVOID_LIST;
2845*5113495bSYour Name 	case WMI_BL_REASON_BTM_DIASSOC_IMMINENT:
2846*5113495bSYour Name 		return REASON_BTM_DISASSOC_IMMINENT;
2847*5113495bSYour Name 	case WMI_BL_REASON_BTM_BSS_TERMINATION:
2848*5113495bSYour Name 		return REASON_BTM_BSS_TERMINATION;
2849*5113495bSYour Name 	case WMI_BL_REASON_BTM_MBO_RETRY:
2850*5113495bSYour Name 		return REASON_BTM_MBO_RETRY;
2851*5113495bSYour Name 	case WMI_BL_REASON_REASSOC_RSSI_REJECT:
2852*5113495bSYour Name 		return REASON_REASSOC_RSSI_REJECT;
2853*5113495bSYour Name 	case WMI_BL_REASON_REASSOC_NO_MORE_STAS:
2854*5113495bSYour Name 		return REASON_REASSOC_NO_MORE_STAS;
2855*5113495bSYour Name 	default:
2856*5113495bSYour Name 		return REASON_UNKNOWN;
2857*5113495bSYour Name 	}
2858*5113495bSYour Name }
2859*5113495bSYour Name 
2860*5113495bSYour Name static QDF_STATUS
extract_btm_denylist_event(wmi_unified_t wmi_handle,uint8_t * event,uint32_t len,struct roam_denylist_event ** list)2861*5113495bSYour Name extract_btm_denylist_event(wmi_unified_t wmi_handle,
2862*5113495bSYour Name 			   uint8_t *event, uint32_t len,
2863*5113495bSYour Name 			   struct roam_denylist_event **list)
2864*5113495bSYour Name {
2865*5113495bSYour Name 	WMI_ROAM_BLACKLIST_EVENTID_param_tlvs *param_buf;
2866*5113495bSYour Name 	wmi_roam_blacklist_event_fixed_param *resp_event;
2867*5113495bSYour Name 	wmi_roam_blacklist_with_timeout_tlv_param *src_list;
2868*5113495bSYour Name 	struct roam_denylist_timeout *roam_denylist;
2869*5113495bSYour Name 	struct roam_denylist_event *dst_list;
2870*5113495bSYour Name 	uint32_t num_entries, i;
2871*5113495bSYour Name 
2872*5113495bSYour Name 	param_buf = (WMI_ROAM_BLACKLIST_EVENTID_param_tlvs *)event;
2873*5113495bSYour Name 	if (!param_buf) {
2874*5113495bSYour Name 		wmi_err("Invalid event buffer");
2875*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2876*5113495bSYour Name 	}
2877*5113495bSYour Name 
2878*5113495bSYour Name 	resp_event = param_buf->fixed_param;
2879*5113495bSYour Name 	if (!resp_event) {
2880*5113495bSYour Name 		wmi_err("received null event data from target");
2881*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2882*5113495bSYour Name 	}
2883*5113495bSYour Name 
2884*5113495bSYour Name 	if (resp_event->vdev_id >= WLAN_MAX_VDEVS) {
2885*5113495bSYour Name 		wmi_err("received invalid vdev_id %d", resp_event->vdev_id);
2886*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2887*5113495bSYour Name 	}
2888*5113495bSYour Name 
2889*5113495bSYour Name 	num_entries = param_buf->num_blacklist_with_timeout;
2890*5113495bSYour Name 	if (num_entries == 0)
2891*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2892*5113495bSYour Name 
2893*5113495bSYour Name 	if (num_entries > MAX_RSSI_AVOID_BSSID_LIST) {
2894*5113495bSYour Name 		wmi_err("num blacklist entries:%d exceeds maximum value",
2895*5113495bSYour Name 			num_entries);
2896*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2897*5113495bSYour Name 	}
2898*5113495bSYour Name 
2899*5113495bSYour Name 	src_list = param_buf->blacklist_with_timeout;
2900*5113495bSYour Name 	if (len < (sizeof(*resp_event) + (num_entries * sizeof(*src_list)))) {
2901*5113495bSYour Name 		wmi_err("Invalid length:%d", len);
2902*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2903*5113495bSYour Name 	}
2904*5113495bSYour Name 
2905*5113495bSYour Name 	dst_list = qdf_mem_malloc(sizeof(struct roam_denylist_event) +
2906*5113495bSYour Name 				 (sizeof(struct roam_denylist_timeout) *
2907*5113495bSYour Name 				 num_entries));
2908*5113495bSYour Name 	if (!dst_list)
2909*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
2910*5113495bSYour Name 
2911*5113495bSYour Name 	dst_list->vdev_id = resp_event->vdev_id;
2912*5113495bSYour Name 	roam_denylist = &dst_list->roam_denylist[0];
2913*5113495bSYour Name 	for (i = 0; i < num_entries; i++) {
2914*5113495bSYour Name 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_list->bssid,
2915*5113495bSYour Name 					   roam_denylist->bssid.bytes);
2916*5113495bSYour Name 		roam_denylist->timeout = src_list->timeout;
2917*5113495bSYour Name 		roam_denylist->received_time = src_list->timestamp;
2918*5113495bSYour Name 		roam_denylist->original_timeout = src_list->original_timeout;
2919*5113495bSYour Name 		roam_denylist->reject_reason =
2920*5113495bSYour Name 				wmi_get_reject_reason(src_list->reason);
2921*5113495bSYour Name 		roam_denylist->source = src_list->source;
2922*5113495bSYour Name 		roam_denylist++;
2923*5113495bSYour Name 		src_list++;
2924*5113495bSYour Name 	}
2925*5113495bSYour Name 
2926*5113495bSYour Name 	dst_list->num_entries = num_entries;
2927*5113495bSYour Name 	*list = dst_list;
2928*5113495bSYour Name 
2929*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2930*5113495bSYour Name }
2931*5113495bSYour Name 
2932*5113495bSYour Name static QDF_STATUS
extract_vdev_disconnect_event_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint32_t data_len,struct vdev_disconnect_event_data * data)2933*5113495bSYour Name extract_vdev_disconnect_event_tlv(wmi_unified_t wmi_handle,
2934*5113495bSYour Name 				  uint8_t *event, uint32_t data_len,
2935*5113495bSYour Name 				  struct vdev_disconnect_event_data *data)
2936*5113495bSYour Name {
2937*5113495bSYour Name 	WMI_VDEV_DISCONNECT_EVENTID_param_tlvs *param_buf;
2938*5113495bSYour Name 	wmi_vdev_disconnect_event_fixed_param *roam_vdev_disc_ev;
2939*5113495bSYour Name 
2940*5113495bSYour Name 	param_buf = (WMI_VDEV_DISCONNECT_EVENTID_param_tlvs *)event;
2941*5113495bSYour Name 
2942*5113495bSYour Name 	roam_vdev_disc_ev = param_buf->fixed_param;
2943*5113495bSYour Name 	if (!roam_vdev_disc_ev) {
2944*5113495bSYour Name 		wmi_err("roam cap event is NULL");
2945*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2946*5113495bSYour Name 	}
2947*5113495bSYour Name 
2948*5113495bSYour Name 	if (roam_vdev_disc_ev->vdev_id >= WLAN_MAX_VDEVS) {
2949*5113495bSYour Name 		wmi_err("Invalid vdev id %d", roam_vdev_disc_ev->vdev_id);
2950*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2951*5113495bSYour Name 	}
2952*5113495bSYour Name 	data->vdev_id = roam_vdev_disc_ev->vdev_id;
2953*5113495bSYour Name 	data->reason = roam_vdev_disc_ev->reason;
2954*5113495bSYour Name 
2955*5113495bSYour Name 	wmi_debug("Received disconnect roam event on vdev_id : %d, reason:%d",
2956*5113495bSYour Name 		  data->vdev_id, data->reason);
2957*5113495bSYour Name 
2958*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2959*5113495bSYour Name }
2960*5113495bSYour Name 
2961*5113495bSYour Name static QDF_STATUS
extract_roam_scan_chan_list_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint32_t data_len,struct cm_roam_scan_ch_resp ** list)2962*5113495bSYour Name extract_roam_scan_chan_list_tlv(wmi_unified_t wmi_handle,
2963*5113495bSYour Name 				uint8_t *event, uint32_t data_len,
2964*5113495bSYour Name 				struct cm_roam_scan_ch_resp **list)
2965*5113495bSYour Name {
2966*5113495bSYour Name 	WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID_param_tlvs *param_buf;
2967*5113495bSYour Name 	wmi_roam_scan_channel_list_event_fixed_param *fixed_param;
2968*5113495bSYour Name 	struct cm_roam_scan_ch_resp *data;
2969*5113495bSYour Name 	uint8_t i = 0, num_ch = 0;
2970*5113495bSYour Name 
2971*5113495bSYour Name 	param_buf = (WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID_param_tlvs *)event;
2972*5113495bSYour Name 	if (!param_buf) {
2973*5113495bSYour Name 		wmi_err_rl("NULL event received from target");
2974*5113495bSYour Name 		return -EINVAL;
2975*5113495bSYour Name 	}
2976*5113495bSYour Name 
2977*5113495bSYour Name 	fixed_param = param_buf->fixed_param;
2978*5113495bSYour Name 	if (!fixed_param) {
2979*5113495bSYour Name 		wmi_err_rl(" NULL fixed param");
2980*5113495bSYour Name 		return -EINVAL;
2981*5113495bSYour Name 	}
2982*5113495bSYour Name 
2983*5113495bSYour Name 	if (fixed_param->vdev_id >= WLAN_MAX_VDEVS) {
2984*5113495bSYour Name 		wmi_err_rl("Invalid vdev_id %d", fixed_param->vdev_id);
2985*5113495bSYour Name 		return -EINVAL;
2986*5113495bSYour Name 	}
2987*5113495bSYour Name 
2988*5113495bSYour Name 	num_ch = (param_buf->num_channel_list < CM_CFG_VALID_CHANNEL_LIST_LEN) ?
2989*5113495bSYour Name 		param_buf->num_channel_list : CM_CFG_VALID_CHANNEL_LIST_LEN;
2990*5113495bSYour Name 
2991*5113495bSYour Name 	data = qdf_mem_malloc(sizeof(struct cm_roam_scan_ch_resp) +
2992*5113495bSYour Name 		num_ch * sizeof(param_buf->channel_list[0]));
2993*5113495bSYour Name 	if (!data)
2994*5113495bSYour Name 		return -EINVAL;
2995*5113495bSYour Name 
2996*5113495bSYour Name 	data->chan_list = (uint32_t *)(data + 1);
2997*5113495bSYour Name 	data->vdev_id = fixed_param->vdev_id;
2998*5113495bSYour Name 	data->command_resp = fixed_param->command_response;
2999*5113495bSYour Name 	data->num_channels = param_buf->num_channel_list;
3000*5113495bSYour Name 
3001*5113495bSYour Name 	for (i = 0; i < num_ch; i++)
3002*5113495bSYour Name 		data->chan_list[i] = param_buf->channel_list[i];
3003*5113495bSYour Name 
3004*5113495bSYour Name 	*list = data;
3005*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3006*5113495bSYour Name }
3007*5113495bSYour Name 
3008*5113495bSYour Name static QDF_STATUS
extract_roam_stats_with_single_tlv(wmi_unified_t wmi_handle,uint8_t * evt_buf,struct roam_stats_event * stats_info)3009*5113495bSYour Name extract_roam_stats_with_single_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
3010*5113495bSYour Name 				   struct roam_stats_event *stats_info)
3011*5113495bSYour Name {
3012*5113495bSYour Name 	QDF_STATUS status;
3013*5113495bSYour Name 	uint8_t vdev_id = stats_info->vdev_id;
3014*5113495bSYour Name 
3015*5113495bSYour Name 	status = wmi_unified_extract_roam_scan_stats(
3016*5113495bSYour Name 			wmi_handle, evt_buf, &stats_info->scan[0], 0, 0, 0);
3017*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
3018*5113495bSYour Name 		wmi_debug("Roam scan stats extract failed vdev %d", vdev_id);
3019*5113495bSYour Name 
3020*5113495bSYour Name 	status = wmi_unified_extract_roam_11kv_stats(
3021*5113495bSYour Name 			wmi_handle, evt_buf, &stats_info->data_11kv[0], 0, 0);
3022*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
3023*5113495bSYour Name 		wmi_debug("Roam 11kv stats extract failed vdev %d", vdev_id);
3024*5113495bSYour Name 
3025*5113495bSYour Name 	status = wmi_unified_extract_roam_trigger_stats(
3026*5113495bSYour Name 			wmi_handle, evt_buf, &stats_info->trigger[0], 0, 0);
3027*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
3028*5113495bSYour Name 		wmi_debug("Extract roamtrigger stats failed vdev %d",
3029*5113495bSYour Name 			  vdev_id);
3030*5113495bSYour Name 
3031*5113495bSYour Name 	status = wmi_unified_extract_roam_btm_response(
3032*5113495bSYour Name 			wmi_handle, evt_buf, &stats_info->btm_rsp[0], 0);
3033*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
3034*5113495bSYour Name 		wmi_debug("Roam btm rsp stats extract fail vdev %d",
3035*5113495bSYour Name 			  vdev_id);
3036*5113495bSYour Name 
3037*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3038*5113495bSYour Name }
3039*5113495bSYour Name 
3040*5113495bSYour Name /**
3041*5113495bSYour Name  * extract_roam_stats_event_tlv() - Extract the roam stats event
3042*5113495bSYour Name  * from the wmi_roam_stats_event_id
3043*5113495bSYour Name  * @wmi_handle: wmi handle
3044*5113495bSYour Name  * @evt_buf:    Pointer to the event buffer
3045*5113495bSYour Name  * @len:        Data length
3046*5113495bSYour Name  * @data:       Double pointer to roam stats data
3047*5113495bSYour Name  */
3048*5113495bSYour Name static QDF_STATUS
extract_roam_stats_event_tlv(wmi_unified_t wmi_handle,uint8_t * evt_buf,uint32_t len,struct roam_stats_event ** data)3049*5113495bSYour Name extract_roam_stats_event_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
3050*5113495bSYour Name 			     uint32_t len,
3051*5113495bSYour Name 			     struct roam_stats_event **data)
3052*5113495bSYour Name {
3053*5113495bSYour Name 	WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
3054*5113495bSYour Name 	wmi_roam_stats_event_fixed_param *fixed_param;
3055*5113495bSYour Name 	struct roam_stats_event *stats_info;
3056*5113495bSYour Name 	struct roam_msg_info *roam_msg_info = NULL;
3057*5113495bSYour Name 	uint8_t vdev_id, i, num_btm = 0, num_frames = 0;
3058*5113495bSYour Name 	uint8_t num_tlv = 0, num_chan = 0, num_ap = 0, num_rpt = 0;
3059*5113495bSYour Name 	uint8_t num_trigger_reason = 0;
3060*5113495bSYour Name 	uint32_t rem_len;
3061*5113495bSYour Name 	QDF_STATUS status;
3062*5113495bSYour Name 
3063*5113495bSYour Name 	param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
3064*5113495bSYour Name 	if (!param_buf) {
3065*5113495bSYour Name 		wmi_err_rl("NULL event received from target");
3066*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3067*5113495bSYour Name 	}
3068*5113495bSYour Name 
3069*5113495bSYour Name 	fixed_param = param_buf->fixed_param;
3070*5113495bSYour Name 	if (!fixed_param) {
3071*5113495bSYour Name 		wmi_err_rl(" NULL fixed param");
3072*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3073*5113495bSYour Name 	}
3074*5113495bSYour Name 
3075*5113495bSYour Name 	vdev_id = fixed_param->vdev_id;
3076*5113495bSYour Name 
3077*5113495bSYour Name 	if (vdev_id >= WLAN_MAX_VDEVS) {
3078*5113495bSYour Name 		wmi_err_rl("Invalid vdev_id %d", vdev_id);
3079*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3080*5113495bSYour Name 	}
3081*5113495bSYour Name 
3082*5113495bSYour Name 	num_tlv = fixed_param->roam_scan_trigger_count;
3083*5113495bSYour Name 	if (num_tlv > MAX_ROAM_SCAN_STATS_TLV) {
3084*5113495bSYour Name 		wmi_err_rl("Limiting roam triggers to 5");
3085*5113495bSYour Name 		num_tlv = MAX_ROAM_SCAN_STATS_TLV;
3086*5113495bSYour Name 	}
3087*5113495bSYour Name 
3088*5113495bSYour Name 	if (param_buf->roam_trigger_reason)
3089*5113495bSYour Name 		num_trigger_reason = num_tlv;
3090*5113495bSYour Name 	else
3091*5113495bSYour Name 		num_trigger_reason = 0;
3092*5113495bSYour Name 
3093*5113495bSYour Name 	rem_len = len - sizeof(*fixed_param);
3094*5113495bSYour Name 	if (rem_len < num_trigger_reason * sizeof(wmi_roam_trigger_reason)) {
3095*5113495bSYour Name 		wmi_err_rl("Invalid roam trigger data");
3096*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3097*5113495bSYour Name 	}
3098*5113495bSYour Name 
3099*5113495bSYour Name 	rem_len -= num_trigger_reason * sizeof(wmi_roam_trigger_reason);
3100*5113495bSYour Name 	if (rem_len < num_tlv * sizeof(wmi_roam_scan_info)) {
3101*5113495bSYour Name 		wmi_err_rl("Invalid roam scan data");
3102*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3103*5113495bSYour Name 	}
3104*5113495bSYour Name 
3105*5113495bSYour Name 	rem_len -= num_tlv * sizeof(wmi_roam_scan_info);
3106*5113495bSYour Name 	if (rem_len < num_tlv * sizeof(wmi_roam_result)) {
3107*5113495bSYour Name 		wmi_err_rl("Invalid roam result data");
3108*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3109*5113495bSYour Name 	}
3110*5113495bSYour Name 
3111*5113495bSYour Name 	rem_len -= num_tlv * sizeof(wmi_roam_result);
3112*5113495bSYour Name 	if (rem_len < (num_tlv * sizeof(wmi_roam_neighbor_report_info))) {
3113*5113495bSYour Name 		wmi_err_rl("Invalid roam neighbor report data");
3114*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3115*5113495bSYour Name 	}
3116*5113495bSYour Name 
3117*5113495bSYour Name 	rem_len -= num_tlv * sizeof(wmi_roam_neighbor_report_info);
3118*5113495bSYour Name 	if (rem_len < (param_buf->num_roam_scan_chan_info *
3119*5113495bSYour Name 		       sizeof(wmi_roam_scan_channel_info))) {
3120*5113495bSYour Name 		wmi_err_rl("Invalid roam chan data num_tlv:%d",
3121*5113495bSYour Name 			   param_buf->num_roam_scan_chan_info);
3122*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3123*5113495bSYour Name 	}
3124*5113495bSYour Name 
3125*5113495bSYour Name 	rem_len -= param_buf->num_roam_scan_chan_info *
3126*5113495bSYour Name 		   sizeof(wmi_roam_scan_channel_info);
3127*5113495bSYour Name 
3128*5113495bSYour Name 	if (rem_len < (param_buf->num_roam_ap_info *
3129*5113495bSYour Name 		       sizeof(wmi_roam_ap_info))) {
3130*5113495bSYour Name 		wmi_err_rl("Invalid roam ap data num_tlv:%d",
3131*5113495bSYour Name 			   param_buf->num_roam_ap_info);
3132*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3133*5113495bSYour Name 	}
3134*5113495bSYour Name 
3135*5113495bSYour Name 	rem_len -= param_buf->num_roam_ap_info * sizeof(wmi_roam_ap_info);
3136*5113495bSYour Name 	if (rem_len < (param_buf->num_roam_neighbor_report_chan_info *
3137*5113495bSYour Name 		       sizeof(wmi_roam_neighbor_report_channel_info))) {
3138*5113495bSYour Name 		wmi_err_rl("Invalid roam neigb rpt chan data num_tlv:%d",
3139*5113495bSYour Name 			   param_buf->num_roam_neighbor_report_chan_info);
3140*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3141*5113495bSYour Name 	}
3142*5113495bSYour Name 
3143*5113495bSYour Name 	rem_len -= param_buf->num_roam_neighbor_report_chan_info *
3144*5113495bSYour Name 			sizeof(wmi_roam_neighbor_report_channel_info);
3145*5113495bSYour Name 	if (rem_len < param_buf->num_roam_btm_response_info *
3146*5113495bSYour Name 	    sizeof(wmi_roam_btm_response_info)) {
3147*5113495bSYour Name 		wmi_err_rl("Invalid btm rsp data");
3148*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3149*5113495bSYour Name 	}
3150*5113495bSYour Name 
3151*5113495bSYour Name 	rem_len -= param_buf->num_roam_btm_response_info *
3152*5113495bSYour Name 			sizeof(wmi_roam_btm_response_info);
3153*5113495bSYour Name 	if (rem_len < param_buf->num_roam_initial_info *
3154*5113495bSYour Name 	    sizeof(wmi_roam_initial_info)) {
3155*5113495bSYour Name 		wmi_err_rl("Invalid Initial roam info");
3156*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3157*5113495bSYour Name 	}
3158*5113495bSYour Name 
3159*5113495bSYour Name 	rem_len -= param_buf->num_roam_initial_info *
3160*5113495bSYour Name 			sizeof(wmi_roam_initial_info);
3161*5113495bSYour Name 	if (rem_len < param_buf->num_roam_msg_info *
3162*5113495bSYour Name 	    sizeof(wmi_roam_msg_info)) {
3163*5113495bSYour Name 		wmi_err_rl("Invalid roam msg info");
3164*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3165*5113495bSYour Name 	}
3166*5113495bSYour Name 
3167*5113495bSYour Name 	rem_len -= param_buf->num_roam_msg_info * sizeof(wmi_roam_msg_info);
3168*5113495bSYour Name 	if (rem_len <
3169*5113495bSYour Name 	    param_buf->num_roam_frame_info * sizeof(wmi_roam_frame_info)) {
3170*5113495bSYour Name 		wmi_err_rl("Invalid roam frame info");
3171*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3172*5113495bSYour Name 	}
3173*5113495bSYour Name 
3174*5113495bSYour Name 	stats_info = qdf_mem_malloc(sizeof(struct roam_stats_event));
3175*5113495bSYour Name 	if (!stats_info) {
3176*5113495bSYour Name 		status = QDF_STATUS_E_NOMEM;
3177*5113495bSYour Name 		goto err;
3178*5113495bSYour Name 	}
3179*5113495bSYour Name 	*data = stats_info;
3180*5113495bSYour Name 	qdf_mem_set(stats_info, sizeof(struct roam_stats_event), 0);
3181*5113495bSYour Name 	stats_info->vdev_id = vdev_id;
3182*5113495bSYour Name 	stats_info->num_roam_msg_info = param_buf->num_roam_msg_info;
3183*5113495bSYour Name 	stats_info->num_tlv = num_tlv;
3184*5113495bSYour Name 
3185*5113495bSYour Name 	if (!num_tlv)
3186*5113495bSYour Name 		extract_roam_stats_with_single_tlv(wmi_handle, evt_buf,
3187*5113495bSYour Name 						   stats_info);
3188*5113495bSYour Name 
3189*5113495bSYour Name 	for (i = 0; i < num_tlv; i++) {
3190*5113495bSYour Name 		/*
3191*5113495bSYour Name 		 * Roam Trigger id and that specific roam trigger related
3192*5113495bSYour Name 		 * details.
3193*5113495bSYour Name 		 */
3194*5113495bSYour Name 		status = wmi_unified_extract_roam_trigger_stats(wmi_handle,
3195*5113495bSYour Name 						    evt_buf,
3196*5113495bSYour Name 						    &stats_info->trigger[i], i,
3197*5113495bSYour Name 						    num_btm);
3198*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
3199*5113495bSYour Name 			wmi_debug_rl("Extract roam trigger stats failed vdev %d at %d iteration",
3200*5113495bSYour Name 				     vdev_id, i);
3201*5113495bSYour Name 			status =  QDF_STATUS_E_INVAL;
3202*5113495bSYour Name 			goto err;
3203*5113495bSYour Name 		}
3204*5113495bSYour Name 
3205*5113495bSYour Name 		if (stats_info->trigger[i].trigger_reason ==
3206*5113495bSYour Name 		    WMI_ROAM_TRIGGER_REASON_BTM)
3207*5113495bSYour Name 			num_btm += stats_info->trigger[i].btm_trig_data.candidate_list_count;
3208*5113495bSYour Name 
3209*5113495bSYour Name 		/* Roam scan related details - Scan channel, scan type .. */
3210*5113495bSYour Name 		status = wmi_unified_extract_roam_scan_stats(wmi_handle,
3211*5113495bSYour Name 							evt_buf,
3212*5113495bSYour Name 							&stats_info->scan[i], i,
3213*5113495bSYour Name 							num_chan, num_ap);
3214*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
3215*5113495bSYour Name 			wmi_debug_rl("Roam scan stats extract failed vdev %d at %d iteration",
3216*5113495bSYour Name 				     vdev_id, i);
3217*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
3218*5113495bSYour Name 			goto err;
3219*5113495bSYour Name 		}
3220*5113495bSYour Name 		num_chan += stats_info->scan[i].num_chan;
3221*5113495bSYour Name 		num_ap += stats_info->scan[i].num_ap;
3222*5113495bSYour Name 		num_frames = stats_info->scan[i].frame_info_count;
3223*5113495bSYour Name 
3224*5113495bSYour Name 		/* Roam result - Success/Failure status, failure reason */
3225*5113495bSYour Name 		status = wmi_unified_extract_roam_result_stats(wmi_handle,
3226*5113495bSYour Name 						     evt_buf,
3227*5113495bSYour Name 						     &stats_info->result[i], i);
3228*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
3229*5113495bSYour Name 			wmi_debug_rl("Roam result stats extract failed vdev %d at %d iteration",
3230*5113495bSYour Name 				     vdev_id, i);
3231*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
3232*5113495bSYour Name 			goto err;
3233*5113495bSYour Name 		}
3234*5113495bSYour Name 
3235*5113495bSYour Name 		if (num_frames) {
3236*5113495bSYour Name 			status = wmi_unified_extract_roam_extract_frame_info(
3237*5113495bSYour Name 					wmi_handle, evt_buf,
3238*5113495bSYour Name 					&stats_info->frame_stats[i], i,
3239*5113495bSYour Name 					num_frames);
3240*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(status)) {
3241*5113495bSYour Name 				wmi_debug_rl("Roam frame stats extract failed vdev %d at %d iteration",
3242*5113495bSYour Name 					     vdev_id, i);
3243*5113495bSYour Name 				status = QDF_STATUS_E_INVAL;
3244*5113495bSYour Name 				goto err;
3245*5113495bSYour Name 			}
3246*5113495bSYour Name 		}
3247*5113495bSYour Name 
3248*5113495bSYour Name 		/* BTM req/resp or Neighbor report/response info */
3249*5113495bSYour Name 		status = wmi_unified_extract_roam_11kv_stats(
3250*5113495bSYour Name 				      wmi_handle,
3251*5113495bSYour Name 				      evt_buf,
3252*5113495bSYour Name 				      &stats_info->data_11kv[i],
3253*5113495bSYour Name 				      i, num_rpt);
3254*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status))
3255*5113495bSYour Name 			wmi_debug_rl("Roam 11kv stats extract fail vdev %d iter %d",
3256*5113495bSYour Name 				     vdev_id, i);
3257*5113495bSYour Name 
3258*5113495bSYour Name 		if (stats_info->data_11kv[i].present)
3259*5113495bSYour Name 			num_rpt += stats_info->data_11kv[i].num_freq;
3260*5113495bSYour Name 
3261*5113495bSYour Name 		/* BTM resp info */
3262*5113495bSYour Name 		status = wmi_unified_extract_roam_btm_response(wmi_handle,
3263*5113495bSYour Name 							evt_buf,
3264*5113495bSYour Name 							&stats_info->btm_rsp[i],
3265*5113495bSYour Name 							i);
3266*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
3267*5113495bSYour Name 			wmi_debug_rl("Roam btm rsp stats extract fail vdev %d at %d iteration",
3268*5113495bSYour Name 				     vdev_id, i);
3269*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
3270*5113495bSYour Name 			goto err;
3271*5113495bSYour Name 		}
3272*5113495bSYour Name 
3273*5113495bSYour Name 		/* Initial Roam info */
3274*5113495bSYour Name 		status = wmi_unified_extract_roam_initial_info(wmi_handle,
3275*5113495bSYour Name 					     evt_buf,
3276*5113495bSYour Name 					     &stats_info->roam_init_info[i], i);
3277*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
3278*5113495bSYour Name 			wmi_debug_rl("Initial roam stats extract fail vdev %d at %d iteration",
3279*5113495bSYour Name 				     vdev_id, i);
3280*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
3281*5113495bSYour Name 			goto err;
3282*5113495bSYour Name 		}
3283*5113495bSYour Name 	}
3284*5113495bSYour Name 
3285*5113495bSYour Name 	if (param_buf->roam_msg_info && param_buf->num_roam_msg_info) {
3286*5113495bSYour Name 		roam_msg_info = qdf_mem_malloc(param_buf->num_roam_msg_info *
3287*5113495bSYour Name 					       sizeof(*roam_msg_info));
3288*5113495bSYour Name 		if (!roam_msg_info) {
3289*5113495bSYour Name 			status = QDF_STATUS_E_NOMEM;
3290*5113495bSYour Name 			goto err;
3291*5113495bSYour Name 		}
3292*5113495bSYour Name 		stats_info->roam_msg_info = roam_msg_info;
3293*5113495bSYour Name 		for (i = 0; i < param_buf->num_roam_msg_info; i++) {
3294*5113495bSYour Name 			status = wmi_unified_extract_roam_msg_info(wmi_handle,
3295*5113495bSYour Name 							  evt_buf,
3296*5113495bSYour Name 							  &roam_msg_info[i], i);
3297*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(status)) {
3298*5113495bSYour Name 				wmi_err("roam msg stats extract fail vdev %d",
3299*5113495bSYour Name 					vdev_id);
3300*5113495bSYour Name 				status = QDF_STATUS_E_INVAL;
3301*5113495bSYour Name 				goto err;
3302*5113495bSYour Name 			}
3303*5113495bSYour Name 		}
3304*5113495bSYour Name 	}
3305*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3306*5113495bSYour Name err:
3307*5113495bSYour Name 	if (stats_info) {
3308*5113495bSYour Name 		if (roam_msg_info)
3309*5113495bSYour Name 			qdf_mem_free(roam_msg_info);
3310*5113495bSYour Name 		qdf_mem_free(stats_info);
3311*5113495bSYour Name 	}
3312*5113495bSYour Name 	return status;
3313*5113495bSYour Name }
3314*5113495bSYour Name 
3315*5113495bSYour Name static QDF_STATUS
extract_auth_offload_event_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint32_t len,struct auth_offload_event * auth_event)3316*5113495bSYour Name extract_auth_offload_event_tlv(wmi_unified_t wmi_handle,
3317*5113495bSYour Name 			       uint8_t *event, uint32_t len,
3318*5113495bSYour Name 			       struct auth_offload_event *auth_event)
3319*5113495bSYour Name {
3320*5113495bSYour Name 	wmi_roam_preauth_start_event_fixed_param *rso_auth_start_ev;
3321*5113495bSYour Name 	WMI_ROAM_PREAUTH_START_EVENTID_param_tlvs *param_buf;
3322*5113495bSYour Name 
3323*5113495bSYour Name 	param_buf = (WMI_ROAM_PREAUTH_START_EVENTID_param_tlvs *) event;
3324*5113495bSYour Name 
3325*5113495bSYour Name 	rso_auth_start_ev = param_buf->fixed_param;
3326*5113495bSYour Name 	if (!rso_auth_start_ev) {
3327*5113495bSYour Name 		wmi_debug("received null event data from target");
3328*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3329*5113495bSYour Name 	}
3330*5113495bSYour Name 
3331*5113495bSYour Name 	if (rso_auth_start_ev->vdev_id > WLAN_MAX_VDEVS) {
3332*5113495bSYour Name 		wmi_debug("received invalid vdev_id %d",
3333*5113495bSYour Name 			  rso_auth_start_ev->vdev_id);
3334*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3335*5113495bSYour Name 	}
3336*5113495bSYour Name 
3337*5113495bSYour Name 	auth_event->vdev_id = rso_auth_start_ev->vdev_id;
3338*5113495bSYour Name 	auth_event->akm = rso_auth_start_ev->akm_suite_type;
3339*5113495bSYour Name 
3340*5113495bSYour Name 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&rso_auth_start_ev->candidate_ap_bssid,
3341*5113495bSYour Name 				   auth_event->ap_bssid.bytes);
3342*5113495bSYour Name 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&rso_auth_start_ev->transmit_addr,
3343*5113495bSYour Name 				   auth_event->ta.bytes);
3344*5113495bSYour Name 	if (qdf_is_macaddr_zero(&auth_event->ap_bssid) ||
3345*5113495bSYour Name 	    qdf_is_macaddr_broadcast(&auth_event->ap_bssid) ||
3346*5113495bSYour Name 	    qdf_is_macaddr_group(&auth_event->ap_bssid)) {
3347*5113495bSYour Name 		wmi_debug("Invalid bssid");
3348*5113495bSYour Name 		return -EINVAL;
3349*5113495bSYour Name 	}
3350*5113495bSYour Name 
3351*5113495bSYour Name 	wmi_debug("Received Roam auth offload event for bss:"
3352*5113495bSYour Name 		  QDF_MAC_ADDR_FMT " ta:" QDF_MAC_ADDR_FMT " vdev_id: %d akm: %d",
3353*5113495bSYour Name 		  QDF_MAC_ADDR_REF(auth_event->ap_bssid.bytes),
3354*5113495bSYour Name 		  QDF_MAC_ADDR_REF(auth_event->ta.bytes),
3355*5113495bSYour Name 		  auth_event->vdev_id, auth_event->akm);
3356*5113495bSYour Name 
3357*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3358*5113495bSYour Name }
3359*5113495bSYour Name 
3360*5113495bSYour Name /**
3361*5113495bSYour Name  * extract_roam_pmkid_request_tlv() - Extract the roam pmkid request event
3362*5113495bSYour Name  * @wmi_handle: wmi handle
3363*5113495bSYour Name  * @evt_buf: Pointer to the event buffer
3364*5113495bSYour Name  * @len: Data length
3365*5113495bSYour Name  * @list: Extract the data and fill in list
3366*5113495bSYour Name  */
3367*5113495bSYour Name static QDF_STATUS
extract_roam_pmkid_request_tlv(wmi_unified_t wmi_handle,uint8_t * evt_buf,uint32_t len,struct roam_pmkid_req_event ** list)3368*5113495bSYour Name extract_roam_pmkid_request_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
3369*5113495bSYour Name 			       uint32_t len,
3370*5113495bSYour Name 			       struct roam_pmkid_req_event **list)
3371*5113495bSYour Name {
3372*5113495bSYour Name 	WMI_ROAM_PMKID_REQUEST_EVENTID_param_tlvs *param_buf;
3373*5113495bSYour Name 	wmi_roam_pmkid_request_event_fixed_param *roam_pmkid_req_ev;
3374*5113495bSYour Name 	wmi_roam_pmkid_request_tlv_param *src_list;
3375*5113495bSYour Name 	struct qdf_mac_addr *roam_bsslist;
3376*5113495bSYour Name 	uint32_t num_entries, i;
3377*5113495bSYour Name 	struct roam_pmkid_req_event *dst_list;
3378*5113495bSYour Name 
3379*5113495bSYour Name 	if (!evt_buf || !len) {
3380*5113495bSYour Name 		wmi_err("received null event from target");
3381*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3382*5113495bSYour Name 	}
3383*5113495bSYour Name 
3384*5113495bSYour Name 	param_buf = (WMI_ROAM_PMKID_REQUEST_EVENTID_param_tlvs *)evt_buf;
3385*5113495bSYour Name 	if (!param_buf) {
3386*5113495bSYour Name 		wmi_err("received null buf from target");
3387*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3388*5113495bSYour Name 	}
3389*5113495bSYour Name 
3390*5113495bSYour Name 	roam_pmkid_req_ev = param_buf->fixed_param;
3391*5113495bSYour Name 	if (!roam_pmkid_req_ev) {
3392*5113495bSYour Name 		wmi_err("received null event data from target");
3393*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3394*5113495bSYour Name 	}
3395*5113495bSYour Name 
3396*5113495bSYour Name 	if (roam_pmkid_req_ev->vdev_id >= WLAN_MAX_VDEVS) {
3397*5113495bSYour Name 		wmi_err_rl("Invalid vdev_id %d", roam_pmkid_req_ev->vdev_id);
3398*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3399*5113495bSYour Name 	}
3400*5113495bSYour Name 
3401*5113495bSYour Name 	num_entries = param_buf->num_pmkid_request;
3402*5113495bSYour Name 	if (num_entries > MAX_RSSI_AVOID_BSSID_LIST) {
3403*5113495bSYour Name 		wmi_err("num bssid entries:%d exceeds maximum value",
3404*5113495bSYour Name 			num_entries);
3405*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3406*5113495bSYour Name 	}
3407*5113495bSYour Name 
3408*5113495bSYour Name 	src_list = param_buf->pmkid_request;
3409*5113495bSYour Name 	if (len < (sizeof(*roam_pmkid_req_ev) +
3410*5113495bSYour Name 		(num_entries * sizeof(*src_list)))) {
3411*5113495bSYour Name 		wmi_err("Invalid length: %d", len);
3412*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3413*5113495bSYour Name 	}
3414*5113495bSYour Name 
3415*5113495bSYour Name 	dst_list = qdf_mem_malloc(sizeof(struct roam_pmkid_req_event) +
3416*5113495bSYour Name 				  (sizeof(struct qdf_mac_addr) * num_entries));
3417*5113495bSYour Name 	if (!dst_list)
3418*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
3419*5113495bSYour Name 
3420*5113495bSYour Name 	dst_list->vdev_id = roam_pmkid_req_ev->vdev_id;
3421*5113495bSYour Name 
3422*5113495bSYour Name 	for (i = 0; i < num_entries; i++) {
3423*5113495bSYour Name 		roam_bsslist = &dst_list->ap_bssid[i];
3424*5113495bSYour Name 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_list->bssid,
3425*5113495bSYour Name 					   roam_bsslist->bytes);
3426*5113495bSYour Name 		if (qdf_is_macaddr_zero(roam_bsslist) ||
3427*5113495bSYour Name 		    qdf_is_macaddr_broadcast(roam_bsslist) ||
3428*5113495bSYour Name 		    qdf_is_macaddr_group(roam_bsslist)) {
3429*5113495bSYour Name 			wmi_err("Invalid bssid");
3430*5113495bSYour Name 			qdf_mem_free(dst_list);
3431*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
3432*5113495bSYour Name 		}
3433*5113495bSYour Name 		wmi_debug("Received pmkid fallback for bssid: " QDF_MAC_ADDR_FMT" vdev_id:%d",
3434*5113495bSYour Name 			  QDF_MAC_ADDR_REF(roam_bsslist->bytes),
3435*5113495bSYour Name 			  roam_pmkid_req_ev->vdev_id);
3436*5113495bSYour Name 		src_list++;
3437*5113495bSYour Name 	}
3438*5113495bSYour Name 	dst_list->num_entries = num_entries;
3439*5113495bSYour Name 	*list = dst_list;
3440*5113495bSYour Name 
3441*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3442*5113495bSYour Name }
3443*5113495bSYour Name 
3444*5113495bSYour Name static QDF_STATUS
extract_roam_candidate_frame_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint32_t len,struct roam_scan_candidate_frame * data)3445*5113495bSYour Name extract_roam_candidate_frame_tlv(wmi_unified_t wmi_handle, uint8_t *event,
3446*5113495bSYour Name 				 uint32_t len,
3447*5113495bSYour Name 				 struct roam_scan_candidate_frame *data)
3448*5113495bSYour Name {
3449*5113495bSYour Name 	WMI_ROAM_FRAME_EVENTID_param_tlvs *param_buf = NULL;
3450*5113495bSYour Name 	wmi_roam_frame_event_fixed_param *frame_params = NULL;
3451*5113495bSYour Name 
3452*5113495bSYour Name 	if (!event || !len) {
3453*5113495bSYour Name 		wmi_debug("Empty roam candidate frame event");
3454*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3455*5113495bSYour Name 	}
3456*5113495bSYour Name 
3457*5113495bSYour Name 	param_buf = (WMI_ROAM_FRAME_EVENTID_param_tlvs *)event;
3458*5113495bSYour Name 	if (!param_buf) {
3459*5113495bSYour Name 		wmi_err("received null buf from target");
3460*5113495bSYour Name 		return -EINVAL;
3461*5113495bSYour Name 	}
3462*5113495bSYour Name 
3463*5113495bSYour Name 	frame_params =
3464*5113495bSYour Name 		(wmi_roam_frame_event_fixed_param *)param_buf->fixed_param;
3465*5113495bSYour Name 
3466*5113495bSYour Name 	if (frame_params->vdev_id >= WLAN_MAX_VDEVS) {
3467*5113495bSYour Name 		wmi_debug("Invalid VDEV id %d", frame_params->vdev_id);
3468*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3469*5113495bSYour Name 	}
3470*5113495bSYour Name 
3471*5113495bSYour Name 	if (frame_params->frame_length > param_buf->num_frame) {
3472*5113495bSYour Name 		wmi_debug("Invalid frame length %d expected : %d",
3473*5113495bSYour Name 			  frame_params->frame_length,
3474*5113495bSYour Name 			  param_buf->num_frame);
3475*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3476*5113495bSYour Name 	}
3477*5113495bSYour Name 
3478*5113495bSYour Name 	if (!param_buf->frame) {
3479*5113495bSYour Name 		wmi_debug("Frame pointer is Null");
3480*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3481*5113495bSYour Name 	}
3482*5113495bSYour Name 
3483*5113495bSYour Name 	data->vdev_id = frame_params->vdev_id;
3484*5113495bSYour Name 	data->frame_length = frame_params->frame_length;
3485*5113495bSYour Name 	data->frame = (uint8_t *)param_buf->frame;
3486*5113495bSYour Name 	data->roam_offload_candidate_frm = true;
3487*5113495bSYour Name 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
3488*5113495bSYour Name 			   data->frame, data->frame_length);
3489*5113495bSYour Name 
3490*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3491*5113495bSYour Name }
3492*5113495bSYour Name 
3493*5113495bSYour Name #ifdef WLAN_FEATURE_ROAM_OFFLOAD
3494*5113495bSYour Name static QDF_STATUS
extract_peer_oper_mode_event_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint32_t len,struct peer_oper_mode_event * data)3495*5113495bSYour Name extract_peer_oper_mode_event_tlv(wmi_unified_t wmi_handle, uint8_t *event,
3496*5113495bSYour Name 				 uint32_t len,
3497*5113495bSYour Name 				 struct peer_oper_mode_event *data)
3498*5113495bSYour Name {
3499*5113495bSYour Name 	WMI_PEER_OPER_MODE_CHANGE_EVENTID_param_tlvs *param_buf = NULL;
3500*5113495bSYour Name 	wmi_peer_oper_mode_change_event_fixed_param *params = NULL;
3501*5113495bSYour Name 
3502*5113495bSYour Name 	if (!event || !len) {
3503*5113495bSYour Name 		wmi_debug("Empty operating mode change event");
3504*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3505*5113495bSYour Name 	}
3506*5113495bSYour Name 
3507*5113495bSYour Name 	param_buf = (WMI_PEER_OPER_MODE_CHANGE_EVENTID_param_tlvs *)event;
3508*5113495bSYour Name 	if (!param_buf) {
3509*5113495bSYour Name 		wmi_err("Received null buf from target");
3510*5113495bSYour Name 		return -EINVAL;
3511*5113495bSYour Name 	}
3512*5113495bSYour Name 
3513*5113495bSYour Name 	params =
3514*5113495bSYour Name 		(wmi_peer_oper_mode_change_event_fixed_param *)param_buf->fixed_param;
3515*5113495bSYour Name 
3516*5113495bSYour Name 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&params->peer_mac_address,
3517*5113495bSYour Name 				   data->peer_mac_address.bytes);
3518*5113495bSYour Name 	data->ind_type = params->ind_type;
3519*5113495bSYour Name 	data->new_rxnss = params->new_rxnss;
3520*5113495bSYour Name 	data->new_bw = params->new_bw;
3521*5113495bSYour Name 	data->new_txnss = params->new_txnss;
3522*5113495bSYour Name 	data->new_disablemu = params->new_disablemu;
3523*5113495bSYour Name 
3524*5113495bSYour Name 	wmi_debug("peer_mac_addr: " QDF_MAC_ADDR_FMT " ind_type: %d new_rxnss: %d new_bw: %d new_txnss: %d new_disablemu: %d",
3525*5113495bSYour Name 		  QDF_MAC_ADDR_REF(data->peer_mac_address.bytes),
3526*5113495bSYour Name 		  data->ind_type,
3527*5113495bSYour Name 		  data->new_rxnss,
3528*5113495bSYour Name 		  data->new_bw,
3529*5113495bSYour Name 		  data->new_txnss,
3530*5113495bSYour Name 		  data->new_disablemu);
3531*5113495bSYour Name 
3532*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3533*5113495bSYour Name }
3534*5113495bSYour Name #endif
3535*5113495bSYour Name #ifdef WLAN_VENDOR_HANDOFF_CONTROL
3536*5113495bSYour Name /**
3537*5113495bSYour Name  * convert_roam_vendor_control_param() - Function to convert
3538*5113495bSYour Name  * vendor_control_roam_param enum to TLV specific
3539*5113495bSYour Name  * WMI_ROAM_GET_VENDOR_CONTROL_PARAM_ID
3540*5113495bSYour Name  * @param_id: Roam vendor control param id
3541*5113495bSYour Name  *
3542*5113495bSYour Name  * Return: wmi roam vendor control param id
3543*5113495bSYour Name  */
3544*5113495bSYour Name static WMI_ROAM_GET_VENDOR_CONTROL_PARAM_ID
convert_roam_vendor_control_param(enum vendor_control_roam_param param_id)3545*5113495bSYour Name convert_roam_vendor_control_param(enum vendor_control_roam_param param_id)
3546*5113495bSYour Name {
3547*5113495bSYour Name 	switch (param_id) {
3548*5113495bSYour Name 	case VENDOR_CONTROL_PARAM_ROAM_TRIGGER:
3549*5113495bSYour Name 		return ROAM_VENDOR_CONTROL_PARAM_TRIGGER;
3550*5113495bSYour Name 	case VENDOR_CONTROL_PARAM_ROAM_DELTA:
3551*5113495bSYour Name 		return ROAM_VENDOR_CONTROL_PARAM_DELTA;
3552*5113495bSYour Name 	case VENDOR_CONTROL_PARAM_ROAM_FULL_SCANPERIOD:
3553*5113495bSYour Name 		return ROAM_VENDOR_CONTROL_PARAM_FULL_SCANPERIOD;
3554*5113495bSYour Name 	case VENDOR_CONTROL_PARAM_ROAM_PARTIAL_SCANPERIOD:
3555*5113495bSYour Name 		return ROAM_VENDOR_CONTROL_PARAM_PARTIAL_SCANPERIOD;
3556*5113495bSYour Name 	case VENDOR_CONTROL_PARAM_ROAM_ACTIVE_CH_DWELLTIME:
3557*5113495bSYour Name 		return ROAM_VENDOR_CONTROL_PARAM_ACTIVE_CH_DWELLTIME;
3558*5113495bSYour Name 	case VENDOR_CONTROL_PARAM_ROAM_PASSIVE_CH_DWELLTIME:
3559*5113495bSYour Name 		return ROAM_VENDOR_CONTROL_PARAM_PASSIVE_CH_DWELLTIME;
3560*5113495bSYour Name 	case VENDOR_CONTROL_PARAM_ROAM_HOME_CH_TIME:
3561*5113495bSYour Name 		return ROAM_VENDOR_CONTROL_PARAM_HOME_CH_TIME;
3562*5113495bSYour Name 	case VENDOR_CONTROL_PARAM_ROAM_AWAY_TIME:
3563*5113495bSYour Name 		return ROAM_VENDOR_CONTROL_PARAM_AWAY_TIME;
3564*5113495bSYour Name 	case VENDOR_CONTROL_PARAM_ROAM_ALL:
3565*5113495bSYour Name 		return ROAM_VENDOR_CONTROL_PARAM_ALL;
3566*5113495bSYour Name 	default:
3567*5113495bSYour Name 		wmi_debug("Invalid param id");
3568*5113495bSYour Name 		return 0;
3569*5113495bSYour Name 	}
3570*5113495bSYour Name }
3571*5113495bSYour Name 
3572*5113495bSYour Name /**
3573*5113495bSYour Name  * convert_wmi_roam_vendor_control_param() - Function to convert TLV specific
3574*5113495bSYour Name  * WMI_ROAM_GET_VENDOR_CONTROL_PARAM_ID to vendor_control_roam_param
3575*5113495bSYour Name  * @param_id: wmi vendor control param id
3576*5113495bSYour Name  *
3577*5113495bSYour Name  * Return: roam vendor control param id
3578*5113495bSYour Name  */
convert_wmi_roam_vendor_control_param(WMI_ROAM_GET_VENDOR_CONTROL_PARAM_ID param_id)3579*5113495bSYour Name static enum vendor_control_roam_param convert_wmi_roam_vendor_control_param(
3580*5113495bSYour Name 			WMI_ROAM_GET_VENDOR_CONTROL_PARAM_ID param_id)
3581*5113495bSYour Name {
3582*5113495bSYour Name 	switch (param_id) {
3583*5113495bSYour Name 	case ROAM_VENDOR_CONTROL_PARAM_TRIGGER:
3584*5113495bSYour Name 		return VENDOR_CONTROL_PARAM_ROAM_TRIGGER;
3585*5113495bSYour Name 	case ROAM_VENDOR_CONTROL_PARAM_DELTA:
3586*5113495bSYour Name 		return VENDOR_CONTROL_PARAM_ROAM_DELTA;
3587*5113495bSYour Name 	case ROAM_VENDOR_CONTROL_PARAM_FULL_SCANPERIOD:
3588*5113495bSYour Name 		return VENDOR_CONTROL_PARAM_ROAM_FULL_SCANPERIOD;
3589*5113495bSYour Name 	case ROAM_VENDOR_CONTROL_PARAM_PARTIAL_SCANPERIOD:
3590*5113495bSYour Name 		return VENDOR_CONTROL_PARAM_ROAM_PARTIAL_SCANPERIOD;
3591*5113495bSYour Name 	case ROAM_VENDOR_CONTROL_PARAM_ACTIVE_CH_DWELLTIME:
3592*5113495bSYour Name 		return VENDOR_CONTROL_PARAM_ROAM_ACTIVE_CH_DWELLTIME;
3593*5113495bSYour Name 	case ROAM_VENDOR_CONTROL_PARAM_PASSIVE_CH_DWELLTIME:
3594*5113495bSYour Name 		return VENDOR_CONTROL_PARAM_ROAM_PASSIVE_CH_DWELLTIME;
3595*5113495bSYour Name 	case ROAM_VENDOR_CONTROL_PARAM_HOME_CH_TIME:
3596*5113495bSYour Name 		return VENDOR_CONTROL_PARAM_ROAM_HOME_CH_TIME;
3597*5113495bSYour Name 	case ROAM_VENDOR_CONTROL_PARAM_AWAY_TIME:
3598*5113495bSYour Name 		return VENDOR_CONTROL_PARAM_ROAM_AWAY_TIME;
3599*5113495bSYour Name 	case ROAM_VENDOR_CONTROL_PARAM_ALL:
3600*5113495bSYour Name 		return VENDOR_CONTROL_PARAM_ROAM_ALL;
3601*5113495bSYour Name 	default:
3602*5113495bSYour Name 		wmi_debug("Invalid param id");
3603*5113495bSYour Name 		return 0;
3604*5113495bSYour Name 	}
3605*5113495bSYour Name }
3606*5113495bSYour Name 
3607*5113495bSYour Name static QDF_STATUS
extract_roam_vendor_control_param_event_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint32_t len,struct roam_vendor_handoff_params ** list)3608*5113495bSYour Name extract_roam_vendor_control_param_event_tlv(wmi_unified_t wmi_handle,
3609*5113495bSYour Name 				uint8_t *event, uint32_t len,
3610*5113495bSYour Name 				struct roam_vendor_handoff_params **list)
3611*5113495bSYour Name {
3612*5113495bSYour Name 	WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID_param_tlvs *param_buf = NULL;
3613*5113495bSYour Name 	wmi_roam_get_vendor_control_param_event_fixed_param *fixed_param = NULL;
3614*5113495bSYour Name 	uint32_t num_entries, i;
3615*5113495bSYour Name 	wmi_vendor_control_param *src_list;
3616*5113495bSYour Name 	struct roam_vendor_handoff_params *dst_list;
3617*5113495bSYour Name 	struct roam_param_info *param_info;
3618*5113495bSYour Name 
3619*5113495bSYour Name 	if (!event || !len) {
3620*5113495bSYour Name 		wmi_debug("Empty roam vendor control param event");
3621*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3622*5113495bSYour Name 	}
3623*5113495bSYour Name 
3624*5113495bSYour Name 	param_buf =
3625*5113495bSYour Name 		(WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID_param_tlvs *)event;
3626*5113495bSYour Name 	if (!param_buf) {
3627*5113495bSYour Name 		wmi_err("received null buf from target");
3628*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3629*5113495bSYour Name 	}
3630*5113495bSYour Name 
3631*5113495bSYour Name 	fixed_param = (wmi_roam_get_vendor_control_param_event_fixed_param *)
3632*5113495bSYour Name 					param_buf->fixed_param;
3633*5113495bSYour Name 	if (!fixed_param) {
3634*5113495bSYour Name 		wmi_err("received null event data from target");
3635*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3636*5113495bSYour Name 	}
3637*5113495bSYour Name 
3638*5113495bSYour Name 	if (fixed_param->vdev_id >= WLAN_MAX_VDEVS) {
3639*5113495bSYour Name 		wmi_debug("Invalid VDEV id %d", fixed_param->vdev_id);
3640*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3641*5113495bSYour Name 	}
3642*5113495bSYour Name 
3643*5113495bSYour Name 	num_entries = param_buf->num_vendor_control_param;
3644*5113495bSYour Name 	src_list = param_buf->vendor_control_param;
3645*5113495bSYour Name 
3646*5113495bSYour Name 	if (len < (sizeof(*fixed_param) + (num_entries * sizeof(*src_list)))) {
3647*5113495bSYour Name 		wmi_err("Invalid length: %d", len);
3648*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3649*5113495bSYour Name 	}
3650*5113495bSYour Name 
3651*5113495bSYour Name 	dst_list = qdf_mem_malloc(sizeof(struct roam_vendor_handoff_params));
3652*5113495bSYour Name 	if (!dst_list)
3653*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3654*5113495bSYour Name 
3655*5113495bSYour Name 	dst_list->vdev_id = fixed_param->vdev_id;
3656*5113495bSYour Name 	wmi_debug("vdev_id:%d, num_tlv:%d", dst_list->vdev_id, num_entries);
3657*5113495bSYour Name 
3658*5113495bSYour Name 	param_info = &dst_list->param_info[0];
3659*5113495bSYour Name 	for (i = 0; i < num_entries; i++) {
3660*5113495bSYour Name 		param_info->param_id =
3661*5113495bSYour Name 		     convert_wmi_roam_vendor_control_param(src_list->param_id);
3662*5113495bSYour Name 		param_info->param_value = src_list->param_value;
3663*5113495bSYour Name 		wmi_debug("param_info->param_id:%d, param_info->param_value:%d",
3664*5113495bSYour Name 			  param_info->param_id, param_info->param_value);
3665*5113495bSYour Name 		param_info++;
3666*5113495bSYour Name 		src_list++;
3667*5113495bSYour Name 	}
3668*5113495bSYour Name 
3669*5113495bSYour Name 	dst_list->num_entries = num_entries;
3670*5113495bSYour Name 	*list = dst_list;
3671*5113495bSYour Name 
3672*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3673*5113495bSYour Name }
3674*5113495bSYour Name 
3675*5113495bSYour Name /**
3676*5113495bSYour Name  * send_process_roam_vendor_handoff_req_cmd_tlv() - Send vendor handoff command
3677*5113495bSYour Name  * to fw.
3678*5113495bSYour Name  * @wmi_handle: wmi handle
3679*5113495bSYour Name  * @vdev_id: vdev id
3680*5113495bSYour Name  * @param_id: parameter ID to set
3681*5113495bSYour Name  *
3682*5113495bSYour Name  * Return: QDF STATUS
3683*5113495bSYour Name  */
3684*5113495bSYour Name static QDF_STATUS
send_process_roam_vendor_handoff_req_cmd_tlv(wmi_unified_t wmi_handle,uint8_t vdev_id,uint32_t param_id)3685*5113495bSYour Name send_process_roam_vendor_handoff_req_cmd_tlv(wmi_unified_t wmi_handle,
3686*5113495bSYour Name 					     uint8_t vdev_id,
3687*5113495bSYour Name 					     uint32_t param_id)
3688*5113495bSYour Name {
3689*5113495bSYour Name 	wmi_roam_get_vendor_control_param_cmd_fixed_param *cmd;
3690*5113495bSYour Name 	wmi_buf_t wmi_buf;
3691*5113495bSYour Name 	uint8_t *buf_ptr;
3692*5113495bSYour Name 	uint16_t len;
3693*5113495bSYour Name 
3694*5113495bSYour Name 	len = sizeof(wmi_roam_get_vendor_control_param_cmd_fixed_param);
3695*5113495bSYour Name 
3696*5113495bSYour Name 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
3697*5113495bSYour Name 	if (!wmi_buf)
3698*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
3699*5113495bSYour Name 
3700*5113495bSYour Name 	cmd = (wmi_roam_get_vendor_control_param_cmd_fixed_param *)wmi_buf_data(
3701*5113495bSYour Name 								wmi_buf);
3702*5113495bSYour Name 	buf_ptr = (uint8_t *)cmd;
3703*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
3704*5113495bSYour Name 	     WMITLV_TAG_STRUC_wmi_roam_get_vendor_control_param_cmd_fixed_param,
3705*5113495bSYour Name 	     WMITLV_GET_STRUCT_TLVLEN
3706*5113495bSYour Name 		       (wmi_roam_get_vendor_control_param_cmd_fixed_param));
3707*5113495bSYour Name 	cmd->vdev_id = vdev_id;
3708*5113495bSYour Name 	cmd->param_id = convert_roam_vendor_control_param(param_id);
3709*5113495bSYour Name 	wmi_debug("Send GET_VENDOR_CONTROL_PARAM cmd vdev_id:%d, param_id:0x%x",
3710*5113495bSYour Name 		cmd->vdev_id, cmd->param_id);
3711*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_GET_VENDOR_CONTROL_PARAM_CMDID, cmd->vdev_id, 0);
3712*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
3713*5113495bSYour Name 				 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_CMDID)) {
3714*5113495bSYour Name 		wmi_err("Failed to send get vendor control param command");
3715*5113495bSYour Name 		wmi_buf_free(wmi_buf);
3716*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3717*5113495bSYour Name 	}
3718*5113495bSYour Name 
3719*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3720*5113495bSYour Name }
3721*5113495bSYour Name 
3722*5113495bSYour Name /**
3723*5113495bSYour Name  * wmi_roam_offload_attach_vendor_handoff_tlv() - register wmi ops for vendor
3724*5113495bSYour Name  * handoff related command and event
3725*5113495bSYour Name  * @ops: wmi ops
3726*5113495bSYour Name  *
3727*5113495bSYour Name  * Return: none
3728*5113495bSYour Name  */
3729*5113495bSYour Name static inline void
wmi_roam_offload_attach_vendor_handoff_tlv(struct wmi_ops * ops)3730*5113495bSYour Name wmi_roam_offload_attach_vendor_handoff_tlv(struct wmi_ops *ops)
3731*5113495bSYour Name {
3732*5113495bSYour Name 	ops->extract_roam_vendor_control_param_event =
3733*5113495bSYour Name 				extract_roam_vendor_control_param_event_tlv;
3734*5113495bSYour Name 	ops->send_process_roam_vendor_handoff_req_cmd =
3735*5113495bSYour Name 			send_process_roam_vendor_handoff_req_cmd_tlv;
3736*5113495bSYour Name }
3737*5113495bSYour Name #else
3738*5113495bSYour Name static inline void
wmi_roam_offload_attach_vendor_handoff_tlv(struct wmi_ops * ops)3739*5113495bSYour Name wmi_roam_offload_attach_vendor_handoff_tlv(struct wmi_ops *ops)
3740*5113495bSYour Name {
3741*5113495bSYour Name }
3742*5113495bSYour Name #endif
3743*5113495bSYour Name 
3744*5113495bSYour Name #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_11BE_MLO)
3745*5113495bSYour Name static inline
wlan_wmi_cipher_to_crypto(uint8_t cipher)3746*5113495bSYour Name enum wlan_crypto_cipher_type wlan_wmi_cipher_to_crypto(uint8_t cipher)
3747*5113495bSYour Name {
3748*5113495bSYour Name 	switch (cipher) {
3749*5113495bSYour Name 	case WMI_CIPHER_NONE:
3750*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_NONE;
3751*5113495bSYour Name 	case WMI_CIPHER_WEP:
3752*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_WEP;
3753*5113495bSYour Name 	case WMI_CIPHER_TKIP:
3754*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_TKIP;
3755*5113495bSYour Name 	case WMI_CIPHER_AES_OCB:
3756*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_OCB;
3757*5113495bSYour Name 	case WMI_CIPHER_AES_CCM:
3758*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_CCM;
3759*5113495bSYour Name 	case WMI_CIPHER_WAPI:
3760*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_WAPI_SMS4;
3761*5113495bSYour Name 	case WMI_CIPHER_CKIP:
3762*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_CKIP;
3763*5113495bSYour Name 	case WMI_CIPHER_AES_CMAC:
3764*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_CMAC;
3765*5113495bSYour Name 	case WMI_CIPHER_AES_GCM:
3766*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_GCM;
3767*5113495bSYour Name 	case WMI_CIPHER_AES_GMAC:
3768*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_GMAC;
3769*5113495bSYour Name 	case WMI_CIPHER_WAPI_GCM_SM4:
3770*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_WAPI_GCM4;
3771*5113495bSYour Name 	case WMI_CIPHER_BIP_CMAC_128:
3772*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_CMAC;
3773*5113495bSYour Name 	case WMI_CIPHER_BIP_CMAC_256:
3774*5113495bSYour Name 		return	WLAN_CRYPTO_CIPHER_AES_CMAC_256;
3775*5113495bSYour Name 	case WMI_CIPHER_BIP_GMAC_128:
3776*5113495bSYour Name 		return	WLAN_CRYPTO_CIPHER_AES_GMAC;
3777*5113495bSYour Name 	case WMI_CIPHER_BIP_GMAC_256:
3778*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_GMAC_256;
3779*5113495bSYour Name 
3780*5113495bSYour Name 	default:
3781*5113495bSYour Name 		return 0;
3782*5113495bSYour Name 	}
3783*5113495bSYour Name }
3784*5113495bSYour Name #define MLO_PAIRWISE_LINKID 0xF
3785*5113495bSYour Name /**
3786*5113495bSYour Name  * wmi_fill_keys_from_tlv  - Fill the destination key buffer from the WMI TLV
3787*5113495bSYour Name  * @ml_keys: ML Keys TLV pointer
3788*5113495bSYour Name  * @dst_key: Destination keys
3789*5113495bSYour Name  * @dst_key_len: Destination keys length
3790*5113495bSYour Name  * @count: TLV count
3791*5113495bSYour Name  * @max_num_tlv: Total number of TLVs
3792*5113495bSYour Name  *
3793*5113495bSYour Name  * Return: None
3794*5113495bSYour Name  */
3795*5113495bSYour Name static void
wmi_fill_keys_from_tlv(wmi_roam_ml_key_material_param ** ml_keys,uint8_t * dst_key,uint8_t * dst_key_len,uint8_t * count,uint8_t max_num_tlv)3796*5113495bSYour Name wmi_fill_keys_from_tlv(wmi_roam_ml_key_material_param **ml_keys,
3797*5113495bSYour Name 		       uint8_t *dst_key, uint8_t *dst_key_len, uint8_t *count,
3798*5113495bSYour Name 		       uint8_t max_num_tlv)
3799*5113495bSYour Name {
3800*5113495bSYour Name 	uint8_t rem_key_len, bytes_filled, key_len, total_key_len;
3801*5113495bSYour Name 	uint8_t max_key_len = WLAN_CRYPTO_KEYBUF_SIZE + WLAN_CRYPTO_MICBUF_SIZE;
3802*5113495bSYour Name 
3803*5113495bSYour Name 	*dst_key_len = (*ml_keys)->key_len;
3804*5113495bSYour Name 	if (*dst_key_len > max_key_len)
3805*5113495bSYour Name 		*dst_key_len = max_key_len;
3806*5113495bSYour Name 
3807*5113495bSYour Name 	total_key_len = *dst_key_len;
3808*5113495bSYour Name 	rem_key_len = *dst_key_len;
3809*5113495bSYour Name 
3810*5113495bSYour Name 	while (rem_key_len) {
3811*5113495bSYour Name 		if (!(*ml_keys)) {
3812*5113495bSYour Name 			wmi_err_rl("ml_keys is NULL. rem_key_len:%d",
3813*5113495bSYour Name 				   rem_key_len);
3814*5113495bSYour Name 			return;
3815*5113495bSYour Name 		}
3816*5113495bSYour Name 
3817*5113495bSYour Name 		if (*count >= max_num_tlv) {
3818*5113495bSYour Name 			wmi_debug("Read all TLVs count:%d", *count);
3819*5113495bSYour Name 			return;
3820*5113495bSYour Name 		}
3821*5113495bSYour Name 
3822*5113495bSYour Name 		if (rem_key_len < WMI_MAX_KEY_LEN)
3823*5113495bSYour Name 			key_len = rem_key_len;
3824*5113495bSYour Name 		else
3825*5113495bSYour Name 			key_len = WMI_MAX_KEY_LEN;
3826*5113495bSYour Name 
3827*5113495bSYour Name 		bytes_filled = total_key_len - rem_key_len;
3828*5113495bSYour Name 		qdf_mem_copy(dst_key + bytes_filled, (*ml_keys)->key_buff,
3829*5113495bSYour Name 			     key_len);
3830*5113495bSYour Name 		(*ml_keys)++;
3831*5113495bSYour Name 		(*count)++;
3832*5113495bSYour Name 
3833*5113495bSYour Name 		rem_key_len -= key_len;
3834*5113495bSYour Name 	}
3835*5113495bSYour Name }
3836*5113495bSYour Name 
3837*5113495bSYour Name #define WMI_NUM_KEYS_ALLOCATED (WLAN_MAX_ML_BSS_LINKS * 4)
3838*5113495bSYour Name static QDF_STATUS
extract_roam_synch_key_event_tlv(wmi_unified_t wmi_handle,uint8_t * event,uint32_t data_len,struct wlan_crypto_key_entry ** entries,uint8_t * num_entries,struct qdf_mac_addr * mld_addr)3839*5113495bSYour Name extract_roam_synch_key_event_tlv(wmi_unified_t wmi_handle,
3840*5113495bSYour Name 				 uint8_t *event, uint32_t data_len,
3841*5113495bSYour Name 				 struct wlan_crypto_key_entry **entries,
3842*5113495bSYour Name 				 uint8_t *num_entries,
3843*5113495bSYour Name 				 struct qdf_mac_addr *mld_addr)
3844*5113495bSYour Name {
3845*5113495bSYour Name 	WMI_ROAM_SYNCH_KEY_EVENTID_param_tlvs *param_buf = NULL;
3846*5113495bSYour Name 	wmi_roam_ml_key_material_param *ml_keys = NULL;
3847*5113495bSYour Name 	struct wlan_crypto_key_entry *key_entry;
3848*5113495bSYour Name 	struct wlan_crypto_keys *all_keys;
3849*5113495bSYour Name 	struct wlan_crypto_key *dst_key, *pairwise;
3850*5113495bSYour Name 	struct wlan_crypto_key *key_alloc_buf[WMI_NUM_KEYS_ALLOCATED];
3851*5113495bSYour Name 	bool flush_keybuf;
3852*5113495bSYour Name 	uint8_t total_num_tlv,  j = 0, k = 0;
3853*5113495bSYour Name 	uint8_t count = 0, total_links = 0, dst_key_count = 0;
3854*5113495bSYour Name 	uint8_t igtk_idx = 0, bigtk_idx = 0;
3855*5113495bSYour Name 	bool slot_found;
3856*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3857*5113495bSYour Name 
3858*5113495bSYour Name 	param_buf = (WMI_ROAM_SYNCH_KEY_EVENTID_param_tlvs *)event;
3859*5113495bSYour Name 	if (!param_buf) {
3860*5113495bSYour Name 		wmi_err_rl("received null buf from target");
3861*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3862*5113495bSYour Name 	}
3863*5113495bSYour Name 
3864*5113495bSYour Name 	total_num_tlv = param_buf->num_ml_key_material;
3865*5113495bSYour Name 	ml_keys = (wmi_roam_ml_key_material_param *)param_buf->ml_key_material;
3866*5113495bSYour Name 	if (!ml_keys) {
3867*5113495bSYour Name 		wmi_err_rl("received ml keys param is null");
3868*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3869*5113495bSYour Name 	}
3870*5113495bSYour Name 
3871*5113495bSYour Name 	*entries = qdf_mem_malloc(WLAN_MAX_ML_BSS_LINKS * sizeof(*key_entry));
3872*5113495bSYour Name 	if (!*entries)
3873*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
3874*5113495bSYour Name 
3875*5113495bSYour Name 	/*
3876*5113495bSYour Name 	 * Allocate memory for each PTK, GTK, IGTK, BIGTK keys.
3877*5113495bSYour Name 	 * So total WLAN_MAX_ML_BSS_LINKS * 4 keys are needed
3878*5113495bSYour Name 	 */
3879*5113495bSYour Name 	for (k = 0; k < WMI_NUM_KEYS_ALLOCATED; k++) {
3880*5113495bSYour Name 		key_alloc_buf[k] = qdf_mem_malloc(sizeof(*dst_key));
3881*5113495bSYour Name 		if (!key_alloc_buf[k]) {
3882*5113495bSYour Name 			flush_keybuf = true;
3883*5113495bSYour Name 			status = QDF_STATUS_E_NOMEM;
3884*5113495bSYour Name 			goto free_entries;
3885*5113495bSYour Name 		}
3886*5113495bSYour Name 	}
3887*5113495bSYour Name 
3888*5113495bSYour Name 	/*
3889*5113495bSYour Name 	 * key_entry is the master structure that is given directly to the
3890*5113495bSYour Name 	 * crypto module and stored for each link.
3891*5113495bSYour Name 	 * key_entry -> keys ->key filled from dst_key has the PTK & GTK indexed
3892*5113495bSYour Name 	 * with corresponding key index
3893*5113495bSYour Name 	 *
3894*5113495bSYour Name 	 * key_entry -> keys -> iGTK holds the iGTK key
3895*5113495bSYour Name 	 * key_entry -> keys -> BIGTK holds the BIGTK key
3896*5113495bSYour Name 	 */
3897*5113495bSYour Name 	key_entry = *entries;
3898*5113495bSYour Name 
3899*5113495bSYour Name 	/*
3900*5113495bSYour Name 	 * Initialize all the Key Entry structures with invalid Link
3901*5113495bSYour Name 	 * ID to identify empty links allocated and will be freed
3902*5113495bSYour Name 	 * at the end.
3903*5113495bSYour Name 	 */
3904*5113495bSYour Name 	for (j = 0; j < WLAN_MAX_ML_BSS_LINKS; j++)
3905*5113495bSYour Name 		key_entry[j].link_id = MLO_INVALID_LINK_IDX;
3906*5113495bSYour Name 
3907*5113495bSYour Name 	/*
3908*5113495bSYour Name 	 * TLV Format to parse:
3909*5113495bSYour Name 	 * 1. wmi_roam_ml_key_material_param -> For PTK with Link ID = 0xF
3910*5113495bSYour Name 	 * Copy this PTK to all the key entry of all the links.
3911*5113495bSYour Name 	 *
3912*5113495bSYour Name 	 * 2. wmi_roam_ml_key_material_param -> GTK for a valid Link.
3913*5113495bSYour Name 	 * Get available entry, and fill the GTK to that entry
3914*5113495bSYour Name 	 *
3915*5113495bSYour Name 	 * 3. wmi_roam_ml_key_material_param -> IGTK for a valid link
3916*5113495bSYour Name 	 *
3917*5113495bSYour Name 	 * 4. wmi_roam_ml_key_material_param -> BIGTK for a valid link
3918*5113495bSYour Name 	 *
3919*5113495bSYour Name 	 * 5. wmi_roam_ml_key_material_param -> For LTF Keyseed with Link ID =
3920*5113495bSYour Name 	 * 0xF and flags has LTF_USAGE set.
3921*5113495bSYour Name 	 *
3922*5113495bSYour Name 	 * If any of the key length is > WMI_MAX_KEY_LEN, then multiple
3923*5113495bSYour Name 	 * wmi_roam_ml_key_material_param TLVs follow to get the entire key
3924*5113495bSYour Name 	 */
3925*5113495bSYour Name 	while (ml_keys && count < total_num_tlv &&
3926*5113495bSYour Name 	       dst_key_count < WMI_NUM_KEYS_ALLOCATED) {
3927*5113495bSYour Name 		/*
3928*5113495bSYour Name 		 * Track individual keys with key_alloc_buf[dst_key_count] array
3929*5113495bSYour Name 		 * pointer to avoid mem leaks if parsing/validating any of the
3930*5113495bSYour Name 		 * keys fail.
3931*5113495bSYour Name 		 * Freeing the allocated keys it done at the end of this
3932*5113495bSYour Name 		 * function
3933*5113495bSYour Name 		 */
3934*5113495bSYour Name 		dst_key = key_alloc_buf[dst_key_count];
3935*5113495bSYour Name 		wmi_debug("link_id:%d key_ix:%d key_cipher:%d key_len:%d key_flags:%d",
3936*5113495bSYour Name 			  ml_keys->link_id, ml_keys->key_ix,
3937*5113495bSYour Name 			  ml_keys->key_cipher,
3938*5113495bSYour Name 			  ml_keys->key_len, ml_keys->key_flags);
3939*5113495bSYour Name 
3940*5113495bSYour Name 		if (!is_valid_keyix(ml_keys->key_ix)) {
3941*5113495bSYour Name 			wmi_err_rl("invalid key index:%d", ml_keys->key_ix);
3942*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
3943*5113495bSYour Name 			flush_keybuf = true;
3944*5113495bSYour Name 			goto free_entries;
3945*5113495bSYour Name 		}
3946*5113495bSYour Name 
3947*5113495bSYour Name 		/* Copy pairwise keys to all the entries */
3948*5113495bSYour Name 		if (ml_keys->link_id == MLO_PAIRWISE_LINKID) {
3949*5113495bSYour Name 			WMI_MAC_ADDR_TO_CHAR_ARRAY(&ml_keys->mac_addr,
3950*5113495bSYour Name 						   mld_addr->bytes);
3951*5113495bSYour Name 			if (!ml_keys->key_len) {
3952*5113495bSYour Name 				wmi_err_rl("Received key_len as 0 for tlv:%d",
3953*5113495bSYour Name 					   count);
3954*5113495bSYour Name 				status = QDF_STATUS_E_INVAL;
3955*5113495bSYour Name 				flush_keybuf = true;
3956*5113495bSYour Name 				goto free_entries;
3957*5113495bSYour Name 			}
3958*5113495bSYour Name 
3959*5113495bSYour Name 			if (ml_keys->key_flags & LTF_USAGE) {
3960*5113495bSYour Name 				struct wlan_crypto_ltf_keyseed_data key_seed;
3961*5113495bSYour Name 				uint8_t key_seed_len;
3962*5113495bSYour Name 
3963*5113495bSYour Name 				if (ml_keys->key_len >
3964*5113495bSYour Name 				    WLAN_MAX_SECURE_LTF_KEYSEED_LEN)
3965*5113495bSYour Name 					ml_keys->key_len =
3966*5113495bSYour Name 						WLAN_MAX_SECURE_LTF_KEYSEED_LEN;
3967*5113495bSYour Name 
3968*5113495bSYour Name 				/*
3969*5113495bSYour Name 				 * Filling the keys from multiple TLVs is
3970*5113495bSYour Name 				 * handled by below API and ml_keys ptr gets
3971*5113495bSYour Name 				 * incremented accordingly inside
3972*5113495bSYour Name 				 */
3973*5113495bSYour Name 				wmi_fill_keys_from_tlv(&ml_keys,
3974*5113495bSYour Name 						       key_seed.key_seed,
3975*5113495bSYour Name 						       &key_seed_len, &count,
3976*5113495bSYour Name 						       total_num_tlv);
3977*5113495bSYour Name 				key_seed.key_seed_len = key_seed_len;
3978*5113495bSYour Name 				wmi_debug("ML_KEY: Got LTF keyseed key for MLD: "
3979*5113495bSYour Name 					  QDF_MAC_ADDR_FMT   " key_seed_len:%d",
3980*5113495bSYour Name 					  QDF_MAC_ADDR_REF(mld_addr->bytes),
3981*5113495bSYour Name 					  key_seed.key_seed_len);
3982*5113495bSYour Name 
3983*5113495bSYour Name 				for (j = 0; j < WLAN_MAX_ML_BSS_LINKS; j++)
3984*5113495bSYour Name 					key_entry[j].keys.ltf_key_seed =
3985*5113495bSYour Name 								key_seed;
3986*5113495bSYour Name 
3987*5113495bSYour Name 				continue;
3988*5113495bSYour Name 			}
3989*5113495bSYour Name 
3990*5113495bSYour Name 			dst_key->valid = true;
3991*5113495bSYour Name 			dst_key->keylen = ml_keys->key_len;
3992*5113495bSYour Name 			dst_key->flags = ml_keys->key_flags;
3993*5113495bSYour Name 			dst_key->keyix = ml_keys->key_ix;
3994*5113495bSYour Name 			dst_key->key_type =
3995*5113495bSYour Name 					WLAN_CRYPTO_KEY_TYPE_UNICAST;
3996*5113495bSYour Name 			dst_key->cipher_type =
3997*5113495bSYour Name 				wlan_wmi_cipher_to_crypto(ml_keys->key_cipher);
3998*5113495bSYour Name 			dst_key->keylen = ml_keys->key_len;
3999*5113495bSYour Name 
4000*5113495bSYour Name 			wmi_fill_keys_from_tlv(&ml_keys, dst_key->keyval,
4001*5113495bSYour Name 					       &dst_key->keylen, &count,
4002*5113495bSYour Name 					       total_num_tlv);
4003*5113495bSYour Name 			wmi_err_rl("ML_KEY: Got Pairwise key for MLD: "
4004*5113495bSYour Name 				   QDF_MAC_ADDR_FMT " rem_len:%d",
4005*5113495bSYour Name 				   QDF_MAC_ADDR_REF(mld_addr->bytes),
4006*5113495bSYour Name 				   dst_key->keylen);
4007*5113495bSYour Name 
4008*5113495bSYour Name 			pairwise = dst_key;
4009*5113495bSYour Name 			/*
4010*5113495bSYour Name 			 * Pairwise keys will be sent only once. Copy that for
4011*5113495bSYour Name 			 * all the link entries
4012*5113495bSYour Name 			 */
4013*5113495bSYour Name 			for (j = 0; j < WLAN_MAX_ML_BSS_LINKS; j++) {
4014*5113495bSYour Name 				dst_key = key_alloc_buf[dst_key_count];
4015*5113495bSYour Name 				*dst_key = *pairwise;
4016*5113495bSYour Name 				key_entry[j].keys.key[dst_key->keyix] = dst_key;
4017*5113495bSYour Name 				dst_key_count++;
4018*5113495bSYour Name 			}
4019*5113495bSYour Name 
4020*5113495bSYour Name 			continue;
4021*5113495bSYour Name 		}
4022*5113495bSYour Name 
4023*5113495bSYour Name 		slot_found = false;
4024*5113495bSYour Name 		for (j = 0; j < WLAN_MAX_ML_BSS_LINKS; j++) {
4025*5113495bSYour Name 			if (ml_keys->link_id == MLO_INVALID_LINK_IDX)
4026*5113495bSYour Name 				break;
4027*5113495bSYour Name 
4028*5113495bSYour Name 			if (key_entry[j].link_id == MLO_INVALID_LINK_IDX ||
4029*5113495bSYour Name 			    key_entry[j].link_id == ml_keys->link_id) {
4030*5113495bSYour Name 				slot_found = true;
4031*5113495bSYour Name 				break;
4032*5113495bSYour Name 			}
4033*5113495bSYour Name 		}
4034*5113495bSYour Name 
4035*5113495bSYour Name 		if (!slot_found) {
4036*5113495bSYour Name 			wmi_err_rl("Not able to find a entry for link:%d j=%d",
4037*5113495bSYour Name 				   ml_keys->link_id, j);
4038*5113495bSYour Name 			break;
4039*5113495bSYour Name 		}
4040*5113495bSYour Name 
4041*5113495bSYour Name 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ml_keys->mac_addr,
4042*5113495bSYour Name 					   dst_key->macaddr);
4043*5113495bSYour Name 		key_entry[j].link_id = ml_keys->link_id;
4044*5113495bSYour Name 		qdf_copy_macaddr((struct qdf_mac_addr *)key_entry[j].mac_addr.raw,
4045*5113495bSYour Name 				 (struct qdf_mac_addr *)dst_key->macaddr);
4046*5113495bSYour Name 		all_keys = &key_entry[j].keys;
4047*5113495bSYour Name 
4048*5113495bSYour Name 		dst_key->valid = true;
4049*5113495bSYour Name 		dst_key->keyix = ml_keys->key_ix;
4050*5113495bSYour Name 		dst_key->cipher_type =
4051*5113495bSYour Name 				wlan_wmi_cipher_to_crypto(ml_keys->key_cipher);
4052*5113495bSYour Name 
4053*5113495bSYour Name 		qdf_mem_copy(dst_key->keyrsc, ml_keys->pn, WMI_MAX_PN_LEN);
4054*5113495bSYour Name 
4055*5113495bSYour Name 		/*
4056*5113495bSYour Name 		 * For LTF keyseed or FILS SHA 384, FILS SHA 512 cases, the key
4057*5113495bSYour Name 		 * size will go beyond WMI_MAX_KEY_LEN(32). So extract first 32
4058*5113495bSYour Name 		 * bytes from 1st TLV and extract the rest of the bytes from
4059*5113495bSYour Name 		 * the following TLVs
4060*5113495bSYour Name 		 */
4061*5113495bSYour Name 		dst_key->keylen = ml_keys->key_len;
4062*5113495bSYour Name 		wmi_fill_keys_from_tlv(&ml_keys, dst_key->keyval,
4063*5113495bSYour Name 				       &dst_key->keylen, &count, total_num_tlv);
4064*5113495bSYour Name 
4065*5113495bSYour Name 		if (is_igtk(dst_key->keyix)) {
4066*5113495bSYour Name 			dst_key->key_type = WLAN_CRYPTO_KEY_TYPE_GROUP;
4067*5113495bSYour Name 
4068*5113495bSYour Name 			igtk_idx = dst_key->keyix - WLAN_CRYPTO_MAXKEYIDX;
4069*5113495bSYour Name 			bigtk_idx = igtk_idx - WLAN_CRYPTO_MAXIGTKKEYIDX;
4070*5113495bSYour Name 
4071*5113495bSYour Name 			wmi_debug("ML_KEY: Slot:%d link_id:%d addr: " QDF_MAC_ADDR_FMT "Key is IGTK key_ix:%d igtk_idx:%d bigtk:%d",
4072*5113495bSYour Name 				  j, key_entry[j].link_id,
4073*5113495bSYour Name 				  QDF_MAC_ADDR_REF(dst_key->macaddr),
4074*5113495bSYour Name 				  dst_key->keyix, igtk_idx, bigtk_idx);
4075*5113495bSYour Name 			all_keys->igtk_key[igtk_idx] = dst_key;
4076*5113495bSYour Name 			all_keys->def_igtk_tx_keyid = igtk_idx;
4077*5113495bSYour Name 
4078*5113495bSYour Name 			bigtk_idx = 0;
4079*5113495bSYour Name 			igtk_idx = 0;
4080*5113495bSYour Name 		} else if (is_bigtk(dst_key->keyix)) {
4081*5113495bSYour Name 			dst_key->key_type = WLAN_CRYPTO_KEY_TYPE_GROUP;
4082*5113495bSYour Name 
4083*5113495bSYour Name 			igtk_idx = dst_key->keyix - WLAN_CRYPTO_MAXKEYIDX;
4084*5113495bSYour Name 			bigtk_idx = igtk_idx - WLAN_CRYPTO_MAXIGTKKEYIDX;
4085*5113495bSYour Name 
4086*5113495bSYour Name 			wmi_debug("ML_KEY: Slot:%d link_id:%d addr: " QDF_MAC_ADDR_FMT "Key is BIGTK key_ix:%d igtk_idx:%d bigtk:%d",
4087*5113495bSYour Name 				  j, key_entry[j].link_id,
4088*5113495bSYour Name 				  QDF_MAC_ADDR_REF(dst_key->macaddr),
4089*5113495bSYour Name 				  dst_key->keyix, igtk_idx, bigtk_idx);
4090*5113495bSYour Name 			all_keys->bigtk_key[bigtk_idx] = dst_key;
4091*5113495bSYour Name 			all_keys->def_bigtk_tx_keyid = bigtk_idx;
4092*5113495bSYour Name 
4093*5113495bSYour Name 			bigtk_idx = 0;
4094*5113495bSYour Name 			igtk_idx = 0;
4095*5113495bSYour Name 		} else if (is_gtk(dst_key->keyix)) {
4096*5113495bSYour Name 			wmi_debug("ML_KEY: Slot:%d link_id:%d addr: " QDF_MAC_ADDR_FMT " Key is GTK key_ix:%d",
4097*5113495bSYour Name 				  j, key_entry[j].link_id,
4098*5113495bSYour Name 				  QDF_MAC_ADDR_REF(dst_key->macaddr),
4099*5113495bSYour Name 				  dst_key->keyix);
4100*5113495bSYour Name 			dst_key->key_type = WLAN_CRYPTO_KEY_TYPE_GROUP;
4101*5113495bSYour Name 			all_keys->key[dst_key->keyix] = dst_key;
4102*5113495bSYour Name 		} else {
4103*5113495bSYour Name 			wmi_debug("Key is Pairwise. Shouldn't reach here");
4104*5113495bSYour Name 			/* Pairwise key */
4105*5113495bSYour Name 			dst_key->key_type = WLAN_CRYPTO_KEY_TYPE_UNICAST;
4106*5113495bSYour Name 			all_keys->key[dst_key->keyix] = dst_key;
4107*5113495bSYour Name 		}
4108*5113495bSYour Name 
4109*5113495bSYour Name 		dst_key_count++;
4110*5113495bSYour Name 	}
4111*5113495bSYour Name 
4112*5113495bSYour Name 	for (j = 0; j < WLAN_MAX_ML_BSS_LINKS; j++) {
4113*5113495bSYour Name 		/*
4114*5113495bSYour Name 		 * Pairwise keys maybe copied for all the WLAN_MAX_ML_BSS_LINKS
4115*5113495bSYour Name 		 * but firmware might have roamed to AP with number of links
4116*5113495bSYour Name 		 * less than WLAN_MAX_ML_BSS_LINKS. So free the memory for those
4117*5113495bSYour Name 		 * links
4118*5113495bSYour Name 		 */
4119*5113495bSYour Name 		if (key_entry[j].link_id != MLO_INVALID_LINK_IDX) {
4120*5113495bSYour Name 			total_links++;
4121*5113495bSYour Name 		} else {
4122*5113495bSYour Name 			wmi_err_rl("Free keys for invalid entry at index:%d",
4123*5113495bSYour Name 				   j);
4124*5113495bSYour Name 			wlan_crypto_free_key(&key_entry[j].keys);
4125*5113495bSYour Name 		}
4126*5113495bSYour Name 	}
4127*5113495bSYour Name 
4128*5113495bSYour Name 	*num_entries = total_links;
4129*5113495bSYour Name 	/* Free the invalid dst_keys allocated */
4130*5113495bSYour Name 	if (!*num_entries)
4131*5113495bSYour Name 		goto free_entries;
4132*5113495bSYour Name 
4133*5113495bSYour Name 	/*
4134*5113495bSYour Name 	 * This is to free the unfilled key_alloc_buf that
4135*5113495bSYour Name 	 * was allocated initially
4136*5113495bSYour Name 	 */
4137*5113495bSYour Name 	flush_keybuf = false;
4138*5113495bSYour Name 
4139*5113495bSYour Name 	wmi_err_rl("ML_KEYS: total_entries filled:%d total_num_tlv:%d dst_key_count:%d",
4140*5113495bSYour Name 		   *num_entries, total_num_tlv, dst_key_count);
4141*5113495bSYour Name 	goto free_keys;
4142*5113495bSYour Name 
4143*5113495bSYour Name free_entries:
4144*5113495bSYour Name 	qdf_mem_zero(*entries,
4145*5113495bSYour Name 		     WLAN_MAX_ML_BSS_LINKS * sizeof(**entries));
4146*5113495bSYour Name 	qdf_mem_free(*entries);
4147*5113495bSYour Name 
4148*5113495bSYour Name free_keys:
4149*5113495bSYour Name 	for (k = 0; k < WMI_NUM_KEYS_ALLOCATED; k++) {
4150*5113495bSYour Name 		if (!key_alloc_buf[k])
4151*5113495bSYour Name 			continue;
4152*5113495bSYour Name 
4153*5113495bSYour Name 		wmi_err_rl("flush keybuf :%d, key is valid", flush_keybuf,
4154*5113495bSYour Name 			   key_alloc_buf[k]->valid);
4155*5113495bSYour Name 		if (!flush_keybuf && key_alloc_buf[k]->valid)
4156*5113495bSYour Name 			continue;
4157*5113495bSYour Name 
4158*5113495bSYour Name 		wmi_err("Free key allocated at idx:%d", k);
4159*5113495bSYour Name 		qdf_mem_zero(key_alloc_buf[k], sizeof(*key_alloc_buf[k]));
4160*5113495bSYour Name 		qdf_mem_free(key_alloc_buf[k]);
4161*5113495bSYour Name 	}
4162*5113495bSYour Name 
4163*5113495bSYour Name 	return status;
4164*5113495bSYour Name }
4165*5113495bSYour Name 
4166*5113495bSYour Name static void
wmi_roam_offload_attach_mlo_tlv(struct wmi_ops * ops)4167*5113495bSYour Name wmi_roam_offload_attach_mlo_tlv(struct wmi_ops *ops)
4168*5113495bSYour Name {
4169*5113495bSYour Name 	ops->extract_roam_synch_key_event = extract_roam_synch_key_event_tlv;
4170*5113495bSYour Name }
4171*5113495bSYour Name #else
4172*5113495bSYour Name static inline void
wmi_roam_offload_attach_mlo_tlv(struct wmi_ops * ops)4173*5113495bSYour Name wmi_roam_offload_attach_mlo_tlv(struct wmi_ops *ops)
4174*5113495bSYour Name {}
4175*5113495bSYour Name #endif
4176*5113495bSYour Name 
wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)4177*5113495bSYour Name void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
4178*5113495bSYour Name {
4179*5113495bSYour Name 	struct wmi_ops *ops = wmi_handle->ops;
4180*5113495bSYour Name 
4181*5113495bSYour Name 	ops->extract_roam_btm_response_stats =
4182*5113495bSYour Name 				extract_roam_btm_response_stats_tlv;
4183*5113495bSYour Name 	ops->extract_roam_initial_info = extract_roam_initial_info_tlv;
4184*5113495bSYour Name 	ops->extract_roam_msg_info = extract_roam_msg_info_tlv;
4185*5113495bSYour Name 	ops->extract_roam_frame_info = extract_roam_frame_info_tlv;
4186*5113495bSYour Name 	ops->extract_roam_sync_event = extract_roam_sync_event_tlv;
4187*5113495bSYour Name 	ops->extract_roam_sync_frame_event = extract_roam_sync_frame_event_tlv;
4188*5113495bSYour Name 	ops->extract_roam_event = extract_roam_event_tlv;
4189*5113495bSYour Name 	ops->extract_btm_dl_event = extract_btm_denylist_event;
4190*5113495bSYour Name 	ops->extract_vdev_disconnect_event = extract_vdev_disconnect_event_tlv;
4191*5113495bSYour Name 	ops->extract_roam_scan_chan_list = extract_roam_scan_chan_list_tlv;
4192*5113495bSYour Name 	ops->extract_roam_stats_event = extract_roam_stats_event_tlv;
4193*5113495bSYour Name 	ops->extract_auth_offload_event = extract_auth_offload_event_tlv;
4194*5113495bSYour Name 	ops->extract_roam_pmkid_request = extract_roam_pmkid_request_tlv;
4195*5113495bSYour Name 	ops->send_set_ric_req_cmd = send_set_ric_req_cmd_tlv;
4196*5113495bSYour Name 	ops->send_process_roam_synch_complete_cmd =
4197*5113495bSYour Name 			send_process_roam_synch_complete_cmd_tlv;
4198*5113495bSYour Name 	ops->send_roam_invoke_cmd = send_roam_invoke_cmd_tlv;
4199*5113495bSYour Name 	ops->send_vdev_set_pcl_cmd = send_vdev_set_pcl_cmd_tlv;
4200*5113495bSYour Name 	ops->send_set_roam_trigger_cmd = send_set_roam_trigger_cmd_tlv;
4201*5113495bSYour Name 	ops->extract_roam_candidate_frame = extract_roam_candidate_frame_tlv;
4202*5113495bSYour Name 	ops->extract_peer_oper_mode_event = extract_peer_oper_mode_event_tlv;
4203*5113495bSYour Name 	wmi_roam_offload_attach_vendor_handoff_tlv(ops);
4204*5113495bSYour Name 	wmi_roam_offload_attach_mlo_tlv(ops);
4205*5113495bSYour Name }
4206*5113495bSYour Name #else
4207*5113495bSYour Name static inline QDF_STATUS
extract_roam_btm_response_stats_tlv(wmi_unified_t wmi_handle,void * evt_buf,struct roam_btm_response_data * dst,uint8_t idx)4208*5113495bSYour Name extract_roam_btm_response_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
4209*5113495bSYour Name 				    struct roam_btm_response_data *dst,
4210*5113495bSYour Name 				    uint8_t idx)
4211*5113495bSYour Name {
4212*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
4213*5113495bSYour Name }
4214*5113495bSYour Name 
4215*5113495bSYour Name static inline QDF_STATUS
extract_roam_initial_info_tlv(wmi_unified_t wmi_handle,void * evt_buf,struct roam_initial_data * dst,uint8_t idx)4216*5113495bSYour Name extract_roam_initial_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
4217*5113495bSYour Name 			      struct roam_initial_data *dst, uint8_t idx)
4218*5113495bSYour Name {
4219*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
4220*5113495bSYour Name }
4221*5113495bSYour Name 
4222*5113495bSYour Name static inline QDF_STATUS
extract_roam_msg_info_tlv(wmi_unified_t wmi_handle,void * evt_buf,struct roam_msg_info * dst,uint8_t idx)4223*5113495bSYour Name extract_roam_msg_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
4224*5113495bSYour Name 			  struct roam_msg_info *dst, uint8_t idx)
4225*5113495bSYour Name {
4226*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
4227*5113495bSYour Name }
4228*5113495bSYour Name 
4229*5113495bSYour Name static inline QDF_STATUS
extract_roam_sync_event(wmi_unified_t wmi_handle,void * evt_buf,uint32_t len,struct roam_offload_synch_ind ** roam_sync_ind)4230*5113495bSYour Name extract_roam_sync_event(wmi_unified_t wmi_handle, void *evt_buf,
4231*5113495bSYour Name 			uint32_t len,
4232*5113495bSYour Name 			struct roam_offload_synch_ind **roam_sync_ind)
4233*5113495bSYour Name {
4234*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
4235*5113495bSYour Name }
4236*5113495bSYour Name 
4237*5113495bSYour Name static inline QDF_STATUS
extract_roam_sync_frame_event(wmi_unified_t wmi_handle,void * evt_buf,struct roam_msg_info * dst,uint8_t idx)4238*5113495bSYour Name extract_roam_sync_frame_event(wmi_unified_t wmi_handle, void *evt_buf,
4239*5113495bSYour Name 			      struct roam_msg_info *dst, uint8_t idx)
4240*5113495bSYour Name {
4241*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
4242*5113495bSYour Name }
4243*5113495bSYour Name 
4244*5113495bSYour Name static inline QDF_STATUS
extract_roam_event(wmi_unified_t wmi_handle,void * evt_buf,uint32_t len,struct roam_offload_roam_event * roam_event)4245*5113495bSYour Name extract_roam_event(wmi_unified_t wmi_handle, void *evt_buf, uint32_t len,
4246*5113495bSYour Name 		   struct roam_offload_roam_event *roam_event)
4247*5113495bSYour Name {
4248*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
4249*5113495bSYour Name }
4250*5113495bSYour Name #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
4251*5113495bSYour Name 
4252*5113495bSYour Name #ifdef WLAN_FEATURE_ROAM_OFFLOAD
4253*5113495bSYour Name /**
4254*5113495bSYour Name  * wmi_fill_roam_offload_11r_params() - Fill roam scan params to send it to fw
4255*5113495bSYour Name  * @akm: Authentication key management type
4256*5113495bSYour Name  * @roam_offload_11r: TLV to be filled with 11r params
4257*5113495bSYour Name  * @roam_req: roam request param
4258*5113495bSYour Name  */
wmi_fill_roam_offload_11r_params(uint32_t akm,wmi_roam_11r_offload_tlv_param * roam_offload_11r,struct wlan_roam_scan_offload_params * roam_req)4259*5113495bSYour Name static void wmi_fill_roam_offload_11r_params(
4260*5113495bSYour Name 		uint32_t akm,
4261*5113495bSYour Name 		wmi_roam_11r_offload_tlv_param *roam_offload_11r,
4262*5113495bSYour Name 		struct wlan_roam_scan_offload_params *roam_req)
4263*5113495bSYour Name {
4264*5113495bSYour Name 	struct wlan_rso_11r_params *src_11r_params;
4265*5113495bSYour Name 	uint8_t *psk_msk, len;
4266*5113495bSYour Name 
4267*5113495bSYour Name 	src_11r_params = &roam_req->rso_11r_info;
4268*5113495bSYour Name 
4269*5113495bSYour Name 	if ((akm == WMI_AUTH_FT_RSNA_FILS_SHA256 ||
4270*5113495bSYour Name 	     akm == WMI_AUTH_FT_RSNA_FILS_SHA384) &&
4271*5113495bSYour Name 	    roam_req->fils_roam_config.fils_ft_len) {
4272*5113495bSYour Name 		wmi_debug("Update the FILS FT key to Firmware");
4273*5113495bSYour Name 		psk_msk = roam_req->fils_roam_config.fils_ft;
4274*5113495bSYour Name 		len = roam_req->fils_roam_config.fils_ft_len;
4275*5113495bSYour Name 	} else {
4276*5113495bSYour Name 		psk_msk = src_11r_params->psk_pmk;
4277*5113495bSYour Name 		len = src_11r_params->pmk_len;
4278*5113495bSYour Name 	}
4279*5113495bSYour Name 
4280*5113495bSYour Name 	/*
4281*5113495bSYour Name 	 * For SHA384 based akm, the pmk length is 48 bytes. So fill
4282*5113495bSYour Name 	 * first 32 bytes in roam_offload_11r->psk_msk and the remaining
4283*5113495bSYour Name 	 * bytes in roam_offload_11r->psk_msk_ext buffer
4284*5113495bSYour Name 	 */
4285*5113495bSYour Name 	roam_offload_11r->psk_msk_len = len > ROAM_OFFLOAD_PSK_MSK_BYTES ?
4286*5113495bSYour Name 					ROAM_OFFLOAD_PSK_MSK_BYTES : len;
4287*5113495bSYour Name 	qdf_mem_copy(roam_offload_11r->psk_msk, psk_msk,
4288*5113495bSYour Name 		     roam_offload_11r->psk_msk_len);
4289*5113495bSYour Name 	roam_offload_11r->psk_msk_ext_len = 0;
4290*5113495bSYour Name 
4291*5113495bSYour Name 	if (len > ROAM_OFFLOAD_PSK_MSK_BYTES) {
4292*5113495bSYour Name 		roam_offload_11r->psk_msk_ext_len =
4293*5113495bSYour Name 					len - roam_offload_11r->psk_msk_len;
4294*5113495bSYour Name 		qdf_mem_copy(roam_offload_11r->psk_msk_ext,
4295*5113495bSYour Name 			     &psk_msk[roam_offload_11r->psk_msk_len],
4296*5113495bSYour Name 			     roam_offload_11r->psk_msk_ext_len);
4297*5113495bSYour Name 	}
4298*5113495bSYour Name }
4299*5113495bSYour Name 
4300*5113495bSYour Name /**
4301*5113495bSYour Name  * wmi_is_ft_akm() - Check if the akm is FT akm. Based on the AKM 11r params
4302*5113495bSYour Name  * will be sent for lfr-3.0 roaming offload
4303*5113495bSYour Name  * @akm: AKM negotiated for the connection
4304*5113495bSYour Name  * @roam_req: roam request sent to firmware
4305*5113495bSYour Name  *
4306*5113495bSYour Name  * Return: true if the akm is 11r based
4307*5113495bSYour Name  */
wmi_is_ft_akm(int akm,struct wlan_roam_scan_offload_params * roam_req)4308*5113495bSYour Name static bool wmi_is_ft_akm(int akm,
4309*5113495bSYour Name 			  struct wlan_roam_scan_offload_params *roam_req)
4310*5113495bSYour Name {
4311*5113495bSYour Name 	switch (akm) {
4312*5113495bSYour Name 	case WMI_AUTH_FT_RSNA:
4313*5113495bSYour Name 	case WMI_AUTH_FT_RSNA_PSK:
4314*5113495bSYour Name 	case WMI_AUTH_FT_RSNA_SAE:
4315*5113495bSYour Name 	case WMI_AUTH_FT_RSNA_SUITE_B_8021X_SHA384:
4316*5113495bSYour Name 	case WMI_AUTH_FT_RSNA_FILS_SHA256:
4317*5113495bSYour Name 	case WMI_AUTH_FT_RSNA_FILS_SHA384:
4318*5113495bSYour Name 	case WMI_AUTH_FT_RSNA_SAE_SHA384:
4319*5113495bSYour Name 		return true;
4320*5113495bSYour Name 	case WMI_AUTH_OPEN:
4321*5113495bSYour Name 		if (roam_req->rso_11r_info.mdid.mdie_present &&
4322*5113495bSYour Name 		    roam_req->rso_11r_info.is_11r_assoc)
4323*5113495bSYour Name 			return true;
4324*5113495bSYour Name 
4325*5113495bSYour Name 		break;
4326*5113495bSYour Name 	default:
4327*5113495bSYour Name 		return false;
4328*5113495bSYour Name 	}
4329*5113495bSYour Name 
4330*5113495bSYour Name 	return false;
4331*5113495bSYour Name }
4332*5113495bSYour Name 
4333*5113495bSYour Name /**
4334*5113495bSYour Name  * wmi_get_rso_buf_len() - calculate the length needed to allocate buffer
4335*5113495bSYour Name  * for RSO mode command
4336*5113495bSYour Name  * @roam_req: roam request parameters
4337*5113495bSYour Name  */
4338*5113495bSYour Name static uint32_t
wmi_get_rso_buf_len(struct wlan_roam_scan_offload_params * roam_req)4339*5113495bSYour Name wmi_get_rso_buf_len(struct wlan_roam_scan_offload_params *roam_req)
4340*5113495bSYour Name {
4341*5113495bSYour Name 	wmi_tlv_buf_len_param *assoc_ies;
4342*5113495bSYour Name 	uint32_t buf_len;
4343*5113495bSYour Name 	uint32_t fils_tlv_len = 0;
4344*5113495bSYour Name 	int akm = roam_req->akm;
4345*5113495bSYour Name 
4346*5113495bSYour Name 	/*
4347*5113495bSYour Name 	 * Allocate room for wmi_roam_offload_tlv_param and
4348*5113495bSYour Name 	 * 11i or 11r or ese roam offload tlv param
4349*5113495bSYour Name 	 * Todo: Test if below headroom of 2 TLV header is needed
4350*5113495bSYour Name 	 */
4351*5113495bSYour Name 	buf_len = (2 * WMI_TLV_HDR_SIZE);
4352*5113495bSYour Name 
4353*5113495bSYour Name 	if (roam_req->is_rso_stop ||
4354*5113495bSYour Name 	    !roam_req->roam_offload_enabled) {
4355*5113495bSYour Name 		buf_len += (4 * WMI_TLV_HDR_SIZE);
4356*5113495bSYour Name 
4357*5113495bSYour Name 		if (!roam_req->is_rso_stop)
4358*5113495bSYour Name 			wmi_debug("vdev[%d]: %s roam offload: %d",
4359*5113495bSYour Name 				  roam_req->vdev_id,
4360*5113495bSYour Name 				  roam_req->is_rso_stop ? "RSO stop cmd." : "",
4361*5113495bSYour Name 				  roam_req->roam_offload_enabled);
4362*5113495bSYour Name 
4363*5113495bSYour Name 		return buf_len;
4364*5113495bSYour Name 	}
4365*5113495bSYour Name 
4366*5113495bSYour Name 	wmi_debug("wmi akm = %d", akm);
4367*5113495bSYour Name 
4368*5113495bSYour Name 	buf_len += sizeof(wmi_roam_offload_tlv_param);
4369*5113495bSYour Name 	buf_len += 2 * WMI_TLV_HDR_SIZE;
4370*5113495bSYour Name 
4371*5113495bSYour Name 	if ((akm != WMI_AUTH_OPEN || roam_req->rso_ese_info.is_ese_assoc ||
4372*5113495bSYour Name 	     wmi_is_ft_akm(akm, roam_req)) && akm != WMI_AUTH_NONE) {
4373*5113495bSYour Name 		if (roam_req->rso_ese_info.is_ese_assoc)
4374*5113495bSYour Name 			buf_len += sizeof(wmi_roam_ese_offload_tlv_param);
4375*5113495bSYour Name 		else if (wmi_is_ft_akm(akm, roam_req))
4376*5113495bSYour Name 			buf_len += sizeof(wmi_roam_11r_offload_tlv_param);
4377*5113495bSYour Name 		else
4378*5113495bSYour Name 			buf_len += sizeof(wmi_roam_11i_offload_tlv_param);
4379*5113495bSYour Name 	}
4380*5113495bSYour Name 
4381*5113495bSYour Name 	buf_len += (sizeof(*assoc_ies) + (2 * WMI_TLV_HDR_SIZE) +
4382*5113495bSYour Name 		    roundup(roam_req->assoc_ie_length, sizeof(uint32_t)));
4383*5113495bSYour Name 
4384*5113495bSYour Name 	/* Fils TLV */
4385*5113495bSYour Name 	buf_len += WMI_TLV_HDR_SIZE;
4386*5113495bSYour Name 	if (roam_req->add_fils_tlv) {
4387*5113495bSYour Name 		fils_tlv_len = sizeof(wmi_roam_fils_offload_tlv_param);
4388*5113495bSYour Name 		buf_len += fils_tlv_len;
4389*5113495bSYour Name 	}
4390*5113495bSYour Name 
4391*5113495bSYour Name 	if (roam_req->rso_11i_info.is_sae_same_pmk)
4392*5113495bSYour Name 		buf_len += WMI_TLV_HDR_SIZE +
4393*5113495bSYour Name 			   sizeof(wmi_roam_sae_offload_tlv_param);
4394*5113495bSYour Name 
4395*5113495bSYour Name 	roam_req->rso_mode_info.roam_scan_mode |=
4396*5113495bSYour Name 			WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
4397*5113495bSYour Name 
4398*5113495bSYour Name 	return buf_len;
4399*5113495bSYour Name }
4400*5113495bSYour Name 
4401*5113495bSYour Name #if defined(WLAN_FEATURE_FILS_SK)
4402*5113495bSYour Name /**
4403*5113495bSYour Name  * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command
4404*5113495bSYour Name  * @wmi_handle: wmi handle
4405*5113495bSYour Name  * @roam_req: Roam scan offload params
4406*5113495bSYour Name  * @buf_ptr: command buffer to send
4407*5113495bSYour Name  * @fils_tlv_len: fils tlv length
4408*5113495bSYour Name  *
4409*5113495bSYour Name  * Return: Updated buffer pointer
4410*5113495bSYour Name  */
wmi_add_fils_tlv(wmi_unified_t wmi_handle,struct wlan_roam_scan_offload_params * roam_req,uint8_t * buf_ptr,uint32_t fils_tlv_len)4411*5113495bSYour Name static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
4412*5113495bSYour Name 				 struct wlan_roam_scan_offload_params *roam_req,
4413*5113495bSYour Name 				 uint8_t *buf_ptr, uint32_t fils_tlv_len)
4414*5113495bSYour Name {
4415*5113495bSYour Name 	wmi_roam_fils_offload_tlv_param *fils_tlv;
4416*5113495bSYour Name 	wmi_erp_info *erp_info;
4417*5113495bSYour Name 	struct wlan_roam_fils_params *roam_fils_params;
4418*5113495bSYour Name 
4419*5113495bSYour Name 	if (!roam_req->add_fils_tlv) {
4420*5113495bSYour Name 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
4421*5113495bSYour Name 		buf_ptr += WMI_TLV_HDR_SIZE;
4422*5113495bSYour Name 		return buf_ptr;
4423*5113495bSYour Name 	}
4424*5113495bSYour Name 
4425*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4426*5113495bSYour Name 		       sizeof(*fils_tlv));
4427*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
4428*5113495bSYour Name 
4429*5113495bSYour Name 	fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr;
4430*5113495bSYour Name 	WMITLV_SET_HDR(&fils_tlv->tlv_header,
4431*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param,
4432*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
4433*5113495bSYour Name 				(wmi_roam_fils_offload_tlv_param));
4434*5113495bSYour Name 
4435*5113495bSYour Name 	roam_fils_params = &roam_req->fils_roam_config;
4436*5113495bSYour Name 	erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info);
4437*5113495bSYour Name 
4438*5113495bSYour Name 	erp_info->username_length = roam_fils_params->username_length;
4439*5113495bSYour Name 	qdf_mem_copy(erp_info->username, roam_fils_params->username,
4440*5113495bSYour Name 		     erp_info->username_length);
4441*5113495bSYour Name 
4442*5113495bSYour Name 	erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num;
4443*5113495bSYour Name 
4444*5113495bSYour Name 	erp_info->rRk_length = roam_fils_params->rrk_length;
4445*5113495bSYour Name 	qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk,
4446*5113495bSYour Name 		     erp_info->rRk_length);
4447*5113495bSYour Name 
4448*5113495bSYour Name 	erp_info->rIk_length = roam_fils_params->rik_length;
4449*5113495bSYour Name 	qdf_mem_copy(erp_info->rIk, roam_fils_params->rik,
4450*5113495bSYour Name 		     erp_info->rIk_length);
4451*5113495bSYour Name 
4452*5113495bSYour Name 	erp_info->realm_len = roam_fils_params->realm_len;
4453*5113495bSYour Name 	qdf_mem_copy(erp_info->realm, roam_fils_params->realm,
4454*5113495bSYour Name 		     erp_info->realm_len);
4455*5113495bSYour Name 
4456*5113495bSYour Name 	buf_ptr += sizeof(*fils_tlv);
4457*5113495bSYour Name 	wmi_debug("RSO_CFG: ERP: usrname_len:%d next_erp_seq_num:%d rRk_len:%d rIk_len:%d realm_len:%d",
4458*5113495bSYour Name 		  erp_info->username_length, erp_info->next_erp_seq_num,
4459*5113495bSYour Name 		  erp_info->rRk_length, erp_info->rIk_length,
4460*5113495bSYour Name 		  erp_info->realm_len);
4461*5113495bSYour Name 	return buf_ptr;
4462*5113495bSYour Name }
4463*5113495bSYour Name #else
4464*5113495bSYour Name static inline
wmi_add_fils_tlv(wmi_unified_t wmi_handle,struct wlan_roam_scan_offload_params * roam_req,uint8_t * buf_ptr,uint32_t fils_tlv_len)4465*5113495bSYour Name uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
4466*5113495bSYour Name 			  struct wlan_roam_scan_offload_params *roam_req,
4467*5113495bSYour Name 			  uint8_t *buf_ptr, uint32_t fils_tlv_len)
4468*5113495bSYour Name {
4469*5113495bSYour Name 	return buf_ptr;
4470*5113495bSYour Name }
4471*5113495bSYour Name #endif
4472*5113495bSYour Name 
4473*5113495bSYour Name #ifdef WLAN_SAE_SINGLE_PMK
4474*5113495bSYour Name static inline void
wmi_fill_sae_single_pmk_param(struct wlan_rso_11i_params * src_11i,wmi_roam_11i_offload_tlv_param * roam_offload_11i)4475*5113495bSYour Name wmi_fill_sae_single_pmk_param(struct wlan_rso_11i_params *src_11i,
4476*5113495bSYour Name 			      wmi_roam_11i_offload_tlv_param *roam_offload_11i)
4477*5113495bSYour Name {
4478*5113495bSYour Name 	if (src_11i->is_sae_same_pmk)
4479*5113495bSYour Name 		roam_offload_11i->flags |=
4480*5113495bSYour Name 			1 << WMI_ROAM_OFFLOAD_FLAG_SAE_SAME_PMKID;
4481*5113495bSYour Name }
4482*5113495bSYour Name 
wmi_fill_sae_single_pmk_tlv(struct wlan_roam_scan_offload_params * roam_req,uint8_t * buf_ptr)4483*5113495bSYour Name static uint8_t *wmi_fill_sae_single_pmk_tlv(
4484*5113495bSYour Name 	struct wlan_roam_scan_offload_params *roam_req, uint8_t *buf_ptr)
4485*5113495bSYour Name {
4486*5113495bSYour Name 	wmi_roam_sae_offload_tlv_param *sae_offload_param;
4487*5113495bSYour Name 
4488*5113495bSYour Name 	if (!roam_req->rso_11i_info.is_sae_same_pmk)
4489*5113495bSYour Name 		return buf_ptr;
4490*5113495bSYour Name 
4491*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4492*5113495bSYour Name 		       sizeof(wmi_roam_sae_offload_tlv_param));
4493*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
4494*5113495bSYour Name 
4495*5113495bSYour Name 	sae_offload_param = (wmi_roam_sae_offload_tlv_param *)buf_ptr;
4496*5113495bSYour Name 	WMITLV_SET_HDR(&sae_offload_param->tlv_header,
4497*5113495bSYour Name 	WMITLV_TAG_STRUC_wmi_roam_sae_offload_tlv_param,
4498*5113495bSYour Name 	WMITLV_GET_STRUCT_TLVLEN(wmi_roam_sae_offload_tlv_param));
4499*5113495bSYour Name 
4500*5113495bSYour Name 	sae_offload_param->spmk_timeout =
4501*5113495bSYour Name 			roam_req->sae_offload_params.spmk_timeout;
4502*5113495bSYour Name 	wmi_debug("spmk_timeout:%d seconds", sae_offload_param->spmk_timeout);
4503*5113495bSYour Name 
4504*5113495bSYour Name 	buf_ptr += sizeof(*sae_offload_param);
4505*5113495bSYour Name 
4506*5113495bSYour Name 	return buf_ptr;
4507*5113495bSYour Name }
4508*5113495bSYour Name #else
4509*5113495bSYour Name static inline void
wmi_fill_sae_single_pmk_param(struct wlan_rso_11i_params * src_11i,wmi_roam_11i_offload_tlv_param * roam_offload_11i)4510*5113495bSYour Name wmi_fill_sae_single_pmk_param(struct wlan_rso_11i_params *src_11i,
4511*5113495bSYour Name 			      wmi_roam_11i_offload_tlv_param *roam_offload_11i)
4512*5113495bSYour Name {}
4513*5113495bSYour Name 
wmi_fill_sae_single_pmk_tlv(struct wlan_roam_scan_offload_params * roam_req,uint8_t * buf_ptr)4514*5113495bSYour Name static inline uint8_t *wmi_fill_sae_single_pmk_tlv(
4515*5113495bSYour Name 		struct wlan_roam_scan_offload_params *roam_req,
4516*5113495bSYour Name 		uint8_t *buf_ptr)
4517*5113495bSYour Name {
4518*5113495bSYour Name 	return buf_ptr;
4519*5113495bSYour Name }
4520*5113495bSYour Name 
4521*5113495bSYour Name #endif
4522*5113495bSYour Name 
4523*5113495bSYour Name static QDF_STATUS
wmi_fill_rso_tlvs(wmi_unified_t wmi_handle,uint8_t * buf,struct wlan_roam_scan_offload_params * roam_req)4524*5113495bSYour Name wmi_fill_rso_tlvs(wmi_unified_t wmi_handle, uint8_t *buf,
4525*5113495bSYour Name 		  struct wlan_roam_scan_offload_params *roam_req)
4526*5113495bSYour Name {
4527*5113495bSYour Name 	wmi_roam_offload_tlv_param *roam_offload_params;
4528*5113495bSYour Name 	wmi_roam_11i_offload_tlv_param *roam_offload_11i;
4529*5113495bSYour Name 	wmi_roam_11r_offload_tlv_param *roam_offload_11r;
4530*5113495bSYour Name 	wmi_roam_ese_offload_tlv_param *roam_offload_ese;
4531*5113495bSYour Name 	wmi_tlv_buf_len_param *assoc_ies;
4532*5113495bSYour Name 	uint32_t fils_tlv_len = 0;
4533*5113495bSYour Name 	int akm = roam_req->akm;
4534*5113495bSYour Name 	struct wlan_rso_lfr3_params *src_lfr3_params =
4535*5113495bSYour Name 			&roam_req->rso_lfr3_params;
4536*5113495bSYour Name 	struct wlan_rso_lfr3_caps *src_lfr3_caps =
4537*5113495bSYour Name 			&roam_req->rso_lfr3_caps;
4538*5113495bSYour Name 	struct wlan_rso_11i_params *src_11i_info =
4539*5113495bSYour Name 			&roam_req->rso_11i_info;
4540*5113495bSYour Name 	struct wlan_rso_ese_params *src_ese_info =
4541*5113495bSYour Name 			&roam_req->rso_ese_info;
4542*5113495bSYour Name 	struct wlan_rso_11r_params *src_11r_info =
4543*5113495bSYour Name 			&roam_req->rso_11r_info;
4544*5113495bSYour Name 
4545*5113495bSYour Name 	/* For RSO stop command, dont fill 11i, 11r or ese tlv */
4546*5113495bSYour Name 	if (roam_req->is_rso_stop || !roam_req->roam_offload_enabled) {
4547*5113495bSYour Name 		WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC,
4548*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(0));
4549*5113495bSYour Name 		buf += WMI_TLV_HDR_SIZE;
4550*5113495bSYour Name 		WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC,
4551*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(0));
4552*5113495bSYour Name 		buf += WMI_TLV_HDR_SIZE;
4553*5113495bSYour Name 		WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC,
4554*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(0));
4555*5113495bSYour Name 		buf += WMI_TLV_HDR_SIZE;
4556*5113495bSYour Name 
4557*5113495bSYour Name 		WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC,
4558*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(0));
4559*5113495bSYour Name 		buf += WMI_TLV_HDR_SIZE;
4560*5113495bSYour Name 		WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC,
4561*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(0));
4562*5113495bSYour Name 		buf += WMI_TLV_HDR_SIZE;
4563*5113495bSYour Name 		WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_BYTE,
4564*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(0));
4565*5113495bSYour Name 
4566*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
4567*5113495bSYour Name 	}
4568*5113495bSYour Name 
4569*5113495bSYour Name 	WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC,
4570*5113495bSYour Name 		       sizeof(wmi_roam_offload_tlv_param));
4571*5113495bSYour Name 
4572*5113495bSYour Name 	buf += WMI_TLV_HDR_SIZE;
4573*5113495bSYour Name 	roam_offload_params = (wmi_roam_offload_tlv_param *)buf;
4574*5113495bSYour Name 	WMITLV_SET_HDR(buf,
4575*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param,
4576*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_offload_tlv_param));
4577*5113495bSYour Name 
4578*5113495bSYour Name 	roam_offload_params->prefer_5g = src_lfr3_params->prefer_5ghz;
4579*5113495bSYour Name 	roam_offload_params->rssi_cat_gap = src_lfr3_params->roam_rssi_cat_gap;
4580*5113495bSYour Name 	roam_offload_params->select_5g_margin =
4581*5113495bSYour Name 			src_lfr3_params->select_5ghz_margin;
4582*5113495bSYour Name 	roam_offload_params->handoff_delay_for_rx =
4583*5113495bSYour Name 			src_lfr3_params->ho_delay_for_rx;
4584*5113495bSYour Name 	roam_offload_params->max_mlme_sw_retries =
4585*5113495bSYour Name 			src_lfr3_params->roam_retry_count;
4586*5113495bSYour Name 	roam_offload_params->no_ack_timeout =
4587*5113495bSYour Name 			src_lfr3_params->roam_preauth_no_ack_timeout;
4588*5113495bSYour Name 	roam_offload_params->reassoc_failure_timeout =
4589*5113495bSYour Name 			src_lfr3_params->reassoc_failure_timeout;
4590*5113495bSYour Name 	roam_offload_params->roam_candidate_validity_time =
4591*5113495bSYour Name 			src_lfr3_params->rct_validity_timer;
4592*5113495bSYour Name 	roam_offload_params->roam_to_current_bss_disable =
4593*5113495bSYour Name 			src_lfr3_params->disable_self_roam;
4594*5113495bSYour Name 	wmi_debug("RSO_CFG: prefer_5g:%d rssi_cat_gap:%d select_5g_margin:%d ho_delay:%d max_sw_retry:%d no_ack_timeout:%d",
4595*5113495bSYour Name 		  roam_offload_params->prefer_5g,
4596*5113495bSYour Name 		  roam_offload_params->rssi_cat_gap,
4597*5113495bSYour Name 		  roam_offload_params->select_5g_margin,
4598*5113495bSYour Name 		  roam_offload_params->handoff_delay_for_rx,
4599*5113495bSYour Name 		  roam_offload_params->max_mlme_sw_retries,
4600*5113495bSYour Name 		  roam_offload_params->no_ack_timeout);
4601*5113495bSYour Name 	wmi_debug("RSO_CFG: reassoc_fail_timeout:%d rct_validity_time:%d disable_self_roam:%d",
4602*5113495bSYour Name 		  roam_offload_params->reassoc_failure_timeout,
4603*5113495bSYour Name 		  roam_offload_params->roam_candidate_validity_time,
4604*5113495bSYour Name 		  roam_offload_params->roam_to_current_bss_disable);
4605*5113495bSYour Name 
4606*5113495bSYour Name 	/* Fill the capabilities */
4607*5113495bSYour Name 	roam_offload_params->capability = src_lfr3_caps->capability;
4608*5113495bSYour Name 	roam_offload_params->ht_caps_info = src_lfr3_caps->ht_caps_info;
4609*5113495bSYour Name 	roam_offload_params->ampdu_param = src_lfr3_caps->ampdu_param;
4610*5113495bSYour Name 	roam_offload_params->ht_ext_cap = src_lfr3_caps->ht_ext_cap;
4611*5113495bSYour Name 	roam_offload_params->ht_txbf = src_lfr3_caps->ht_txbf;
4612*5113495bSYour Name 	roam_offload_params->asel_cap = src_lfr3_caps->asel_cap;
4613*5113495bSYour Name 	roam_offload_params->qos_caps = src_lfr3_caps->qos_caps;
4614*5113495bSYour Name 	roam_offload_params->qos_enabled = src_lfr3_caps->qos_enabled;
4615*5113495bSYour Name 	roam_offload_params->wmm_caps = src_lfr3_caps->wmm_caps;
4616*5113495bSYour Name 	qdf_mem_copy((uint8_t *)roam_offload_params->mcsset,
4617*5113495bSYour Name 		     (uint8_t *)src_lfr3_caps->mcsset,
4618*5113495bSYour Name 		     ROAM_OFFLOAD_NUM_MCS_SET);
4619*5113495bSYour Name 	wmi_debug("RSO_CFG: capability:0x%x ht_caps:0x%x ampdu_param:0%x ht_ext_cap:0x%x ht_txbf:0x%x asel_cap:0x%x qos_caps:0x%x qos_en:%d wmm_caps:0x%x",
4620*5113495bSYour Name 		  roam_offload_params->capability,
4621*5113495bSYour Name 		  roam_offload_params->ht_caps_info,
4622*5113495bSYour Name 		  roam_offload_params->ampdu_param,
4623*5113495bSYour Name 		  roam_offload_params->ht_ext_cap,
4624*5113495bSYour Name 		  roam_offload_params->ht_txbf, roam_offload_params->asel_cap,
4625*5113495bSYour Name 		  roam_offload_params->qos_caps,
4626*5113495bSYour Name 		  roam_offload_params->qos_enabled,
4627*5113495bSYour Name 		  roam_offload_params->wmm_caps);
4628*5113495bSYour Name 
4629*5113495bSYour Name 	buf += sizeof(wmi_roam_offload_tlv_param);
4630*5113495bSYour Name 	/*
4631*5113495bSYour Name 	 * The TLV's are in the order of 11i, 11R, ESE. Hence,
4632*5113495bSYour Name 	 * they are filled in the same order.Depending on the
4633*5113495bSYour Name 	 * authentication type, the other mode TLV's are nullified
4634*5113495bSYour Name 	 * and only headers are filled.
4635*5113495bSYour Name 	 */
4636*5113495bSYour Name 	if ((akm != WMI_AUTH_OPEN || roam_req->rso_ese_info.is_ese_assoc ||
4637*5113495bSYour Name 	     wmi_is_ft_akm(akm, roam_req)) && akm != WMI_AUTH_NONE) {
4638*5113495bSYour Name 		if (roam_req->rso_ese_info.is_ese_assoc) {
4639*5113495bSYour Name 			/* Fill the length of 11i, 11r TLV as 0 */
4640*5113495bSYour Name 			WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0);
4641*5113495bSYour Name 			buf += WMI_TLV_HDR_SIZE;
4642*5113495bSYour Name 
4643*5113495bSYour Name 			WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0);
4644*5113495bSYour Name 			buf += WMI_TLV_HDR_SIZE;
4645*5113495bSYour Name 
4646*5113495bSYour Name 			/* Start filling the ESE TLV */
4647*5113495bSYour Name 			WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC,
4648*5113495bSYour Name 				       sizeof(wmi_roam_ese_offload_tlv_param));
4649*5113495bSYour Name 			buf += WMI_TLV_HDR_SIZE;
4650*5113495bSYour Name 			roam_offload_ese =
4651*5113495bSYour Name 					(wmi_roam_ese_offload_tlv_param *)buf;
4652*5113495bSYour Name 			qdf_mem_copy(roam_offload_ese->krk, src_ese_info->krk,
4653*5113495bSYour Name 				     sizeof(src_ese_info->krk));
4654*5113495bSYour Name 			qdf_mem_copy(roam_offload_ese->btk, src_ese_info->btk,
4655*5113495bSYour Name 				     sizeof(src_ese_info->btk));
4656*5113495bSYour Name 
4657*5113495bSYour Name 			WMITLV_SET_HDR(&roam_offload_ese->tlv_header,
4658*5113495bSYour Name 			WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param,
4659*5113495bSYour Name 			WMITLV_GET_STRUCT_TLVLEN(wmi_roam_ese_offload_tlv_param));
4660*5113495bSYour Name 
4661*5113495bSYour Name 			buf += sizeof(wmi_roam_ese_offload_tlv_param);
4662*5113495bSYour Name 		} else if (wmi_is_ft_akm(akm, roam_req)) {
4663*5113495bSYour Name 			WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0);
4664*5113495bSYour Name 			buf += WMI_TLV_HDR_SIZE;
4665*5113495bSYour Name 
4666*5113495bSYour Name 			WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC,
4667*5113495bSYour Name 				       sizeof(wmi_roam_11r_offload_tlv_param));
4668*5113495bSYour Name 			buf += WMI_TLV_HDR_SIZE;
4669*5113495bSYour Name 
4670*5113495bSYour Name 			roam_offload_11r =
4671*5113495bSYour Name 				(wmi_roam_11r_offload_tlv_param *)buf;
4672*5113495bSYour Name 
4673*5113495bSYour Name 			roam_offload_11r->r0kh_id_len =
4674*5113495bSYour Name 				src_11r_info->r0kh_id_length;
4675*5113495bSYour Name 			qdf_mem_copy(roam_offload_11r->r0kh_id,
4676*5113495bSYour Name 				     src_11r_info->r0kh_id,
4677*5113495bSYour Name 				     src_11r_info->r0kh_id_length);
4678*5113495bSYour Name 
4679*5113495bSYour Name 			wmi_fill_roam_offload_11r_params(akm, roam_offload_11r,
4680*5113495bSYour Name 							 roam_req);
4681*5113495bSYour Name 
4682*5113495bSYour Name 			roam_offload_11r->mdie_present =
4683*5113495bSYour Name 				src_11r_info->mdid.mdie_present;
4684*5113495bSYour Name 			roam_offload_11r->mdid =
4685*5113495bSYour Name 				src_11r_info->mdid.mobility_domain;
4686*5113495bSYour Name 			roam_offload_11r->adaptive_11r =
4687*5113495bSYour Name 				src_11r_info->is_adaptive_11r;
4688*5113495bSYour Name 			roam_offload_11r->ft_im_for_deauth =
4689*5113495bSYour Name 				src_11r_info->enable_ft_im_roaming;
4690*5113495bSYour Name 			roam_offload_11r->ft_over_ds_enable =
4691*5113495bSYour Name 				src_11r_info->enable_ft_over_ds;
4692*5113495bSYour Name 
4693*5113495bSYour Name 			if (akm == WMI_AUTH_OPEN) {
4694*5113495bSYour Name 				/*
4695*5113495bSYour Name 				 * If FT-Open ensure pmk length
4696*5113495bSYour Name 				 * and r0khid len are zero
4697*5113495bSYour Name 				 */
4698*5113495bSYour Name 				roam_offload_11r->r0kh_id_len = 0;
4699*5113495bSYour Name 				roam_offload_11r->psk_msk_len = 0;
4700*5113495bSYour Name 			}
4701*5113495bSYour Name 
4702*5113495bSYour Name 			WMITLV_SET_HDR(&roam_offload_11r->tlv_header,
4703*5113495bSYour Name 			WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param,
4704*5113495bSYour Name 			WMITLV_GET_STRUCT_TLVLEN(wmi_roam_11r_offload_tlv_param));
4705*5113495bSYour Name 
4706*5113495bSYour Name 			buf += sizeof(wmi_roam_11r_offload_tlv_param);
4707*5113495bSYour Name 			/* Set ESE TLV len to 0*/
4708*5113495bSYour Name 			WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0);
4709*5113495bSYour Name 			buf += WMI_TLV_HDR_SIZE;
4710*5113495bSYour Name 
4711*5113495bSYour Name 			wmi_debug("RSO_CFG: vdev[%d] 11r TLV psk_msk_len = %d psk_msk_ext:%d md:0x%x",
4712*5113495bSYour Name 				  roam_req->vdev_id,
4713*5113495bSYour Name 				  roam_offload_11r->psk_msk_len,
4714*5113495bSYour Name 				  roam_offload_11r->psk_msk_ext_len,
4715*5113495bSYour Name 				  roam_offload_11r->mdid);
4716*5113495bSYour Name 			if (roam_offload_11r->psk_msk_len)
4717*5113495bSYour Name 				QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
4718*5113495bSYour Name 						   QDF_TRACE_LEVEL_DEBUG,
4719*5113495bSYour Name 						   roam_offload_11r->psk_msk,
4720*5113495bSYour Name 						   WLAN_MAX_PMK_DUMP_BYTES);
4721*5113495bSYour Name 		} else {
4722*5113495bSYour Name 			WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC,
4723*5113495bSYour Name 				       sizeof(wmi_roam_11i_offload_tlv_param));
4724*5113495bSYour Name 			buf += WMI_TLV_HDR_SIZE;
4725*5113495bSYour Name 
4726*5113495bSYour Name 			roam_offload_11i =
4727*5113495bSYour Name 				(wmi_roam_11i_offload_tlv_param *)buf;
4728*5113495bSYour Name 
4729*5113495bSYour Name 			if (src_11i_info->roam_key_mgmt_offload_enabled &&
4730*5113495bSYour Name 			    src_11i_info->fw_okc)
4731*5113495bSYour Name 				WMI_SET_ROAM_OFFLOAD_OKC_ENABLED(
4732*5113495bSYour Name 						   roam_offload_11i->flags);
4733*5113495bSYour Name 			else
4734*5113495bSYour Name 				WMI_SET_ROAM_OFFLOAD_OKC_DISABLED(
4735*5113495bSYour Name 						roam_offload_11i->flags);
4736*5113495bSYour Name 
4737*5113495bSYour Name 			if (src_11i_info->roam_key_mgmt_offload_enabled &&
4738*5113495bSYour Name 			    src_11i_info->fw_pmksa_cache)
4739*5113495bSYour Name 				WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED(
4740*5113495bSYour Name 						roam_offload_11i->flags);
4741*5113495bSYour Name 			else
4742*5113495bSYour Name 				WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED(
4743*5113495bSYour Name 						roam_offload_11i->flags);
4744*5113495bSYour Name 
4745*5113495bSYour Name 			wmi_fill_sae_single_pmk_param(src_11i_info,
4746*5113495bSYour Name 						      roam_offload_11i);
4747*5113495bSYour Name 
4748*5113495bSYour Name 			roam_offload_11i->pmk_len =
4749*5113495bSYour Name 				src_11i_info->pmk_len > ROAM_OFFLOAD_PMK_BYTES ?
4750*5113495bSYour Name 				ROAM_OFFLOAD_PMK_BYTES : src_11i_info->pmk_len;
4751*5113495bSYour Name 			qdf_mem_copy(roam_offload_11i->pmk,
4752*5113495bSYour Name 				     src_11i_info->psk_pmk,
4753*5113495bSYour Name 				     roam_offload_11i->pmk_len);
4754*5113495bSYour Name 
4755*5113495bSYour Name 			roam_offload_11i->pmk_ext_len = 0;
4756*5113495bSYour Name 			if (src_11i_info->pmk_len > ROAM_OFFLOAD_PMK_BYTES) {
4757*5113495bSYour Name 				roam_offload_11i->pmk_ext_len =
4758*5113495bSYour Name 					QDF_MIN(src_11i_info->pmk_len -
4759*5113495bSYour Name 						ROAM_OFFLOAD_PMK_BYTES,
4760*5113495bSYour Name 						ROAM_OFFLOAD_PMK_BYTES);
4761*5113495bSYour Name 			}
4762*5113495bSYour Name 			qdf_mem_copy(
4763*5113495bSYour Name 				roam_offload_11i->pmk_ext,
4764*5113495bSYour Name 				&src_11i_info->psk_pmk[ROAM_OFFLOAD_PMK_BYTES],
4765*5113495bSYour Name 				roam_offload_11i->pmk_ext_len);
4766*5113495bSYour Name 
4767*5113495bSYour Name 			WMITLV_SET_HDR(&roam_offload_11i->tlv_header,
4768*5113495bSYour Name 			WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param,
4769*5113495bSYour Name 			WMITLV_GET_STRUCT_TLVLEN(wmi_roam_11i_offload_tlv_param));
4770*5113495bSYour Name 
4771*5113495bSYour Name 			buf += sizeof(wmi_roam_11i_offload_tlv_param);
4772*5113495bSYour Name 
4773*5113495bSYour Name 			/*
4774*5113495bSYour Name 			 * Set 11r TLV len to 0, since security profile is not
4775*5113495bSYour Name 			 * FT
4776*5113495bSYour Name 			 */
4777*5113495bSYour Name 			WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0);
4778*5113495bSYour Name 			buf += WMI_TLV_HDR_SIZE;
4779*5113495bSYour Name 
4780*5113495bSYour Name 			/*
4781*5113495bSYour Name 			 * Set ESE TLV len to 0 since security profile is not
4782*5113495bSYour Name 			 * ESE
4783*5113495bSYour Name 			 */
4784*5113495bSYour Name 			WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0);
4785*5113495bSYour Name 			buf += WMI_TLV_HDR_SIZE;
4786*5113495bSYour Name 
4787*5113495bSYour Name 			wmi_info("RSO_CFG: vdev:%d pmk_len = %d pmksa caching:%d OKC:%d sae_same_pmk:%d key_mgmt_offload:%d",
4788*5113495bSYour Name 				 roam_req->vdev_id, roam_offload_11i->pmk_len,
4789*5113495bSYour Name 				 src_11i_info->fw_pmksa_cache,
4790*5113495bSYour Name 				 src_11i_info->fw_okc,
4791*5113495bSYour Name 				 src_11i_info->is_sae_same_pmk,
4792*5113495bSYour Name 				 src_11i_info->roam_key_mgmt_offload_enabled);
4793*5113495bSYour Name 			if (roam_offload_11i->pmk_len)
4794*5113495bSYour Name 				QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
4795*5113495bSYour Name 						   QDF_TRACE_LEVEL_DEBUG,
4796*5113495bSYour Name 						   roam_offload_11i->pmk,
4797*5113495bSYour Name 						   WLAN_MAX_PMK_DUMP_BYTES);
4798*5113495bSYour Name 			if (roam_offload_11i->pmk_ext_len)
4799*5113495bSYour Name 				QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
4800*5113495bSYour Name 						   QDF_TRACE_LEVEL_DEBUG,
4801*5113495bSYour Name 						   roam_offload_11i->pmk_ext,
4802*5113495bSYour Name 						   WLAN_MAX_PMK_DUMP_BYTES);
4803*5113495bSYour Name 		}
4804*5113495bSYour Name 	} else {
4805*5113495bSYour Name 		WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0);
4806*5113495bSYour Name 		buf += WMI_TLV_HDR_SIZE;
4807*5113495bSYour Name 
4808*5113495bSYour Name 		WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0);
4809*5113495bSYour Name 		buf += WMI_TLV_HDR_SIZE;
4810*5113495bSYour Name 
4811*5113495bSYour Name 		WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0);
4812*5113495bSYour Name 		buf += WMI_TLV_HDR_SIZE;
4813*5113495bSYour Name 	}
4814*5113495bSYour Name 
4815*5113495bSYour Name 	WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, sizeof(*assoc_ies));
4816*5113495bSYour Name 	buf += WMI_TLV_HDR_SIZE;
4817*5113495bSYour Name 
4818*5113495bSYour Name 	assoc_ies = (wmi_tlv_buf_len_param *)buf;
4819*5113495bSYour Name 	WMITLV_SET_HDR(&assoc_ies->tlv_header,
4820*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_tlv_buf_len_param,
4821*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param));
4822*5113495bSYour Name 	assoc_ies->buf_len = roam_req->assoc_ie_length;
4823*5113495bSYour Name 
4824*5113495bSYour Name 	buf += sizeof(*assoc_ies);
4825*5113495bSYour Name 
4826*5113495bSYour Name 	WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_BYTE,
4827*5113495bSYour Name 		       roundup(assoc_ies->buf_len, sizeof(uint32_t)));
4828*5113495bSYour Name 	buf += WMI_TLV_HDR_SIZE;
4829*5113495bSYour Name 
4830*5113495bSYour Name 	wmi_debug("RSO_CFG: akm:%d assoc_ies len:%d", akm, assoc_ies->buf_len);
4831*5113495bSYour Name 	if (assoc_ies->buf_len)
4832*5113495bSYour Name 		qdf_mem_copy(buf, roam_req->assoc_ie, assoc_ies->buf_len);
4833*5113495bSYour Name 
4834*5113495bSYour Name 	buf += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t));
4835*5113495bSYour Name 	buf = wmi_add_fils_tlv(wmi_handle, roam_req, buf, fils_tlv_len);
4836*5113495bSYour Name 
4837*5113495bSYour Name 	buf = wmi_fill_sae_single_pmk_tlv(roam_req, buf);
4838*5113495bSYour Name 
4839*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4840*5113495bSYour Name }
4841*5113495bSYour Name #else
4842*5113495bSYour Name static inline
wmi_get_rso_buf_len(struct wlan_roam_scan_offload_params * roam_req)4843*5113495bSYour Name uint32_t wmi_get_rso_buf_len(struct wlan_roam_scan_offload_params *roam_req)
4844*5113495bSYour Name {
4845*5113495bSYour Name 	return 0;
4846*5113495bSYour Name }
4847*5113495bSYour Name 
4848*5113495bSYour Name static inline QDF_STATUS
wmi_fill_rso_tlvs(wmi_unified_t wmi_handle,uint8_t * buf_ptr,struct wlan_roam_scan_offload_params * roam_req)4849*5113495bSYour Name wmi_fill_rso_tlvs(wmi_unified_t wmi_handle, uint8_t *buf_ptr,
4850*5113495bSYour Name 		  struct wlan_roam_scan_offload_params *roam_req)
4851*5113495bSYour Name {
4852*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4853*5113495bSYour Name }
4854*5113495bSYour Name #endif
4855*5113495bSYour Name 
4856*5113495bSYour Name static QDF_STATUS
wmi_fill_rso_start_scan_tlv(struct wlan_roam_scan_offload_params * rso_req,wmi_start_scan_cmd_fixed_param * scan_tlv)4857*5113495bSYour Name wmi_fill_rso_start_scan_tlv(struct wlan_roam_scan_offload_params *rso_req,
4858*5113495bSYour Name 			    wmi_start_scan_cmd_fixed_param *scan_tlv)
4859*5113495bSYour Name {
4860*5113495bSYour Name 	struct wlan_roam_scan_params *src_scan_params;
4861*5113495bSYour Name 
4862*5113495bSYour Name 	src_scan_params = &rso_req->rso_scan_params;
4863*5113495bSYour Name 	scan_tlv->scan_ctrl_flags = WMI_SCAN_ADD_CCK_RATES |
4864*5113495bSYour Name 				    WMI_SCAN_ADD_OFDM_RATES |
4865*5113495bSYour Name 				    WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ |
4866*5113495bSYour Name 				    WMI_SCAN_FILTER_PROBE_REQ;
4867*5113495bSYour Name 	if (rso_req->is_rso_stop) {
4868*5113495bSYour Name 		scan_tlv->dwell_time_active =
4869*5113495bSYour Name 			ROAM_SCAN_DWELL_TIME_ACTIVE_DEFAULT;
4870*5113495bSYour Name 		scan_tlv->dwell_time_passive =
4871*5113495bSYour Name 			ROAM_SCAN_DWELL_TIME_PASSIVE_DEFAULT;
4872*5113495bSYour Name 		scan_tlv->min_rest_time = ROAM_SCAN_MIN_REST_TIME_DEFAULT;
4873*5113495bSYour Name 		scan_tlv->max_rest_time = ROAM_SCAN_MAX_REST_TIME_DEFAULT;
4874*5113495bSYour Name 		scan_tlv->repeat_probe_time = 0;
4875*5113495bSYour Name 		scan_tlv->probe_spacing_time = 0;
4876*5113495bSYour Name 		scan_tlv->probe_delay = 0;
4877*5113495bSYour Name 		scan_tlv->max_scan_time = ROAM_SCAN_HW_DEF_SCAN_MAX_DURATION;
4878*5113495bSYour Name 		scan_tlv->idle_time = src_scan_params->min_rest_time;
4879*5113495bSYour Name 		scan_tlv->burst_duration = 0;
4880*5113495bSYour Name 
4881*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
4882*5113495bSYour Name 	}
4883*5113495bSYour Name 
4884*5113495bSYour Name 	scan_tlv->dwell_time_active = src_scan_params->dwell_time_active;
4885*5113495bSYour Name 	scan_tlv->dwell_time_passive = src_scan_params->dwell_time_passive;
4886*5113495bSYour Name 	scan_tlv->min_dwell_time_6ghz = src_scan_params->min_dwell_time_6ghz;
4887*5113495bSYour Name 	scan_tlv->burst_duration = src_scan_params->burst_duration;
4888*5113495bSYour Name 	scan_tlv->min_rest_time = src_scan_params->min_rest_time;
4889*5113495bSYour Name 	scan_tlv->max_rest_time = src_scan_params->max_rest_time;
4890*5113495bSYour Name 	scan_tlv->repeat_probe_time = src_scan_params->repeat_probe_time;
4891*5113495bSYour Name 	scan_tlv->probe_spacing_time = src_scan_params->probe_spacing_time;
4892*5113495bSYour Name 	scan_tlv->probe_delay = src_scan_params->probe_delay;
4893*5113495bSYour Name 	scan_tlv->max_scan_time = ROAM_SCAN_HW_DEF_SCAN_MAX_DURATION;
4894*5113495bSYour Name 	scan_tlv->idle_time = src_scan_params->idle_time;
4895*5113495bSYour Name 	scan_tlv->n_probes = src_scan_params->n_probes;
4896*5113495bSYour Name 	scan_tlv->scan_ctrl_flags |= src_scan_params->scan_ctrl_flags;
4897*5113495bSYour Name 	scan_tlv->dwell_time_active_6ghz =
4898*5113495bSYour Name 		src_scan_params->dwell_time_active_6ghz;
4899*5113495bSYour Name 	scan_tlv->dwell_time_passive_6ghz =
4900*5113495bSYour Name 		src_scan_params->dwell_time_passive_6ghz;
4901*5113495bSYour Name 
4902*5113495bSYour Name 	WMI_SCAN_SET_DWELL_MODE(scan_tlv->scan_ctrl_flags,
4903*5113495bSYour Name 				src_scan_params->rso_adaptive_dwell_mode);
4904*5113495bSYour Name 
4905*5113495bSYour Name 	/* Configure roaming scan behavior (DBS/Non-DBS scan) */
4906*5113495bSYour Name 	if (rso_req->roaming_scan_policy)
4907*5113495bSYour Name 		scan_tlv->scan_ctrl_flags_ext |=
4908*5113495bSYour Name 			WMI_SCAN_DBS_POLICY_FORCE_NONDBS;
4909*5113495bSYour Name 	else
4910*5113495bSYour Name 		scan_tlv->scan_ctrl_flags_ext |=
4911*5113495bSYour Name 			WMI_SCAN_DBS_POLICY_DEFAULT;
4912*5113495bSYour Name 
4913*5113495bSYour Name 	wmi_debug("RSO_CFG: dwell time: active %d passive %d, burst_duration:%d, active 6g %d passive 6g %d, min_rest_time %d max rest %d repeat probe time %d probe_spacing:%d",
4914*5113495bSYour Name 		  scan_tlv->dwell_time_active, scan_tlv->dwell_time_passive,
4915*5113495bSYour Name 		  scan_tlv->burst_duration,
4916*5113495bSYour Name 		  scan_tlv->dwell_time_active_6ghz,
4917*5113495bSYour Name 		  scan_tlv->dwell_time_passive_6ghz,
4918*5113495bSYour Name 		  scan_tlv->min_rest_time, scan_tlv->max_rest_time,
4919*5113495bSYour Name 		  scan_tlv->repeat_probe_time, scan_tlv->probe_spacing_time);
4920*5113495bSYour Name 	wmi_debug("RSO_CFG: ctrl_flags:0x%x probe_delay:%d max_scan_time:%d idle_time:%d n_probes:%d",
4921*5113495bSYour Name 		  scan_tlv->scan_ctrl_flags_ext, scan_tlv->probe_delay,
4922*5113495bSYour Name 		  scan_tlv->max_scan_time, scan_tlv->idle_time,
4923*5113495bSYour Name 		  scan_tlv->n_probes);
4924*5113495bSYour Name 
4925*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4926*5113495bSYour Name }
4927*5113495bSYour Name 
4928*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
4929*5113495bSYour Name static void
wmi_set_rso_stop_report_status(wmi_roam_scan_mode_fixed_param * rso_fp)4930*5113495bSYour Name wmi_set_rso_stop_report_status(wmi_roam_scan_mode_fixed_param *rso_fp)
4931*5113495bSYour Name {
4932*5113495bSYour Name 	/**
4933*5113495bSYour Name 	 * Set the REPORT status flag always, so that firmware sends RSO stop
4934*5113495bSYour Name 	 * status always
4935*5113495bSYour Name 	 */
4936*5113495bSYour Name 	rso_fp->flags |= WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS;
4937*5113495bSYour Name }
4938*5113495bSYour Name #else
4939*5113495bSYour Name static void
wmi_set_rso_stop_report_status(wmi_roam_scan_mode_fixed_param * rso_fp)4940*5113495bSYour Name wmi_set_rso_stop_report_status(wmi_roam_scan_mode_fixed_param *rso_fp)
4941*5113495bSYour Name {
4942*5113495bSYour Name }
4943*5113495bSYour Name #endif
4944*5113495bSYour Name 
4945*5113495bSYour Name /**
4946*5113495bSYour Name  * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw
4947*5113495bSYour Name  * @wmi_handle: wmi handle
4948*5113495bSYour Name  * @rso_req: roam request param
4949*5113495bSYour Name  *
4950*5113495bSYour Name  * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
4951*5113495bSYour Name  * of WMI_ROAM_SCAN_MODE.
4952*5113495bSYour Name  *
4953*5113495bSYour Name  * Return: QDF status
4954*5113495bSYour Name  */
4955*5113495bSYour Name static QDF_STATUS
send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle,struct wlan_roam_scan_offload_params * rso_req)4956*5113495bSYour Name send_roam_scan_offload_mode_cmd_tlv(
4957*5113495bSYour Name 			wmi_unified_t wmi_handle,
4958*5113495bSYour Name 			struct wlan_roam_scan_offload_params *rso_req)
4959*5113495bSYour Name {
4960*5113495bSYour Name 	wmi_buf_t buf = NULL;
4961*5113495bSYour Name 	QDF_STATUS status;
4962*5113495bSYour Name 	size_t len;
4963*5113495bSYour Name 	uint8_t *buf_ptr;
4964*5113495bSYour Name 	wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp;
4965*5113495bSYour Name 	wmi_start_scan_cmd_fixed_param *scan_cmd_fp;
4966*5113495bSYour Name 	struct wlan_roam_scan_mode_params *src_rso_mode_info = NULL;
4967*5113495bSYour Name 
4968*5113495bSYour Name 	/*
4969*5113495bSYour Name 	 * Need to create a buf with roam_scan command at
4970*5113495bSYour Name 	 * front and piggyback with scan command
4971*5113495bSYour Name 	 */
4972*5113495bSYour Name 	len = sizeof(wmi_roam_scan_mode_fixed_param) +
4973*5113495bSYour Name 	      sizeof(wmi_start_scan_cmd_fixed_param);
4974*5113495bSYour Name 	len += wmi_get_rso_buf_len(rso_req);
4975*5113495bSYour Name 
4976*5113495bSYour Name 	if (rso_req->rso_mode_info.roam_scan_mode ==
4977*5113495bSYour Name 	    (WMI_ROAM_SCAN_MODE_NONE | WMI_ROAM_SCAN_MODE_ROAMOFFLOAD))
4978*5113495bSYour Name 		len = sizeof(wmi_roam_scan_mode_fixed_param);
4979*5113495bSYour Name 
4980*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
4981*5113495bSYour Name 	if (!buf)
4982*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4983*5113495bSYour Name 
4984*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
4985*5113495bSYour Name 
4986*5113495bSYour Name 	src_rso_mode_info = &rso_req->rso_mode_info;
4987*5113495bSYour Name 	roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *)buf_ptr;
4988*5113495bSYour Name 	WMITLV_SET_HDR(
4989*5113495bSYour Name 		&roam_scan_mode_fp->tlv_header,
4990*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param,
4991*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_mode_fixed_param));
4992*5113495bSYour Name 
4993*5113495bSYour Name 	roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask =
4994*5113495bSYour Name 			src_rso_mode_info->min_delay_roam_trigger_bitmask;
4995*5113495bSYour Name 	roam_scan_mode_fp->min_delay_btw_scans =
4996*5113495bSYour Name 		WMI_SEC_TO_MSEC(src_rso_mode_info->min_delay_btw_scans);
4997*5113495bSYour Name 	roam_scan_mode_fp->roam_scan_mode = src_rso_mode_info->roam_scan_mode;
4998*5113495bSYour Name 	roam_scan_mode_fp->vdev_id = rso_req->vdev_id;
4999*5113495bSYour Name 	wmi_debug("RSO_CFG: vdev_id:%d roam scan mode:0x%x min_delay_bitmap:0x%x min_delay_btw_scans:%d",
5000*5113495bSYour Name 		  rso_req->vdev_id,
5001*5113495bSYour Name 		  roam_scan_mode_fp->roam_scan_mode,
5002*5113495bSYour Name 		  roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask,
5003*5113495bSYour Name 		  roam_scan_mode_fp->min_delay_btw_scans);
5004*5113495bSYour Name 	/*
5005*5113495bSYour Name 	 * For supplicant disabled roaming, all other roam triggers are disabled
5006*5113495bSYour Name 	 * so send only roam scan mode Fixed param in the command
5007*5113495bSYour Name 	 */
5008*5113495bSYour Name 	if (src_rso_mode_info->roam_scan_mode ==
5009*5113495bSYour Name 	    (WMI_ROAM_SCAN_MODE_NONE | WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) {
5010*5113495bSYour Name 		roam_scan_mode_fp->flags |=
5011*5113495bSYour Name 				WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS;
5012*5113495bSYour Name 		goto send_roam_scan_mode_cmd;
5013*5113495bSYour Name 	} else {
5014*5113495bSYour Name 		wmi_set_rso_stop_report_status(roam_scan_mode_fp);
5015*5113495bSYour Name 	}
5016*5113495bSYour Name 
5017*5113495bSYour Name 	/* Fill in scan parameters suitable for roaming scan */
5018*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param);
5019*5113495bSYour Name 	WMITLV_SET_HDR(
5020*5113495bSYour Name 		buf_ptr,
5021*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
5022*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(wmi_start_scan_cmd_fixed_param));
5023*5113495bSYour Name 	scan_cmd_fp = (wmi_start_scan_cmd_fixed_param *)buf_ptr;
5024*5113495bSYour Name 	wmi_fill_rso_start_scan_tlv(rso_req, scan_cmd_fp);
5025*5113495bSYour Name 
5026*5113495bSYour Name 	/* Ensure there is no additional IEs */
5027*5113495bSYour Name 	scan_cmd_fp->ie_len = 0;
5028*5113495bSYour Name 	buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param);
5029*5113495bSYour Name 
5030*5113495bSYour Name 	status = wmi_fill_rso_tlvs(wmi_handle, buf_ptr, rso_req);
5031*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
5032*5113495bSYour Name 		wmi_buf_free(buf);
5033*5113495bSYour Name 		return status;
5034*5113495bSYour Name 	}
5035*5113495bSYour Name 
5036*5113495bSYour Name send_roam_scan_mode_cmd:
5037*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_SCAN_MODE, rso_req->vdev_id, 0);
5038*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf,
5039*5113495bSYour Name 				      len, WMI_ROAM_SCAN_MODE);
5040*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
5041*5113495bSYour Name 		wmi_buf_free(buf);
5042*5113495bSYour Name 
5043*5113495bSYour Name 	return status;
5044*5113495bSYour Name }
5045*5113495bSYour Name 
5046*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
5047*5113495bSYour Name static void
send_update_mlo_roam_params(wmi_roam_cnd_scoring_param * score_param,struct ap_profile_params * ap_profile)5048*5113495bSYour Name send_update_mlo_roam_params(wmi_roam_cnd_scoring_param *score_param,
5049*5113495bSYour Name 			    struct ap_profile_params *ap_profile)
5050*5113495bSYour Name {
5051*5113495bSYour Name 	score_param->eht_weightage_pcnt =
5052*5113495bSYour Name 				ap_profile->param.eht_caps_weightage;
5053*5113495bSYour Name 	score_param->mlo_weightage_pcnt =
5054*5113495bSYour Name 				ap_profile->param.mlo_weightage;
5055*5113495bSYour Name 	wmi_debug("11be score params weightage: EHT %d MLO %d",
5056*5113495bSYour Name 		  score_param->eht_weightage_pcnt,
5057*5113495bSYour Name 		  score_param->mlo_weightage_pcnt);
5058*5113495bSYour Name }
5059*5113495bSYour Name 
convert_support_link_band_to_wmi(uint32_t bands)5060*5113495bSYour Name static uint32_t convert_support_link_band_to_wmi(uint32_t bands)
5061*5113495bSYour Name {
5062*5113495bSYour Name 	uint32_t target_bands = 0;
5063*5113495bSYour Name 
5064*5113495bSYour Name 	if (bands & BIT(REG_BAND_2G))
5065*5113495bSYour Name 		target_bands |= BIT(0);
5066*5113495bSYour Name 	if (bands & BIT(REG_BAND_5G))
5067*5113495bSYour Name 		target_bands |= BIT(1);
5068*5113495bSYour Name 	if (bands & BIT(REG_BAND_6G))
5069*5113495bSYour Name 		target_bands |= BIT(2);
5070*5113495bSYour Name 
5071*5113495bSYour Name 	return target_bands;
5072*5113495bSYour Name }
5073*5113495bSYour Name 
5074*5113495bSYour Name /**
5075*5113495bSYour Name  * send_roam_mlo_config_tlv() - send roam mlo config parameters
5076*5113495bSYour Name  * @wmi_handle: wmi handle
5077*5113495bSYour Name  * @req: pointer to wlan roam mlo config parameters
5078*5113495bSYour Name  *
5079*5113495bSYour Name  * This function sends the roam mlo config parameters to fw.
5080*5113495bSYour Name  *
5081*5113495bSYour Name  * Return: QDF status
5082*5113495bSYour Name  */
5083*5113495bSYour Name static QDF_STATUS
send_roam_mlo_config_tlv(wmi_unified_t wmi_handle,struct wlan_roam_mlo_config * req)5084*5113495bSYour Name send_roam_mlo_config_tlv(wmi_unified_t wmi_handle,
5085*5113495bSYour Name 			 struct wlan_roam_mlo_config *req)
5086*5113495bSYour Name {
5087*5113495bSYour Name 	wmi_roam_mlo_config_cmd_fixed_param *cmd;
5088*5113495bSYour Name 	wmi_buf_t buf;
5089*5113495bSYour Name 	uint32_t len;
5090*5113495bSYour Name 
5091*5113495bSYour Name 	len = sizeof(*cmd);
5092*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
5093*5113495bSYour Name 	if (!buf)
5094*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5095*5113495bSYour Name 
5096*5113495bSYour Name 	cmd = (wmi_roam_mlo_config_cmd_fixed_param *)wmi_buf_data(buf);
5097*5113495bSYour Name 	WMITLV_SET_HDR(
5098*5113495bSYour Name 	    &cmd->tlv_header,
5099*5113495bSYour Name 	    WMITLV_TAG_STRUC_wmi_roam_mlo_config_cmd_fixed_param,
5100*5113495bSYour Name 	    WMITLV_GET_STRUCT_TLVLEN(wmi_roam_mlo_config_cmd_fixed_param));
5101*5113495bSYour Name 
5102*5113495bSYour Name 	cmd->vdev_id = req->vdev_id;
5103*5113495bSYour Name 	cmd->support_link_num = req->support_link_num;
5104*5113495bSYour Name 	cmd->support_link_band = convert_support_link_band_to_wmi(
5105*5113495bSYour Name 						req->support_link_band);
5106*5113495bSYour Name 	if (!req->mlo_5gl_5gh_mlsr)
5107*5113495bSYour Name 		cmd->disallow_connect_modes |= WMI_ROAM_MLO_CONNECTION_MODE_5GL_5GH_MLSR;
5108*5113495bSYour Name 
5109*5113495bSYour Name 	WMI_CHAR_ARRAY_TO_MAC_ADDR(req->partner_link_addr.bytes,
5110*5113495bSYour Name 				   &cmd->partner_link_addr);
5111*5113495bSYour Name 
5112*5113495bSYour Name 	wmi_debug("RSO_CFG MLO: vdev_id:%d support_link_num:%d support_link_band:0x%0x disallow_connect_mode %d link addr:"QDF_MAC_ADDR_FMT,
5113*5113495bSYour Name 		  cmd->vdev_id, cmd->support_link_num,
5114*5113495bSYour Name 		  cmd->support_link_band,
5115*5113495bSYour Name 		  cmd->disallow_connect_modes,
5116*5113495bSYour Name 		  QDF_MAC_ADDR_REF(req->partner_link_addr.bytes));
5117*5113495bSYour Name 
5118*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_MLO_CONFIG_CMDID, cmd->vdev_id, 0);
5119*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
5120*5113495bSYour Name 				 WMI_ROAM_MLO_CONFIG_CMDID)) {
5121*5113495bSYour Name 		wmi_err("Failed to send WMI_ROAM_MLO_CONFIG_CMDID");
5122*5113495bSYour Name 		wmi_buf_free(buf);
5123*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5124*5113495bSYour Name 	}
5125*5113495bSYour Name 
5126*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5127*5113495bSYour Name }
5128*5113495bSYour Name 
wmi_roam_mlo_attach_tlv(struct wmi_unified * wmi_handle)5129*5113495bSYour Name static void wmi_roam_mlo_attach_tlv(struct wmi_unified *wmi_handle)
5130*5113495bSYour Name {
5131*5113495bSYour Name 	struct wmi_ops *ops = wmi_handle->ops;
5132*5113495bSYour Name 
5133*5113495bSYour Name 	ops->send_roam_mlo_config = send_roam_mlo_config_tlv;
5134*5113495bSYour Name }
5135*5113495bSYour Name 
5136*5113495bSYour Name #else
5137*5113495bSYour Name static void
send_update_mlo_roam_params(wmi_roam_cnd_scoring_param * score_param,struct ap_profile_params * ap_profile)5138*5113495bSYour Name send_update_mlo_roam_params(wmi_roam_cnd_scoring_param *score_param,
5139*5113495bSYour Name 			    struct ap_profile_params *ap_profile)
5140*5113495bSYour Name {
5141*5113495bSYour Name }
5142*5113495bSYour Name 
wmi_roam_mlo_attach_tlv(struct wmi_unified * wmi_handle)5143*5113495bSYour Name static void wmi_roam_mlo_attach_tlv(struct wmi_unified *wmi_handle)
5144*5113495bSYour Name {
5145*5113495bSYour Name }
5146*5113495bSYour Name #endif
5147*5113495bSYour Name 
5148*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
5149*5113495bSYour Name /**
5150*5113495bSYour Name  * update_mlo_prefer_percentage() - Update mlo preference with configured value
5151*5113495bSYour Name  * @psoc: psoc object
5152*5113495bSYour Name  * @mlo_prefer_percentage: pointer to hold mlo preference percentage
5153*5113495bSYour Name  *
5154*5113495bSYour Name  * Return: None
5155*5113495bSYour Name  */
update_mlo_prefer_percentage(struct wlan_objmgr_psoc * psoc,int8_t * mlo_prefer_percentage)5156*5113495bSYour Name static void update_mlo_prefer_percentage(struct wlan_objmgr_psoc *psoc,
5157*5113495bSYour Name 					  int8_t *mlo_prefer_percentage)
5158*5113495bSYour Name {
5159*5113495bSYour Name 	wlan_mlme_get_mlo_prefer_percentage(psoc, mlo_prefer_percentage);
5160*5113495bSYour Name 	/* host will deliver actual weighted number based on 100.
5161*5113495bSYour Name 	 * For example:
5162*5113495bSYour Name 	 * If percentage value in INI is 20, then host will give 120 (100 + 20)
5163*5113495bSYour Name 	 * i.e (100 * 1.2) as mlo_etp_weightage_pcnt.
5164*5113495bSYour Name 	 * If percentage value in INI is -20, then host will give 80 (100 - 20)
5165*5113495bSYour Name 	 * i.e (100 * 0.8) as mlo_etp_weightage_pcnt.
5166*5113495bSYour Name 	 */
5167*5113495bSYour Name 	*mlo_prefer_percentage += 100;
5168*5113495bSYour Name }
5169*5113495bSYour Name #else
5170*5113495bSYour Name static inline
update_mlo_prefer_percentage(struct wlan_objmgr_psoc * psoc,int8_t * mlo_preference_pctn)5171*5113495bSYour Name void update_mlo_prefer_percentage(struct wlan_objmgr_psoc *psoc,
5172*5113495bSYour Name 				int8_t *mlo_preference_pctn)
5173*5113495bSYour Name {}
5174*5113495bSYour Name #endif
5175*5113495bSYour Name 
5176*5113495bSYour Name /**
5177*5113495bSYour Name  * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw
5178*5113495bSYour Name  * @wmi_handle: wmi handle
5179*5113495bSYour Name  * @ap_profile: ap profile
5180*5113495bSYour Name  *
5181*5113495bSYour Name  * Send WMI_ROAM_AP_PROFILE to firmware
5182*5113495bSYour Name  *
5183*5113495bSYour Name  * Return: CDF status
5184*5113495bSYour Name  */
5185*5113495bSYour Name static QDF_STATUS
send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,struct ap_profile_params * ap_profile)5186*5113495bSYour Name send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
5187*5113495bSYour Name 					  struct ap_profile_params *ap_profile)
5188*5113495bSYour Name {
5189*5113495bSYour Name 	wmi_buf_t buf = NULL;
5190*5113495bSYour Name 	QDF_STATUS status;
5191*5113495bSYour Name 	size_t len;
5192*5113495bSYour Name 	uint8_t *buf_ptr;
5193*5113495bSYour Name 	wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp;
5194*5113495bSYour Name 	wmi_roam_cnd_scoring_param *score_param;
5195*5113495bSYour Name 	wmi_ap_profile *profile;
5196*5113495bSYour Name 	wmi_roam_score_delta_param *score_delta_param;
5197*5113495bSYour Name 	wmi_roam_cnd_min_rssi_param *min_rssi_param;
5198*5113495bSYour Name 	wmi_owe_ap_profile *owe_ap_profile;
5199*5113495bSYour Name 	enum roam_trigger_reason trig_reason;
5200*5113495bSYour Name 	uint32_t *authmode_list;
5201*5113495bSYour Name 	int8_t mlo_prefer_percentage = 0;
5202*5113495bSYour Name 	wmi_ssid *ssid;
5203*5113495bSYour Name 	int i;
5204*5113495bSYour Name 
5205*5113495bSYour Name 	len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile);
5206*5113495bSYour Name 	len += sizeof(*score_param) + WMI_TLV_HDR_SIZE;
5207*5113495bSYour Name 
5208*5113495bSYour Name 	if (!wmi_service_enabled(wmi_handle,
5209*5113495bSYour Name 			wmi_service_configure_roam_trigger_param_support)) {
5210*5113495bSYour Name 		len += WMI_TLV_HDR_SIZE;
5211*5113495bSYour Name 		len += NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param);
5212*5113495bSYour Name 		len += WMI_TLV_HDR_SIZE;
5213*5113495bSYour Name 		len += NUM_OF_ROAM_MIN_RSSI * sizeof(*min_rssi_param);
5214*5113495bSYour Name 	} else {
5215*5113495bSYour Name 		len += 2 * WMI_TLV_HDR_SIZE;
5216*5113495bSYour Name 	}
5217*5113495bSYour Name 
5218*5113495bSYour Name 	if (ap_profile->owe_ap_profile.is_owe_transition_conn) {
5219*5113495bSYour Name 		len += WMI_TLV_HDR_SIZE;
5220*5113495bSYour Name 		len += sizeof(*owe_ap_profile);
5221*5113495bSYour Name 	} else {
5222*5113495bSYour Name 		len += WMI_TLV_HDR_SIZE;
5223*5113495bSYour Name 	}
5224*5113495bSYour Name 
5225*5113495bSYour Name 	if (ap_profile->profile.num_allowed_authmode) {
5226*5113495bSYour Name 		len += WMI_TLV_HDR_SIZE;
5227*5113495bSYour Name 		len += ap_profile->profile.num_allowed_authmode *
5228*5113495bSYour Name 						sizeof(uint32_t);
5229*5113495bSYour Name 	} else {
5230*5113495bSYour Name 		len += WMI_TLV_HDR_SIZE;
5231*5113495bSYour Name 	}
5232*5113495bSYour Name 
5233*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
5234*5113495bSYour Name 	if (!buf)
5235*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5236*5113495bSYour Name 
5237*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
5238*5113495bSYour Name 	roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *)buf_ptr;
5239*5113495bSYour Name 	WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header,
5240*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param,
5241*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
5242*5113495bSYour Name 			       (wmi_roam_ap_profile_fixed_param));
5243*5113495bSYour Name 	/* fill in threshold values */
5244*5113495bSYour Name 	roam_ap_profile_fp->vdev_id = ap_profile->vdev_id;
5245*5113495bSYour Name 	roam_ap_profile_fp->id = 0;
5246*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param);
5247*5113495bSYour Name 
5248*5113495bSYour Name 	profile = (wmi_ap_profile *)buf_ptr;
5249*5113495bSYour Name 	WMITLV_SET_HDR(&profile->tlv_header,
5250*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_ap_profile,
5251*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile));
5252*5113495bSYour Name 	profile->flags = ap_profile->profile.flags;
5253*5113495bSYour Name 	profile->rssi_threshold = ap_profile->profile.rssi_threshold;
5254*5113495bSYour Name 	profile->bg_rssi_threshold = ap_profile->profile.bg_rssi_threshold;
5255*5113495bSYour Name 	profile->ssid.ssid_len = ap_profile->profile.ssid.length;
5256*5113495bSYour Name 	qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.ssid,
5257*5113495bSYour Name 		     profile->ssid.ssid_len);
5258*5113495bSYour Name 	profile->rsn_authmode = ap_profile->profile.rsn_authmode;
5259*5113495bSYour Name 	profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset;
5260*5113495bSYour Name 	profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset;
5261*5113495bSYour Name 	profile->rsn_mcastmgmtcipherset =
5262*5113495bSYour Name 				ap_profile->profile.rsn_mcastmgmtcipherset;
5263*5113495bSYour Name 	profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh;
5264*5113495bSYour Name 
5265*5113495bSYour Name 	wmi_debug("vdev %d AP PROFILE: flags:%x rssi_thres:%d bg_rssi_thres:%d ssid:" QDF_SSID_FMT " authmode:%d uc cipher:%d mc cipher:%d mc mgmt cipher:%d rssi abs thresh:%d",
5266*5113495bSYour Name 		  roam_ap_profile_fp->vdev_id,
5267*5113495bSYour Name 		  profile->flags, profile->rssi_threshold,
5268*5113495bSYour Name 		  profile->bg_rssi_threshold,
5269*5113495bSYour Name 		  QDF_SSID_REF(profile->ssid.ssid_len,
5270*5113495bSYour Name 			       ap_profile->profile.ssid.ssid),
5271*5113495bSYour Name 		  profile->rsn_authmode, profile->rsn_ucastcipherset,
5272*5113495bSYour Name 		  profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset,
5273*5113495bSYour Name 		  profile->rssi_abs_thresh);
5274*5113495bSYour Name 
5275*5113495bSYour Name 	buf_ptr += sizeof(wmi_ap_profile);
5276*5113495bSYour Name 
5277*5113495bSYour Name 	score_param = (wmi_roam_cnd_scoring_param *)buf_ptr;
5278*5113495bSYour Name 	WMITLV_SET_HDR(&score_param->tlv_header,
5279*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param,
5280*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param));
5281*5113495bSYour Name 	score_param->disable_bitmap = ap_profile->param.disable_bitmap;
5282*5113495bSYour Name 	score_param->rssi_weightage_pcnt =
5283*5113495bSYour Name 			ap_profile->param.rssi_weightage;
5284*5113495bSYour Name 	score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage;
5285*5113495bSYour Name 	score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage;
5286*5113495bSYour Name 	score_param->he_weightage_pcnt = ap_profile->param.he_weightage;
5287*5113495bSYour Name 	score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage;
5288*5113495bSYour Name 	score_param->band_weightage_pcnt = ap_profile->param.band_weightage;
5289*5113495bSYour Name 	score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage;
5290*5113495bSYour Name 	score_param->security_weightage_pcnt =
5291*5113495bSYour Name 				ap_profile->param.security_weightage;
5292*5113495bSYour Name 	score_param->esp_qbss_weightage_pcnt =
5293*5113495bSYour Name 			ap_profile->param.esp_qbss_weightage;
5294*5113495bSYour Name 	score_param->beamforming_weightage_pcnt =
5295*5113495bSYour Name 			ap_profile->param.beamforming_weightage;
5296*5113495bSYour Name 	score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage;
5297*5113495bSYour Name 	score_param->oce_wan_weightage_pcnt =
5298*5113495bSYour Name 			ap_profile->param.oce_wan_weightage;
5299*5113495bSYour Name 	score_param->oce_ap_tx_pwr_weightage_pcnt =
5300*5113495bSYour Name 				ap_profile->param.oce_ap_tx_pwr_weightage;
5301*5113495bSYour Name 	score_param->oce_ap_subnet_id_weightage_pcnt =
5302*5113495bSYour Name 				ap_profile->param.oce_subnet_id_weightage;
5303*5113495bSYour Name 	score_param->vendor_roam_score_algorithm_id =
5304*5113495bSYour Name 			ap_profile->param.vendor_roam_score_algorithm;
5305*5113495bSYour Name 	score_param->sae_pk_ap_weightage_pcnt =
5306*5113495bSYour Name 				ap_profile->param.sae_pk_ap_weightage;
5307*5113495bSYour Name 	update_mlo_prefer_percentage(wmi_handle->soc->wmi_psoc,
5308*5113495bSYour Name 				     &mlo_prefer_percentage);
5309*5113495bSYour Name 	score_param->mlo_etp_weightage_pcnt = mlo_prefer_percentage;
5310*5113495bSYour Name 	send_update_mlo_roam_params(score_param, ap_profile);
5311*5113495bSYour Name 	wmi_debug("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 sae-pk %d security %d mlo_etp_weight_pct %d",
5312*5113495bSYour Name 		  score_param->disable_bitmap, score_param->rssi_weightage_pcnt,
5313*5113495bSYour Name 		  score_param->ht_weightage_pcnt,
5314*5113495bSYour Name 		  score_param->vht_weightage_pcnt,
5315*5113495bSYour Name 		  score_param->he_weightage_pcnt,
5316*5113495bSYour Name 		  score_param->bw_weightage_pcnt,
5317*5113495bSYour Name 		  score_param->band_weightage_pcnt,
5318*5113495bSYour Name 		  score_param->nss_weightage_pcnt,
5319*5113495bSYour Name 		  score_param->esp_qbss_weightage_pcnt,
5320*5113495bSYour Name 		  score_param->beamforming_weightage_pcnt,
5321*5113495bSYour Name 		  score_param->pcl_weightage_pcnt,
5322*5113495bSYour Name 		  score_param->oce_wan_weightage_pcnt,
5323*5113495bSYour Name 		  score_param->oce_ap_tx_pwr_weightage_pcnt,
5324*5113495bSYour Name 		  score_param->vendor_roam_score_algorithm_id,
5325*5113495bSYour Name 		  score_param->oce_ap_subnet_id_weightage_pcnt,
5326*5113495bSYour Name 		  score_param->sae_pk_ap_weightage_pcnt,
5327*5113495bSYour Name 		  score_param->security_weightage_pcnt,
5328*5113495bSYour Name 		  score_param->mlo_etp_weightage_pcnt);
5329*5113495bSYour Name 
5330*5113495bSYour Name 	score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score;
5331*5113495bSYour Name 	score_param->band_scoring.score_pcnt =
5332*5113495bSYour Name 			ap_profile->param.band_index_score;
5333*5113495bSYour Name 	score_param->nss_scoring.score_pcnt =
5334*5113495bSYour Name 			ap_profile->param.nss_index_score;
5335*5113495bSYour Name 	score_param->security_scoring.score_pcnt =
5336*5113495bSYour Name 			ap_profile->param.security_index_score;
5337*5113495bSYour Name 
5338*5113495bSYour Name 	wmi_debug("bw_index_score %x band_index_score %x nss_index_score %x security_index_score %x",
5339*5113495bSYour Name 		  score_param->bw_scoring.score_pcnt,
5340*5113495bSYour Name 		  score_param->band_scoring.score_pcnt,
5341*5113495bSYour Name 		  score_param->nss_scoring.score_pcnt,
5342*5113495bSYour Name 		  score_param->security_scoring.score_pcnt);
5343*5113495bSYour Name 
5344*5113495bSYour Name 	score_param->rssi_scoring.best_rssi_threshold =
5345*5113495bSYour Name 		(-1) * ap_profile->param.rssi_scoring.best_rssi_threshold;
5346*5113495bSYour Name 	score_param->rssi_scoring.good_rssi_threshold =
5347*5113495bSYour Name 		(-1) * ap_profile->param.rssi_scoring.good_rssi_threshold;
5348*5113495bSYour Name 	score_param->rssi_scoring.bad_rssi_threshold =
5349*5113495bSYour Name 		(-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold;
5350*5113495bSYour Name 	score_param->rssi_scoring.good_rssi_pcnt =
5351*5113495bSYour Name 		ap_profile->param.rssi_scoring.good_rssi_pcnt;
5352*5113495bSYour Name 	score_param->rssi_scoring.bad_rssi_pcnt =
5353*5113495bSYour Name 		ap_profile->param.rssi_scoring.bad_rssi_pcnt;
5354*5113495bSYour Name 	score_param->rssi_scoring.good_bucket_size =
5355*5113495bSYour Name 		ap_profile->param.rssi_scoring.good_rssi_bucket_size;
5356*5113495bSYour Name 	score_param->rssi_scoring.bad_bucket_size =
5357*5113495bSYour Name 		ap_profile->param.rssi_scoring.bad_rssi_bucket_size;
5358*5113495bSYour Name 	score_param->rssi_scoring.rssi_pref_5g_rssi_thresh =
5359*5113495bSYour Name 		(-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh;
5360*5113495bSYour Name 
5361*5113495bSYour Name 	wmi_debug("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d",
5362*5113495bSYour Name 		 score_param->rssi_scoring.best_rssi_threshold,
5363*5113495bSYour Name 		 score_param->rssi_scoring.good_rssi_threshold,
5364*5113495bSYour Name 		 score_param->rssi_scoring.bad_rssi_threshold,
5365*5113495bSYour Name 		 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh);
5366*5113495bSYour Name 	wmi_debug("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d",
5367*5113495bSYour Name 		 score_param->rssi_scoring.good_rssi_pcnt,
5368*5113495bSYour Name 		 score_param->rssi_scoring.bad_rssi_pcnt,
5369*5113495bSYour Name 		 score_param->rssi_scoring.good_bucket_size,
5370*5113495bSYour Name 		 score_param->rssi_scoring.bad_bucket_size);
5371*5113495bSYour Name 
5372*5113495bSYour Name 	score_param->esp_qbss_scoring.num_slot =
5373*5113495bSYour Name 			ap_profile->param.esp_qbss_scoring.num_slot;
5374*5113495bSYour Name 	score_param->esp_qbss_scoring.score_pcnt3_to_0 =
5375*5113495bSYour Name 			ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0;
5376*5113495bSYour Name 	score_param->esp_qbss_scoring.score_pcnt7_to_4 =
5377*5113495bSYour Name 			ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4;
5378*5113495bSYour Name 	score_param->esp_qbss_scoring.score_pcnt11_to_8 =
5379*5113495bSYour Name 			ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8;
5380*5113495bSYour Name 	score_param->esp_qbss_scoring.score_pcnt15_to_12 =
5381*5113495bSYour Name 			ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12;
5382*5113495bSYour Name 
5383*5113495bSYour Name 	wmi_debug("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
5384*5113495bSYour Name 		 score_param->esp_qbss_scoring.num_slot,
5385*5113495bSYour Name 		 score_param->esp_qbss_scoring.score_pcnt3_to_0,
5386*5113495bSYour Name 		 score_param->esp_qbss_scoring.score_pcnt7_to_4,
5387*5113495bSYour Name 		 score_param->esp_qbss_scoring.score_pcnt11_to_8,
5388*5113495bSYour Name 		 score_param->esp_qbss_scoring.score_pcnt15_to_12);
5389*5113495bSYour Name 
5390*5113495bSYour Name 	score_param->oce_wan_scoring.num_slot =
5391*5113495bSYour Name 			ap_profile->param.oce_wan_scoring.num_slot;
5392*5113495bSYour Name 	score_param->oce_wan_scoring.score_pcnt3_to_0 =
5393*5113495bSYour Name 			ap_profile->param.oce_wan_scoring.score_pcnt3_to_0;
5394*5113495bSYour Name 	score_param->oce_wan_scoring.score_pcnt7_to_4 =
5395*5113495bSYour Name 			ap_profile->param.oce_wan_scoring.score_pcnt7_to_4;
5396*5113495bSYour Name 	score_param->oce_wan_scoring.score_pcnt11_to_8 =
5397*5113495bSYour Name 			ap_profile->param.oce_wan_scoring.score_pcnt11_to_8;
5398*5113495bSYour Name 	score_param->oce_wan_scoring.score_pcnt15_to_12 =
5399*5113495bSYour Name 			ap_profile->param.oce_wan_scoring.score_pcnt15_to_12;
5400*5113495bSYour Name 
5401*5113495bSYour Name 	wmi_debug("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
5402*5113495bSYour Name 		 score_param->oce_wan_scoring.num_slot,
5403*5113495bSYour Name 		 score_param->oce_wan_scoring.score_pcnt3_to_0,
5404*5113495bSYour Name 		 score_param->oce_wan_scoring.score_pcnt7_to_4,
5405*5113495bSYour Name 		 score_param->oce_wan_scoring.score_pcnt11_to_8,
5406*5113495bSYour Name 		 score_param->oce_wan_scoring.score_pcnt15_to_12);
5407*5113495bSYour Name 
5408*5113495bSYour Name 	score_param->roam_score_delta_pcnt = ap_profile->param.roam_score_delta;
5409*5113495bSYour Name 	score_param->roam_score_delta_mask =
5410*5113495bSYour Name 				ap_profile->param.roam_trigger_bitmap;
5411*5113495bSYour Name 	score_param->candidate_min_roam_score_delta =
5412*5113495bSYour Name 				ap_profile->param.cand_min_roam_score_delta;
5413*5113495bSYour Name 	wmi_debug("Roam score delta:%d Roam_trigger_bitmap:%x cand min score delta = %d",
5414*5113495bSYour Name 		 score_param->roam_score_delta_pcnt,
5415*5113495bSYour Name 		 score_param->roam_score_delta_mask,
5416*5113495bSYour Name 		 score_param->candidate_min_roam_score_delta);
5417*5113495bSYour Name 
5418*5113495bSYour Name 	buf_ptr += sizeof(*score_param);
5419*5113495bSYour Name 
5420*5113495bSYour Name 	if (!wmi_service_enabled(wmi_handle,
5421*5113495bSYour Name 			wmi_service_configure_roam_trigger_param_support)) {
5422*5113495bSYour Name 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5423*5113495bSYour Name 			       (NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param)));
5424*5113495bSYour Name 		buf_ptr += WMI_TLV_HDR_SIZE;
5425*5113495bSYour Name 
5426*5113495bSYour Name 		score_delta_param = (wmi_roam_score_delta_param *)buf_ptr;
5427*5113495bSYour Name 		WMITLV_SET_HDR(&score_delta_param->tlv_header,
5428*5113495bSYour Name 			       WMITLV_TAG_STRUC_wmi_roam_score_delta_param,
5429*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_score_delta_param));
5430*5113495bSYour Name 		trig_reason =
5431*5113495bSYour Name 			ap_profile->score_delta_param[IDLE_ROAM_TRIGGER].trigger_reason;
5432*5113495bSYour Name 		score_delta_param->roam_trigger_reason =
5433*5113495bSYour Name 			convert_roam_trigger_reason(trig_reason);
5434*5113495bSYour Name 		score_delta_param->roam_score_delta =
5435*5113495bSYour Name 			ap_profile->score_delta_param[IDLE_ROAM_TRIGGER].roam_score_delta;
5436*5113495bSYour Name 
5437*5113495bSYour Name 		buf_ptr += sizeof(*score_delta_param);
5438*5113495bSYour Name 		score_delta_param = (wmi_roam_score_delta_param *)buf_ptr;
5439*5113495bSYour Name 		WMITLV_SET_HDR(&score_delta_param->tlv_header,
5440*5113495bSYour Name 			       WMITLV_TAG_STRUC_wmi_roam_score_delta_param,
5441*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_score_delta_param));
5442*5113495bSYour Name 		trig_reason =
5443*5113495bSYour Name 			ap_profile->score_delta_param[BTM_ROAM_TRIGGER].trigger_reason;
5444*5113495bSYour Name 		score_delta_param->roam_trigger_reason =
5445*5113495bSYour Name 			convert_roam_trigger_reason(trig_reason);
5446*5113495bSYour Name 		score_delta_param->roam_score_delta =
5447*5113495bSYour Name 			ap_profile->score_delta_param[BTM_ROAM_TRIGGER].roam_score_delta;
5448*5113495bSYour Name 
5449*5113495bSYour Name 		buf_ptr += sizeof(*score_delta_param);
5450*5113495bSYour Name 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5451*5113495bSYour Name 			       (NUM_OF_ROAM_MIN_RSSI * sizeof(*min_rssi_param)));
5452*5113495bSYour Name 		buf_ptr += WMI_TLV_HDR_SIZE;
5453*5113495bSYour Name 
5454*5113495bSYour Name 		min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr;
5455*5113495bSYour Name 		WMITLV_SET_HDR(&min_rssi_param->tlv_header,
5456*5113495bSYour Name 			       WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param,
5457*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param));
5458*5113495bSYour Name 		trig_reason =
5459*5113495bSYour Name 			ap_profile->min_rssi_params[DEAUTH_MIN_RSSI].trigger_reason;
5460*5113495bSYour Name 		min_rssi_param->roam_trigger_reason =
5461*5113495bSYour Name 			convert_roam_trigger_reason(trig_reason);
5462*5113495bSYour Name 		min_rssi_param->candidate_min_rssi =
5463*5113495bSYour Name 			ap_profile->min_rssi_params[DEAUTH_MIN_RSSI].min_rssi;
5464*5113495bSYour Name 
5465*5113495bSYour Name 		buf_ptr += sizeof(*min_rssi_param);
5466*5113495bSYour Name 		min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr;
5467*5113495bSYour Name 		WMITLV_SET_HDR(&min_rssi_param->tlv_header,
5468*5113495bSYour Name 			       WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param,
5469*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param));
5470*5113495bSYour Name 		trig_reason =
5471*5113495bSYour Name 			ap_profile->min_rssi_params[BMISS_MIN_RSSI].trigger_reason;
5472*5113495bSYour Name 		min_rssi_param->roam_trigger_reason =
5473*5113495bSYour Name 			convert_roam_trigger_reason(trig_reason);
5474*5113495bSYour Name 		min_rssi_param->candidate_min_rssi =
5475*5113495bSYour Name 			ap_profile->min_rssi_params[BMISS_MIN_RSSI].min_rssi;
5476*5113495bSYour Name 
5477*5113495bSYour Name 		buf_ptr += sizeof(*min_rssi_param);
5478*5113495bSYour Name 		min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr;
5479*5113495bSYour Name 		WMITLV_SET_HDR(&min_rssi_param->tlv_header,
5480*5113495bSYour Name 			       WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param,
5481*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param));
5482*5113495bSYour Name 		trig_reason =
5483*5113495bSYour Name 		     ap_profile->min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM].trigger_reason;
5484*5113495bSYour Name 		min_rssi_param->roam_trigger_reason =
5485*5113495bSYour Name 			convert_roam_trigger_reason(trig_reason);
5486*5113495bSYour Name 		min_rssi_param->candidate_min_rssi =
5487*5113495bSYour Name 			ap_profile->min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM].min_rssi;
5488*5113495bSYour Name 
5489*5113495bSYour Name 		buf_ptr += sizeof(*min_rssi_param);
5490*5113495bSYour Name 	} else {
5491*5113495bSYour Name 		/* set zero TLV's for roam_score_delta_param_list */
5492*5113495bSYour Name 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5493*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(0));
5494*5113495bSYour Name 		buf_ptr += WMI_TLV_HDR_SIZE;
5495*5113495bSYour Name 
5496*5113495bSYour Name 		/* set zero TLV's for roam_cnd_min_rssi_param_list */
5497*5113495bSYour Name 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5498*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(0));
5499*5113495bSYour Name 		buf_ptr += WMI_TLV_HDR_SIZE;
5500*5113495bSYour Name 	}
5501*5113495bSYour Name 
5502*5113495bSYour Name 	/* set zero TLV's for roam_cnd_vendor_scoring_param */
5503*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5504*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(0));
5505*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
5506*5113495bSYour Name 
5507*5113495bSYour Name 	if (ap_profile->owe_ap_profile.is_owe_transition_conn) {
5508*5113495bSYour Name 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5509*5113495bSYour Name 			       sizeof(*owe_ap_profile));
5510*5113495bSYour Name 		buf_ptr += WMI_TLV_HDR_SIZE;
5511*5113495bSYour Name 
5512*5113495bSYour Name 		owe_ap_profile = (wmi_owe_ap_profile *)buf_ptr;
5513*5113495bSYour Name 		ssid = &owe_ap_profile->open_ssid_for_owe_transition;
5514*5113495bSYour Name 		WMITLV_SET_HDR(&owe_ap_profile->tlv_header,
5515*5113495bSYour Name 			       WMITLV_TAG_STRUC_wmi_owe_ap_profile,
5516*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(wmi_owe_ap_profile));
5517*5113495bSYour Name 
5518*5113495bSYour Name 		ssid->ssid_len = ap_profile->owe_ap_profile.ssid.length;
5519*5113495bSYour Name 		qdf_mem_copy(ssid->ssid,
5520*5113495bSYour Name 			     ap_profile->owe_ap_profile.ssid.ssid,
5521*5113495bSYour Name 			     ap_profile->owe_ap_profile.ssid.length);
5522*5113495bSYour Name 		wmi_debug("[OWE_TRANSITION]: open ssid:" QDF_SSID_FMT,
5523*5113495bSYour Name 			  QDF_SSID_REF(ssid->ssid_len, (char *)ssid->ssid));
5524*5113495bSYour Name 
5525*5113495bSYour Name 		buf_ptr += sizeof(*owe_ap_profile);
5526*5113495bSYour Name 	} else {
5527*5113495bSYour Name 		/* set zero TLV's for owe_ap_profile */
5528*5113495bSYour Name 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5529*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(0));
5530*5113495bSYour Name 		buf_ptr += WMI_TLV_HDR_SIZE;
5531*5113495bSYour Name 	}
5532*5113495bSYour Name 
5533*5113495bSYour Name 	/* List of Allowed authmode other than the connected akm */
5534*5113495bSYour Name 	if (ap_profile->profile.num_allowed_authmode) {
5535*5113495bSYour Name 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
5536*5113495bSYour Name 			       (ap_profile->profile.num_allowed_authmode *
5537*5113495bSYour Name 			       sizeof(uint32_t)));
5538*5113495bSYour Name 
5539*5113495bSYour Name 		buf_ptr += WMI_TLV_HDR_SIZE;
5540*5113495bSYour Name 
5541*5113495bSYour Name 		authmode_list = (uint32_t *)buf_ptr;
5542*5113495bSYour Name 		for (i = 0; i < ap_profile->profile.num_allowed_authmode; i++)
5543*5113495bSYour Name 			authmode_list[i] =
5544*5113495bSYour Name 				ap_profile->profile.allowed_authmode[i];
5545*5113495bSYour Name 
5546*5113495bSYour Name 		wmi_debug("[Allowed Authmode]: num_allowed_authmode: %d",
5547*5113495bSYour Name 			  ap_profile->profile.num_allowed_authmode);
5548*5113495bSYour Name 		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
5549*5113495bSYour Name 				   authmode_list,
5550*5113495bSYour Name 				   ap_profile->profile.num_allowed_authmode *
5551*5113495bSYour Name 				   sizeof(uint32_t));
5552*5113495bSYour Name 	} else {
5553*5113495bSYour Name 		/* set zero TLV's for allowed_authmode */
5554*5113495bSYour Name 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5555*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(0));
5556*5113495bSYour Name 		buf_ptr += WMI_TLV_HDR_SIZE;
5557*5113495bSYour Name 	}
5558*5113495bSYour Name 
5559*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0);
5560*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf,
5561*5113495bSYour Name 				      len, WMI_ROAM_AP_PROFILE);
5562*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
5563*5113495bSYour Name 		wmi_buf_free(buf);
5564*5113495bSYour Name 
5565*5113495bSYour Name 	return status;
5566*5113495bSYour Name }
5567*5113495bSYour Name 
5568*5113495bSYour Name /**
5569*5113495bSYour Name  * send_roam_scan_offload_cmd_tlv() - set roam offload command
5570*5113495bSYour Name  * @wmi_handle: wmi handle
5571*5113495bSYour Name  * @command: command
5572*5113495bSYour Name  * @vdev_id: vdev id
5573*5113495bSYour Name  *
5574*5113495bSYour Name  * This function set roam offload command to fw.
5575*5113495bSYour Name  *
5576*5113495bSYour Name  * Return: QDF status
5577*5113495bSYour Name  */
5578*5113495bSYour Name static QDF_STATUS
send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle,uint32_t command,uint32_t vdev_id)5579*5113495bSYour Name send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle,
5580*5113495bSYour Name 			       uint32_t command, uint32_t vdev_id)
5581*5113495bSYour Name {
5582*5113495bSYour Name 	QDF_STATUS status;
5583*5113495bSYour Name 	wmi_roam_scan_cmd_fixed_param *cmd_fp;
5584*5113495bSYour Name 	wmi_buf_t buf = NULL;
5585*5113495bSYour Name 	int len;
5586*5113495bSYour Name 	uint8_t *buf_ptr;
5587*5113495bSYour Name 
5588*5113495bSYour Name 	len = sizeof(wmi_roam_scan_cmd_fixed_param);
5589*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
5590*5113495bSYour Name 	if (!buf)
5591*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5592*5113495bSYour Name 
5593*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
5594*5113495bSYour Name 
5595*5113495bSYour Name 	cmd_fp = (wmi_roam_scan_cmd_fixed_param *)buf_ptr;
5596*5113495bSYour Name 	WMITLV_SET_HDR(&cmd_fp->tlv_header,
5597*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param,
5598*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param));
5599*5113495bSYour Name 	cmd_fp->vdev_id = vdev_id;
5600*5113495bSYour Name 	cmd_fp->command_arg = command;
5601*5113495bSYour Name 
5602*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_SCAN_CMD, NO_SESSION, 0);
5603*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf,
5604*5113495bSYour Name 				      len, WMI_ROAM_SCAN_CMD);
5605*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
5606*5113495bSYour Name 		goto error;
5607*5113495bSYour Name 
5608*5113495bSYour Name 	wmi_info("WMI --> WMI_ROAM_SCAN_CMD");
5609*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5610*5113495bSYour Name 
5611*5113495bSYour Name error:
5612*5113495bSYour Name 	wmi_buf_free(buf);
5613*5113495bSYour Name 
5614*5113495bSYour Name 	return status;
5615*5113495bSYour Name }
5616*5113495bSYour Name 
5617*5113495bSYour Name /**
5618*5113495bSYour Name  * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list
5619*5113495bSYour Name  * @wmi_handle: wmi handle
5620*5113495bSYour Name  * @rso_ch_info: Roam offload channel information
5621*5113495bSYour Name  *
5622*5113495bSYour Name  * Set roam offload channel list.
5623*5113495bSYour Name  *
5624*5113495bSYour Name  * Return: QDF status
5625*5113495bSYour Name  */
send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle,struct wlan_roam_scan_channel_list * rso_ch_info)5626*5113495bSYour Name static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(
5627*5113495bSYour Name 			wmi_unified_t wmi_handle,
5628*5113495bSYour Name 			struct wlan_roam_scan_channel_list *rso_ch_info)
5629*5113495bSYour Name {
5630*5113495bSYour Name 	wmi_buf_t buf = NULL;
5631*5113495bSYour Name 	QDF_STATUS status;
5632*5113495bSYour Name 	int len, list_tlv_len;
5633*5113495bSYour Name 	int i;
5634*5113495bSYour Name 	uint8_t *buf_ptr;
5635*5113495bSYour Name 	wmi_roam_chan_list_fixed_param *chan_list_fp;
5636*5113495bSYour Name 	uint32_t *roam_chan_list_array;
5637*5113495bSYour Name 	uint8_t chan_count = rso_ch_info->chan_count;
5638*5113495bSYour Name 	uint32_t *chan_list = rso_ch_info->chan_freq_list;
5639*5113495bSYour Name 
5640*5113495bSYour Name 	/* Channel list is a table of 2 TLV's */
5641*5113495bSYour Name 	list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t);
5642*5113495bSYour Name 	len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len;
5643*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
5644*5113495bSYour Name 	if (!buf)
5645*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5646*5113495bSYour Name 
5647*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
5648*5113495bSYour Name 	chan_list_fp = (wmi_roam_chan_list_fixed_param *)buf_ptr;
5649*5113495bSYour Name 	WMITLV_SET_HDR(&chan_list_fp->tlv_header,
5650*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param,
5651*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
5652*5113495bSYour Name 			       (wmi_roam_chan_list_fixed_param));
5653*5113495bSYour Name 	chan_list_fp->vdev_id = rso_ch_info->vdev_id;
5654*5113495bSYour Name 	chan_list_fp->num_chan = chan_count;
5655*5113495bSYour Name 	if (rso_ch_info->chan_cache_type == WMI_CHANNEL_LIST_STATIC)
5656*5113495bSYour Name 		/* external app is controlling channel list */
5657*5113495bSYour Name 		chan_list_fp->chan_list_type =
5658*5113495bSYour Name 			WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC;
5659*5113495bSYour Name 	else
5660*5113495bSYour Name 		/* umac supplied occupied channel list in LFR */
5661*5113495bSYour Name 		chan_list_fp->chan_list_type =
5662*5113495bSYour Name 			WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC;
5663*5113495bSYour Name 
5664*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_chan_list_fixed_param);
5665*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
5666*5113495bSYour Name 		       (chan_list_fp->num_chan * sizeof(uint32_t)));
5667*5113495bSYour Name 	roam_chan_list_array = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
5668*5113495bSYour Name 	for (i = 0; ((i < chan_list_fp->num_chan) &&
5669*5113495bSYour Name 		     (i < WMI_ROAM_MAX_CHANNELS)); i++)
5670*5113495bSYour Name 		roam_chan_list_array[i] = chan_list[i];
5671*5113495bSYour Name 
5672*5113495bSYour Name 	wmi_debug("RSO_CFG: vdev:%d num_chan:%d cache_type:%d",
5673*5113495bSYour Name 		  chan_list_fp->vdev_id, chan_list_fp->num_chan,
5674*5113495bSYour Name 		  rso_ch_info->chan_cache_type);
5675*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_CHAN_LIST, NO_SESSION, 0);
5676*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf,
5677*5113495bSYour Name 				      len, WMI_ROAM_CHAN_LIST);
5678*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
5679*5113495bSYour Name 		goto error;
5680*5113495bSYour Name 
5681*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5682*5113495bSYour Name error:
5683*5113495bSYour Name 	wmi_buf_free(buf);
5684*5113495bSYour Name 
5685*5113495bSYour Name 	return status;
5686*5113495bSYour Name }
5687*5113495bSYour Name 
5688*5113495bSYour Name /**
5689*5113495bSYour Name  * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th
5690*5113495bSYour Name  * @wmi_handle: wmi handle
5691*5113495bSYour Name  * @params: RSSI change parameters
5692*5113495bSYour Name  *
5693*5113495bSYour Name  * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
5694*5113495bSYour Name  *
5695*5113495bSYour Name  * Return: CDF status
5696*5113495bSYour Name  */
send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle,struct wlan_roam_rssi_change_params * params)5697*5113495bSYour Name static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(
5698*5113495bSYour Name 		wmi_unified_t wmi_handle,
5699*5113495bSYour Name 		struct wlan_roam_rssi_change_params *params)
5700*5113495bSYour Name {
5701*5113495bSYour Name 	wmi_buf_t buf = NULL;
5702*5113495bSYour Name 	QDF_STATUS status;
5703*5113495bSYour Name 	int len;
5704*5113495bSYour Name 	uint8_t *buf_ptr;
5705*5113495bSYour Name 	wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp;
5706*5113495bSYour Name 
5707*5113495bSYour Name 	/* Send rssi change parameters */
5708*5113495bSYour Name 	len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param);
5709*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
5710*5113495bSYour Name 	if (!buf)
5711*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5712*5113495bSYour Name 
5713*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
5714*5113495bSYour Name 	rssi_change_fp =
5715*5113495bSYour Name 		(wmi_roam_scan_rssi_change_threshold_fixed_param *)buf_ptr;
5716*5113495bSYour Name 	WMITLV_SET_HDR(&rssi_change_fp->tlv_header,
5717*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param,
5718*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN
5719*5113495bSYour Name 		       (wmi_roam_scan_rssi_change_threshold_fixed_param));
5720*5113495bSYour Name 	/* fill in rssi change threshold (hysteresis) values */
5721*5113495bSYour Name 	rssi_change_fp->vdev_id = params->vdev_id;
5722*5113495bSYour Name 	rssi_change_fp->roam_scan_rssi_change_thresh =
5723*5113495bSYour Name 				params->rssi_change_thresh;
5724*5113495bSYour Name 	rssi_change_fp->bcn_rssi_weight = params->bcn_rssi_weight;
5725*5113495bSYour Name 	rssi_change_fp->hirssi_delay_btw_scans = params->hirssi_delay_btw_scans;
5726*5113495bSYour Name 
5727*5113495bSYour Name 	wmi_nofl_debug("RSO_CFG: vdev %d rssi_change_thresh:%d bcn_rssi_weight:%d hirssi_delay_btw_scans:%d",
5728*5113495bSYour Name 		       rssi_change_fp->vdev_id,
5729*5113495bSYour Name 		       rssi_change_fp->roam_scan_rssi_change_thresh,
5730*5113495bSYour Name 		       rssi_change_fp->bcn_rssi_weight,
5731*5113495bSYour Name 		       rssi_change_fp->hirssi_delay_btw_scans);
5732*5113495bSYour Name 
5733*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
5734*5113495bSYour Name 		   rssi_change_fp->vdev_id, 0);
5735*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
5736*5113495bSYour Name 				      WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD);
5737*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
5738*5113495bSYour Name 		goto error;
5739*5113495bSYour Name 
5740*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5741*5113495bSYour Name error:
5742*5113495bSYour Name 	wmi_buf_free(buf);
5743*5113495bSYour Name 
5744*5113495bSYour Name 	return status;
5745*5113495bSYour Name }
5746*5113495bSYour Name 
5747*5113495bSYour Name /**
5748*5113495bSYour Name  * send_per_roam_config_cmd_tlv() - set per roaming config to FW
5749*5113495bSYour Name  * @wmi_handle: wmi handle
5750*5113495bSYour Name  * @req_buf: per roam config buffer
5751*5113495bSYour Name  *
5752*5113495bSYour Name  * Return: QDF status
5753*5113495bSYour Name  */
5754*5113495bSYour Name static QDF_STATUS
send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle,struct wlan_per_roam_config_req * req_buf)5755*5113495bSYour Name send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle,
5756*5113495bSYour Name 			     struct wlan_per_roam_config_req *req_buf)
5757*5113495bSYour Name {
5758*5113495bSYour Name 	wmi_buf_t buf = NULL;
5759*5113495bSYour Name 	QDF_STATUS status;
5760*5113495bSYour Name 	int len;
5761*5113495bSYour Name 	uint8_t *buf_ptr;
5762*5113495bSYour Name 	wmi_roam_per_config_fixed_param *wmi_per_config;
5763*5113495bSYour Name 
5764*5113495bSYour Name 	len = sizeof(wmi_roam_per_config_fixed_param);
5765*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
5766*5113495bSYour Name 	if (!buf)
5767*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5768*5113495bSYour Name 
5769*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
5770*5113495bSYour Name 	wmi_per_config =
5771*5113495bSYour Name 		(wmi_roam_per_config_fixed_param *)buf_ptr;
5772*5113495bSYour Name 	WMITLV_SET_HDR(&wmi_per_config->tlv_header,
5773*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param,
5774*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
5775*5113495bSYour Name 		       (wmi_roam_per_config_fixed_param));
5776*5113495bSYour Name 
5777*5113495bSYour Name 	/* fill in per roam config values */
5778*5113495bSYour Name 	wmi_per_config->vdev_id = req_buf->vdev_id;
5779*5113495bSYour Name 
5780*5113495bSYour Name 	wmi_per_config->enable = req_buf->per_config.enable;
5781*5113495bSYour Name 	wmi_per_config->high_rate_thresh =
5782*5113495bSYour Name 		(req_buf->per_config.tx_high_rate_thresh << 16) |
5783*5113495bSYour Name 		(req_buf->per_config.rx_high_rate_thresh & 0x0000ffff);
5784*5113495bSYour Name 	wmi_per_config->low_rate_thresh =
5785*5113495bSYour Name 		(req_buf->per_config.tx_low_rate_thresh << 16) |
5786*5113495bSYour Name 		(req_buf->per_config.rx_low_rate_thresh & 0x0000ffff);
5787*5113495bSYour Name 	wmi_per_config->pkt_err_rate_thresh_pct =
5788*5113495bSYour Name 		(req_buf->per_config.tx_rate_thresh_percnt << 16) |
5789*5113495bSYour Name 		(req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff);
5790*5113495bSYour Name 	wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time;
5791*5113495bSYour Name 	wmi_per_config->pkt_err_rate_mon_time =
5792*5113495bSYour Name 			(req_buf->per_config.tx_per_mon_time << 16) |
5793*5113495bSYour Name 			(req_buf->per_config.rx_per_mon_time & 0x0000ffff);
5794*5113495bSYour Name 	wmi_per_config->min_candidate_rssi =
5795*5113495bSYour Name 			req_buf->per_config.min_candidate_rssi;
5796*5113495bSYour Name 
5797*5113495bSYour Name 	/* Send per roam config parameters */
5798*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_PER_CONFIG_CMDID, NO_SESSION, 0);
5799*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf,
5800*5113495bSYour Name 				      len, WMI_ROAM_PER_CONFIG_CMDID);
5801*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
5802*5113495bSYour Name 		wmi_err("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d", status);
5803*5113495bSYour Name 		wmi_buf_free(buf);
5804*5113495bSYour Name 		return status;
5805*5113495bSYour Name 	}
5806*5113495bSYour Name 	wmi_debug("per roam enable=%d, vdev=%d",
5807*5113495bSYour Name 		 req_buf->per_config.enable, req_buf->vdev_id);
5808*5113495bSYour Name 
5809*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5810*5113495bSYour Name }
5811*5113495bSYour Name 
5812*5113495bSYour Name /**
5813*5113495bSYour Name  * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan
5814*5113495bSYour Name  * configuration params
5815*5113495bSYour Name  * @wmi_handle: wmi handler
5816*5113495bSYour Name  * @limit_off_chan_param: pointer to wmi_off_chan_param
5817*5113495bSYour Name  *
5818*5113495bSYour Name  * Return: 0 for success and non zero for failure
5819*5113495bSYour Name  */
send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle,struct wmi_limit_off_chan_param * limit_off_chan_param)5820*5113495bSYour Name static QDF_STATUS send_limit_off_chan_cmd_tlv(
5821*5113495bSYour Name 			wmi_unified_t wmi_handle,
5822*5113495bSYour Name 			struct wmi_limit_off_chan_param *limit_off_chan_param)
5823*5113495bSYour Name {
5824*5113495bSYour Name 	wmi_vdev_limit_offchan_cmd_fixed_param *cmd;
5825*5113495bSYour Name 	wmi_buf_t buf;
5826*5113495bSYour Name 	uint32_t len = sizeof(*cmd);
5827*5113495bSYour Name 	int err;
5828*5113495bSYour Name 
5829*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
5830*5113495bSYour Name 	if (!buf)
5831*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5832*5113495bSYour Name 
5833*5113495bSYour Name 	cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf);
5834*5113495bSYour Name 
5835*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
5836*5113495bSYour Name 			WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param,
5837*5113495bSYour Name 			WMITLV_GET_STRUCT_TLVLEN(
5838*5113495bSYour Name 				wmi_vdev_limit_offchan_cmd_fixed_param));
5839*5113495bSYour Name 
5840*5113495bSYour Name 	cmd->vdev_id = limit_off_chan_param->vdev_id;
5841*5113495bSYour Name 
5842*5113495bSYour Name 	cmd->flags &= 0;
5843*5113495bSYour Name 	if (limit_off_chan_param->status)
5844*5113495bSYour Name 		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE;
5845*5113495bSYour Name 	if (limit_off_chan_param->skip_dfs_chans)
5846*5113495bSYour Name 		cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS;
5847*5113495bSYour Name 
5848*5113495bSYour Name 	cmd->max_offchan_time = limit_off_chan_param->max_offchan_time;
5849*5113495bSYour Name 	cmd->rest_time = limit_off_chan_param->rest_time;
5850*5113495bSYour Name 
5851*5113495bSYour Name 	wmi_debug("vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d",
5852*5113495bSYour Name 		 cmd->vdev_id, cmd->flags, cmd->max_offchan_time,
5853*5113495bSYour Name 		 cmd->rest_time);
5854*5113495bSYour Name 
5855*5113495bSYour Name 	wmi_mtrace(WMI_VDEV_LIMIT_OFFCHAN_CMDID, cmd->vdev_id, 0);
5856*5113495bSYour Name 	err = wmi_unified_cmd_send(wmi_handle, buf,
5857*5113495bSYour Name 				   len, WMI_VDEV_LIMIT_OFFCHAN_CMDID);
5858*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(err)) {
5859*5113495bSYour Name 		wmi_err("Failed to send limit off chan cmd err=%d", err);
5860*5113495bSYour Name 		wmi_buf_free(buf);
5861*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5862*5113495bSYour Name 	}
5863*5113495bSYour Name 
5864*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5865*5113495bSYour Name }
5866*5113495bSYour Name 
5867*5113495bSYour Name #ifdef WLAN_FEATURE_FILS_SK
send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle,struct hlp_params * params)5868*5113495bSYour Name static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle,
5869*5113495bSYour Name 						  struct hlp_params *params)
5870*5113495bSYour Name {
5871*5113495bSYour Name 	uint32_t len;
5872*5113495bSYour Name 	uint8_t *buf_ptr;
5873*5113495bSYour Name 	wmi_buf_t buf = NULL;
5874*5113495bSYour Name 	wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params;
5875*5113495bSYour Name 
5876*5113495bSYour Name 	len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param);
5877*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE;
5878*5113495bSYour Name 	len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t));
5879*5113495bSYour Name 
5880*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
5881*5113495bSYour Name 	if (!buf)
5882*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5883*5113495bSYour Name 
5884*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
5885*5113495bSYour Name 	hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *)buf_ptr;
5886*5113495bSYour Name 	WMITLV_SET_HDR(&hlp_params->tlv_header,
5887*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param,
5888*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
5889*5113495bSYour Name 			wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param));
5890*5113495bSYour Name 
5891*5113495bSYour Name 	hlp_params->vdev_id = params->vdev_id;
5892*5113495bSYour Name 	hlp_params->size = params->hlp_ie_len;
5893*5113495bSYour Name 	hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER;
5894*5113495bSYour Name 
5895*5113495bSYour Name 	buf_ptr += sizeof(*hlp_params);
5896*5113495bSYour Name 
5897*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5898*5113495bSYour Name 		       round_up(params->hlp_ie_len, sizeof(uint32_t)));
5899*5113495bSYour Name 
5900*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
5901*5113495bSYour Name 	qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len);
5902*5113495bSYour Name 
5903*5113495bSYour Name 	wmi_debug("send FILS HLP pkt vdev %d len %d",
5904*5113495bSYour Name 		 hlp_params->vdev_id, hlp_params->size);
5905*5113495bSYour Name 	wmi_mtrace(WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID, NO_SESSION, 0);
5906*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
5907*5113495bSYour Name 				 WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) {
5908*5113495bSYour Name 		wmi_err("Failed to send FILS HLP pkt cmd");
5909*5113495bSYour Name 		wmi_buf_free(buf);
5910*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5911*5113495bSYour Name 	}
5912*5113495bSYour Name 
5913*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5914*5113495bSYour Name }
5915*5113495bSYour Name 
wmi_fils_sk_attach_tlv(wmi_unified_t wmi_handle)5916*5113495bSYour Name void wmi_fils_sk_attach_tlv(wmi_unified_t wmi_handle)
5917*5113495bSYour Name {
5918*5113495bSYour Name 	struct wmi_ops *ops = wmi_handle->ops;
5919*5113495bSYour Name 
5920*5113495bSYour Name 	ops->send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv;
5921*5113495bSYour Name }
5922*5113495bSYour Name #endif /* WLAN_FEATURE_FILS_SK */
5923*5113495bSYour Name 
5924*5113495bSYour Name /*
5925*5113495bSYour Name  * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config
5926*5113495bSYour Name  * @wmi_handle: wmi handle
5927*5113495bSYour Name  * @params: pointer to wlan_roam_btm_config
5928*5113495bSYour Name  *
5929*5113495bSYour Name  * Return: QDF_STATUS
5930*5113495bSYour Name  */
send_btm_config_cmd_tlv(wmi_unified_t wmi_handle,struct wlan_roam_btm_config * params)5931*5113495bSYour Name static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle,
5932*5113495bSYour Name 					  struct wlan_roam_btm_config *params)
5933*5113495bSYour Name {
5934*5113495bSYour Name 	wmi_btm_config_fixed_param *cmd;
5935*5113495bSYour Name 	wmi_buf_t buf;
5936*5113495bSYour Name 	uint32_t len;
5937*5113495bSYour Name 
5938*5113495bSYour Name 	len = sizeof(*cmd);
5939*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
5940*5113495bSYour Name 	if (!buf)
5941*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5942*5113495bSYour Name 
5943*5113495bSYour Name 	cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf);
5944*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
5945*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_btm_config_fixed_param,
5946*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param));
5947*5113495bSYour Name 	cmd->vdev_id = params->vdev_id;
5948*5113495bSYour Name 	cmd->flags = params->btm_offload_config;
5949*5113495bSYour Name 	cmd->max_attempt_cnt = params->btm_max_attempt_cnt;
5950*5113495bSYour Name 	cmd->solicited_timeout_ms = params->btm_solicited_timeout;
5951*5113495bSYour Name 	cmd->stick_time_seconds = params->btm_sticky_time;
5952*5113495bSYour Name 	cmd->disassoc_timer_threshold = params->disassoc_timer_threshold;
5953*5113495bSYour Name 	cmd->btm_bitmap = params->btm_query_bitmask;
5954*5113495bSYour Name 	cmd->btm_candidate_min_score = params->btm_candidate_min_score;
5955*5113495bSYour Name 
5956*5113495bSYour Name 	wmi_debug("RSO_CFG: vdev_id:%u btm_offload:%u btm_query_bitmask:%u btm_candidate_min_score:%u",
5957*5113495bSYour Name 		  cmd->vdev_id, cmd->flags, cmd->btm_bitmap,
5958*5113495bSYour Name 		  cmd->btm_candidate_min_score);
5959*5113495bSYour Name 	wmi_debug("RSO_CFG: btm_solicited_timeout:%u btm_max_attempt_cnt:%u btm_sticky_time:%u disassoc_timer_threshold:%u",
5960*5113495bSYour Name 		  cmd->solicited_timeout_ms, cmd->max_attempt_cnt,
5961*5113495bSYour Name 		  cmd->stick_time_seconds, cmd->disassoc_timer_threshold);
5962*5113495bSYour Name 
5963*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_BTM_CONFIG_CMDID, cmd->vdev_id, 0);
5964*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
5965*5113495bSYour Name 				 WMI_ROAM_BTM_CONFIG_CMDID)) {
5966*5113495bSYour Name 		wmi_err("Failed to send WMI_ROAM_BTM_CONFIG_CMDID");
5967*5113495bSYour Name 		wmi_buf_free(buf);
5968*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5969*5113495bSYour Name 	}
5970*5113495bSYour Name 
5971*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5972*5113495bSYour Name }
5973*5113495bSYour Name 
5974*5113495bSYour Name /**
5975*5113495bSYour Name  * send_roam_bss_load_config_tlv() - send roam load bss trigger configuration
5976*5113495bSYour Name  * @wmi_handle: wmi handle
5977*5113495bSYour Name  * @params: pointer to wlan_roam_bss_load_config
5978*5113495bSYour Name  *
5979*5113495bSYour Name  * This function sends the roam load bss trigger configuration to fw.
5980*5113495bSYour Name  * the bss_load_threshold parameter is used to configure the maximum
5981*5113495bSYour Name  * bss load percentage, above which the firmware should trigger roaming
5982*5113495bSYour Name  *
5983*5113495bSYour Name  * Return: QDF status
5984*5113495bSYour Name  */
5985*5113495bSYour Name static QDF_STATUS
send_roam_bss_load_config_tlv(wmi_unified_t wmi_handle,struct wlan_roam_bss_load_config * params)5986*5113495bSYour Name send_roam_bss_load_config_tlv(wmi_unified_t wmi_handle,
5987*5113495bSYour Name 			      struct wlan_roam_bss_load_config *params)
5988*5113495bSYour Name {
5989*5113495bSYour Name 	wmi_roam_bss_load_config_cmd_fixed_param *cmd;
5990*5113495bSYour Name 	wmi_buf_t buf;
5991*5113495bSYour Name 	uint32_t len;
5992*5113495bSYour Name 
5993*5113495bSYour Name 	len = sizeof(*cmd);
5994*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
5995*5113495bSYour Name 	if (!buf)
5996*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5997*5113495bSYour Name 
5998*5113495bSYour Name 	cmd = (wmi_roam_bss_load_config_cmd_fixed_param *)wmi_buf_data(buf);
5999*5113495bSYour Name 	WMITLV_SET_HDR(
6000*5113495bSYour Name 	    &cmd->tlv_header,
6001*5113495bSYour Name 	    WMITLV_TAG_STRUC_wmi_roam_bss_load_config_cmd_fixed_param,
6002*5113495bSYour Name 	    WMITLV_GET_STRUCT_TLVLEN(wmi_roam_bss_load_config_cmd_fixed_param));
6003*5113495bSYour Name 
6004*5113495bSYour Name 	cmd->vdev_id = params->vdev_id;
6005*5113495bSYour Name 	cmd->bss_load_threshold = params->bss_load_threshold;
6006*5113495bSYour Name 	cmd->monitor_time_window = params->bss_load_sample_time;
6007*5113495bSYour Name 	cmd->rssi_2g_threshold = params->rssi_threshold_24ghz;
6008*5113495bSYour Name 	cmd->rssi_5g_threshold = params->rssi_threshold_5ghz;
6009*5113495bSYour Name 	cmd->rssi_6g_threshold = params->rssi_threshold_6ghz;
6010*5113495bSYour Name 
6011*5113495bSYour Name 	wmi_debug("RSO_CFG: vdev:%d bss_load_thres:%d monitor_time:%d rssi_2g:%d rssi_5g:%d, rssi_6g:%d",
6012*5113495bSYour Name 		  cmd->vdev_id, cmd->bss_load_threshold,
6013*5113495bSYour Name 		  cmd->monitor_time_window, cmd->rssi_2g_threshold,
6014*5113495bSYour Name 		  cmd->rssi_5g_threshold, cmd->rssi_6g_threshold);
6015*5113495bSYour Name 
6016*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_BSS_LOAD_CONFIG_CMDID, cmd->vdev_id, 0);
6017*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
6018*5113495bSYour Name 				 WMI_ROAM_BSS_LOAD_CONFIG_CMDID)) {
6019*5113495bSYour Name 		wmi_err("Failed to send WMI_ROAM_BSS_LOAD_CONFIG_CMDID");
6020*5113495bSYour Name 		wmi_buf_free(buf);
6021*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6022*5113495bSYour Name 	}
6023*5113495bSYour Name 
6024*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6025*5113495bSYour Name }
6026*5113495bSYour Name 
6027*5113495bSYour Name #ifdef WLAN_FEATURE_ROAM_OFFLOAD
6028*5113495bSYour Name /**
6029*5113495bSYour Name  * send_disconnect_roam_params_tlv() - send disconnect roam trigger parameters
6030*5113495bSYour Name  * @wmi_handle: wmi handle
6031*5113495bSYour Name  * @req: pointer to wlan_roam_disconnect_params which carries the
6032*5113495bSYour Name  * disconnect_roam_trigger parameters
6033*5113495bSYour Name  *
6034*5113495bSYour Name  * This function sends the disconnect roam trigger parameters to fw.
6035*5113495bSYour Name  *
6036*5113495bSYour Name  * Return: QDF status
6037*5113495bSYour Name  */
6038*5113495bSYour Name static QDF_STATUS
send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle,struct wlan_roam_disconnect_params * req)6039*5113495bSYour Name send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle,
6040*5113495bSYour Name 				struct wlan_roam_disconnect_params *req)
6041*5113495bSYour Name {
6042*5113495bSYour Name 	wmi_roam_deauth_config_cmd_fixed_param *cmd;
6043*5113495bSYour Name 	wmi_buf_t buf;
6044*5113495bSYour Name 	uint32_t len;
6045*5113495bSYour Name 
6046*5113495bSYour Name 	len = sizeof(*cmd);
6047*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
6048*5113495bSYour Name 	if (!buf)
6049*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
6050*5113495bSYour Name 
6051*5113495bSYour Name 	cmd = (wmi_roam_deauth_config_cmd_fixed_param *)wmi_buf_data(buf);
6052*5113495bSYour Name 	WMITLV_SET_HDR(
6053*5113495bSYour Name 	    &cmd->tlv_header,
6054*5113495bSYour Name 	    WMITLV_TAG_STRUC_wmi_roam_deauth_config_cmd_fixed_param,
6055*5113495bSYour Name 	    WMITLV_GET_STRUCT_TLVLEN(wmi_roam_deauth_config_cmd_fixed_param));
6056*5113495bSYour Name 
6057*5113495bSYour Name 	cmd->vdev_id = req->vdev_id;
6058*5113495bSYour Name 	cmd->enable = req->enable;
6059*5113495bSYour Name 	wmi_debug("RSO_CFG: vdev_id:%d enable:%d", cmd->vdev_id, cmd->enable);
6060*5113495bSYour Name 
6061*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_DEAUTH_CONFIG_CMDID, cmd->vdev_id, 0);
6062*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
6063*5113495bSYour Name 				 WMI_ROAM_DEAUTH_CONFIG_CMDID)) {
6064*5113495bSYour Name 		wmi_err("Failed to send WMI_ROAM_DEAUTH_CONFIG_CMDID");
6065*5113495bSYour Name 		wmi_buf_free(buf);
6066*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6067*5113495bSYour Name 	}
6068*5113495bSYour Name 
6069*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6070*5113495bSYour Name }
6071*5113495bSYour Name 
6072*5113495bSYour Name #define WLAN_TIME_IN_MS 1000
6073*5113495bSYour Name /**
6074*5113495bSYour Name  * send_idle_roam_params_tlv() - send idle roam trigger parameters
6075*5113495bSYour Name  * @wmi_handle: wmi handle
6076*5113495bSYour Name  * @idle_roam_params: pointer to wlan_roam_idle_params which carries the
6077*5113495bSYour Name  * idle roam parameters from CSR
6078*5113495bSYour Name  *
6079*5113495bSYour Name  * This function sends the idle roam trigger parameters to fw.
6080*5113495bSYour Name  *
6081*5113495bSYour Name  * Return: QDF status
6082*5113495bSYour Name  */
6083*5113495bSYour Name static QDF_STATUS
send_idle_roam_params_tlv(wmi_unified_t wmi_handle,struct wlan_roam_idle_params * idle_roam_params)6084*5113495bSYour Name send_idle_roam_params_tlv(wmi_unified_t wmi_handle,
6085*5113495bSYour Name 			  struct wlan_roam_idle_params *idle_roam_params)
6086*5113495bSYour Name {
6087*5113495bSYour Name 	wmi_roam_idle_config_cmd_fixed_param *cmd;
6088*5113495bSYour Name 	wmi_buf_t buf;
6089*5113495bSYour Name 	uint32_t len;
6090*5113495bSYour Name 
6091*5113495bSYour Name 	len = sizeof(*cmd);
6092*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
6093*5113495bSYour Name 	if (!buf)
6094*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
6095*5113495bSYour Name 
6096*5113495bSYour Name 	cmd = (wmi_roam_idle_config_cmd_fixed_param *)wmi_buf_data(buf);
6097*5113495bSYour Name 	WMITLV_SET_HDR(
6098*5113495bSYour Name 	    &cmd->tlv_header,
6099*5113495bSYour Name 	    WMITLV_TAG_STRUC_wmi_roam_idle_config_cmd_fixed_param,
6100*5113495bSYour Name 	    WMITLV_GET_STRUCT_TLVLEN(wmi_roam_idle_config_cmd_fixed_param));
6101*5113495bSYour Name 
6102*5113495bSYour Name 	cmd->vdev_id = idle_roam_params->vdev_id;
6103*5113495bSYour Name 	cmd->enable = idle_roam_params->enable;
6104*5113495bSYour Name 	cmd->band = idle_roam_params->band;
6105*5113495bSYour Name 	cmd->rssi_delta = idle_roam_params->conn_ap_rssi_delta;
6106*5113495bSYour Name 	cmd->min_rssi = idle_roam_params->conn_ap_min_rssi;
6107*5113495bSYour Name 	cmd->idle_time = idle_roam_params->inactive_time / WLAN_TIME_IN_MS;
6108*5113495bSYour Name 	cmd->data_packet_count = idle_roam_params->data_pkt_count;
6109*5113495bSYour Name 	wmi_debug("RSO_CFG: vdev_id:%d enable:%d band:%d rssi_delta:%d min_rssi:%d idle_time:%d data_pkt:%d",
6110*5113495bSYour Name 		 cmd->vdev_id, cmd->enable,
6111*5113495bSYour Name 		 cmd->band, cmd->rssi_delta, cmd->min_rssi,
6112*5113495bSYour Name 		 cmd->idle_time, cmd->data_packet_count);
6113*5113495bSYour Name 
6114*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_IDLE_CONFIG_CMDID, cmd->vdev_id, 0);
6115*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
6116*5113495bSYour Name 				 WMI_ROAM_IDLE_CONFIG_CMDID)) {
6117*5113495bSYour Name 		wmi_err("Failed to send WMI_ROAM_IDLE_CONFIG_CMDID");
6118*5113495bSYour Name 		wmi_buf_free(buf);
6119*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6120*5113495bSYour Name 	}
6121*5113495bSYour Name 
6122*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6123*5113495bSYour Name }
6124*5113495bSYour Name 
6125*5113495bSYour Name /**
6126*5113495bSYour Name  * send_roam_preauth_status_tlv() - send roam pre-authentication status
6127*5113495bSYour Name  * @wmi_handle: wmi handle
6128*5113495bSYour Name  * @params: pre-auth status params
6129*5113495bSYour Name  *
6130*5113495bSYour Name  * This function sends the roam pre-authentication status for WPA3 SAE
6131*5113495bSYour Name  * pre-auth to target.
6132*5113495bSYour Name  *
6133*5113495bSYour Name  * Return: QDF status
6134*5113495bSYour Name  */
6135*5113495bSYour Name static QDF_STATUS
send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,struct wmi_roam_auth_status_params * params)6136*5113495bSYour Name send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
6137*5113495bSYour Name 			     struct wmi_roam_auth_status_params *params)
6138*5113495bSYour Name {
6139*5113495bSYour Name 	wmi_roam_preauth_status_cmd_fixed_param *cmd;
6140*5113495bSYour Name 	wmi_buf_t buf;
6141*5113495bSYour Name 	uint32_t len;
6142*5113495bSYour Name 	uint8_t *buf_ptr;
6143*5113495bSYour Name 
6144*5113495bSYour Name 	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + PMKID_LEN;
6145*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
6146*5113495bSYour Name 	if (!buf)
6147*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
6148*5113495bSYour Name 
6149*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
6150*5113495bSYour Name 	cmd = (wmi_roam_preauth_status_cmd_fixed_param *)buf_ptr;
6151*5113495bSYour Name 	WMITLV_SET_HDR(
6152*5113495bSYour Name 	    &cmd->tlv_header,
6153*5113495bSYour Name 	    WMITLV_TAG_STRUC_wmi_roam_preauth_status_cmd_fixed_param,
6154*5113495bSYour Name 	    WMITLV_GET_STRUCT_TLVLEN(wmi_roam_preauth_status_cmd_fixed_param));
6155*5113495bSYour Name 
6156*5113495bSYour Name 	cmd->vdev_id = params->vdev_id;
6157*5113495bSYour Name 	cmd->preauth_status = params->preauth_status;
6158*5113495bSYour Name 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->bssid.bytes,
6159*5113495bSYour Name 				   &cmd->candidate_ap_bssid);
6160*5113495bSYour Name 
6161*5113495bSYour Name 	buf_ptr += sizeof(wmi_roam_preauth_status_cmd_fixed_param);
6162*5113495bSYour Name 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, PMKID_LEN);
6163*5113495bSYour Name 	buf_ptr += WMI_TLV_HDR_SIZE;
6164*5113495bSYour Name 
6165*5113495bSYour Name 	qdf_mem_copy(buf_ptr, params->pmkid, PMKID_LEN);
6166*5113495bSYour Name 	wmi_debug("vdev_id:%d status:%d bssid:"QDF_MAC_ADDR_FMT,
6167*5113495bSYour Name 		 cmd->vdev_id, cmd->preauth_status,
6168*5113495bSYour Name 		 QDF_MAC_ADDR_REF(params->bssid.bytes));
6169*5113495bSYour Name 
6170*5113495bSYour Name 	wmi_mtrace(WMI_ROAM_PREAUTH_STATUS_CMDID, cmd->vdev_id, 0);
6171*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, buf, len,
6172*5113495bSYour Name 				 WMI_ROAM_PREAUTH_STATUS_CMDID)) {
6173*5113495bSYour Name 		wmi_buf_free(buf);
6174*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6175*5113495bSYour Name 	}
6176*5113495bSYour Name 
6177*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6178*5113495bSYour Name }
6179*5113495bSYour Name #else
6180*5113495bSYour Name static inline QDF_STATUS
send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle,struct wlan_roam_disconnect_params * req)6181*5113495bSYour Name send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle,
6182*5113495bSYour Name 				struct wlan_roam_disconnect_params *req)
6183*5113495bSYour Name {
6184*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
6185*5113495bSYour Name }
6186*5113495bSYour Name 
6187*5113495bSYour Name static inline QDF_STATUS
send_idle_roam_params_tlv(wmi_unified_t wmi_handle,struct wlan_roam_idle_params * idle_roam_params)6188*5113495bSYour Name send_idle_roam_params_tlv(wmi_unified_t wmi_handle,
6189*5113495bSYour Name 			  struct wlan_roam_idle_params *idle_roam_params)
6190*5113495bSYour Name {
6191*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
6192*5113495bSYour Name }
6193*5113495bSYour Name 
6194*5113495bSYour Name static inline QDF_STATUS
send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,struct wmi_roam_auth_status_params * params)6195*5113495bSYour Name send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
6196*5113495bSYour Name 			     struct wmi_roam_auth_status_params *params)
6197*5113495bSYour Name {
6198*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
6199*5113495bSYour Name }
6200*5113495bSYour Name #endif
6201*5113495bSYour Name 
6202*5113495bSYour Name /**
6203*5113495bSYour Name  * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params
6204*5113495bSYour Name  * @wmi_handle: wmi handler
6205*5113495bSYour Name  * @params: pointer to 11k offload params
6206*5113495bSYour Name  *
6207*5113495bSYour Name  * Return: 0 for success and non zero for failure
6208*5113495bSYour Name  */
6209*5113495bSYour Name static QDF_STATUS
send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle,struct wlan_roam_11k_offload_params * params)6210*5113495bSYour Name send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle,
6211*5113495bSYour Name 			 struct wlan_roam_11k_offload_params *params)
6212*5113495bSYour Name {
6213*5113495bSYour Name 	wmi_11k_offload_report_fixed_param *cmd;
6214*5113495bSYour Name 	wmi_buf_t buf;
6215*5113495bSYour Name 	QDF_STATUS status;
6216*5113495bSYour Name 	uint8_t *buf_ptr;
6217*5113495bSYour Name 	wmi_neighbor_report_11k_offload_tlv_param
6218*5113495bSYour Name 					*neighbor_report_offload_params;
6219*5113495bSYour Name 	wmi_neighbor_report_offload *neighbor_report_offload;
6220*5113495bSYour Name 	uint32_t len = sizeof(*cmd);
6221*5113495bSYour Name 
6222*5113495bSYour Name 	if (params->offload_11k_bitmask &
6223*5113495bSYour Name 	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ)
6224*5113495bSYour Name 		len += WMI_TLV_HDR_SIZE +
6225*5113495bSYour Name 			sizeof(wmi_neighbor_report_11k_offload_tlv_param);
6226*5113495bSYour Name 
6227*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
6228*5113495bSYour Name 	if (!buf)
6229*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
6230*5113495bSYour Name 
6231*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
6232*5113495bSYour Name 	cmd = (wmi_11k_offload_report_fixed_param *)buf_ptr;
6233*5113495bSYour Name 
6234*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
6235*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param,
6236*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(
6237*5113495bSYour Name 				wmi_11k_offload_report_fixed_param));
6238*5113495bSYour Name 
6239*5113495bSYour Name 	cmd->vdev_id = params->vdev_id;
6240*5113495bSYour Name 	cmd->offload_11k = params->offload_11k_bitmask;
6241*5113495bSYour Name 
6242*5113495bSYour Name 	if (params->offload_11k_bitmask &
6243*5113495bSYour Name 	    WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) {
6244*5113495bSYour Name 		buf_ptr += sizeof(wmi_11k_offload_report_fixed_param);
6245*5113495bSYour Name 
6246*5113495bSYour Name 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6247*5113495bSYour Name 			sizeof(wmi_neighbor_report_11k_offload_tlv_param));
6248*5113495bSYour Name 		buf_ptr += WMI_TLV_HDR_SIZE;
6249*5113495bSYour Name 
6250*5113495bSYour Name 		neighbor_report_offload_params =
6251*5113495bSYour Name 			(wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr;
6252*5113495bSYour Name 		WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header,
6253*5113495bSYour Name 			WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param,
6254*5113495bSYour Name 			WMITLV_GET_STRUCT_TLVLEN(
6255*5113495bSYour Name 				wmi_neighbor_report_11k_offload_tlv_param));
6256*5113495bSYour Name 
6257*5113495bSYour Name 		neighbor_report_offload = &neighbor_report_offload_params->
6258*5113495bSYour Name 			neighbor_rep_ofld_params;
6259*5113495bSYour Name 
6260*5113495bSYour Name 		neighbor_report_offload->time_offset =
6261*5113495bSYour Name 			params->neighbor_report_params.time_offset;
6262*5113495bSYour Name 		neighbor_report_offload->low_rssi_offset =
6263*5113495bSYour Name 			params->neighbor_report_params.low_rssi_offset;
6264*5113495bSYour Name 		neighbor_report_offload->bmiss_count_trigger =
6265*5113495bSYour Name 			params->neighbor_report_params.bmiss_count_trigger;
6266*5113495bSYour Name 		neighbor_report_offload->per_threshold_offset =
6267*5113495bSYour Name 			params->neighbor_report_params.per_threshold_offset;
6268*5113495bSYour Name 		neighbor_report_offload->neighbor_report_cache_timeout =
6269*5113495bSYour Name 			params->neighbor_report_params.
6270*5113495bSYour Name 			neighbor_report_cache_timeout;
6271*5113495bSYour Name 		neighbor_report_offload->max_neighbor_report_req_cap =
6272*5113495bSYour Name 			params->neighbor_report_params.
6273*5113495bSYour Name 			max_neighbor_report_req_cap;
6274*5113495bSYour Name 		neighbor_report_offload->ssid.ssid_len =
6275*5113495bSYour Name 			params->neighbor_report_params.ssid.length;
6276*5113495bSYour Name 		qdf_mem_copy(neighbor_report_offload->ssid.ssid,
6277*5113495bSYour Name 			     &params->neighbor_report_params.ssid.ssid,
6278*5113495bSYour Name 			     neighbor_report_offload->ssid.ssid_len);
6279*5113495bSYour Name 	}
6280*5113495bSYour Name 
6281*5113495bSYour Name 	wmi_debug("RSO_CFG: vdev %d 11k_bitmask:%u time_offset:%u low_rssi_offset:%u bmiss_count_trigger:%u per_threshold_offset%u",
6282*5113495bSYour Name 		  cmd->vdev_id, params->offload_11k_bitmask,
6283*5113495bSYour Name 		  params->neighbor_report_params.time_offset,
6284*5113495bSYour Name 		  params->neighbor_report_params.low_rssi_offset,
6285*5113495bSYour Name 		  params->neighbor_report_params.bmiss_count_trigger,
6286*5113495bSYour Name 		  params->neighbor_report_params.per_threshold_offset);
6287*5113495bSYour Name 	wmi_debug("RSO_CFG: neighbor_report_cache_timeout:%u max_neighbor_report_req_cap:%u SSID:" QDF_SSID_FMT,
6288*5113495bSYour Name 		  params->neighbor_report_params.neighbor_report_cache_timeout,
6289*5113495bSYour Name 		  params->neighbor_report_params.max_neighbor_report_req_cap,
6290*5113495bSYour Name 		  QDF_SSID_REF(params->neighbor_report_params.ssid.length,
6291*5113495bSYour Name 			       params->neighbor_report_params.ssid.ssid));
6292*5113495bSYour Name 
6293*5113495bSYour Name 	wmi_mtrace(WMI_11K_OFFLOAD_REPORT_CMDID, cmd->vdev_id, 0);
6294*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
6295*5113495bSYour Name 				      WMI_11K_OFFLOAD_REPORT_CMDID);
6296*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
6297*5113495bSYour Name 		wmi_err("Failed to send 11k offload command %d", status);
6298*5113495bSYour Name 		wmi_buf_free(buf);
6299*5113495bSYour Name 	}
6300*5113495bSYour Name 
6301*5113495bSYour Name 	return status;
6302*5113495bSYour Name }
6303*5113495bSYour Name 
6304*5113495bSYour Name /**
6305*5113495bSYour Name  * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report
6306*5113495bSYour Name  * command
6307*5113495bSYour Name  * @wmi_handle: wmi handler
6308*5113495bSYour Name  * @params: pointer to neighbor report invoke params
6309*5113495bSYour Name  *
6310*5113495bSYour Name  * Return: 0 for success and non zero for failure
6311*5113495bSYour Name  */
send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle,struct wmi_invoke_neighbor_report_params * params)6312*5113495bSYour Name static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(
6313*5113495bSYour Name 		wmi_unified_t wmi_handle,
6314*5113495bSYour Name 		struct wmi_invoke_neighbor_report_params *params)
6315*5113495bSYour Name {
6316*5113495bSYour Name 	wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd;
6317*5113495bSYour Name 	wmi_buf_t buf;
6318*5113495bSYour Name 	QDF_STATUS status;
6319*5113495bSYour Name 	uint8_t *buf_ptr;
6320*5113495bSYour Name 	uint32_t len = sizeof(*cmd);
6321*5113495bSYour Name 
6322*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
6323*5113495bSYour Name 	if (!buf)
6324*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
6325*5113495bSYour Name 
6326*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
6327*5113495bSYour Name 	cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *)buf_ptr;
6328*5113495bSYour Name 
6329*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
6330*5113495bSYour Name 		 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param,
6331*5113495bSYour Name 		 WMITLV_GET_STRUCT_TLVLEN(
6332*5113495bSYour Name 			wmi_11k_offload_invoke_neighbor_report_fixed_param));
6333*5113495bSYour Name 
6334*5113495bSYour Name 	cmd->vdev_id = params->vdev_id;
6335*5113495bSYour Name 	cmd->flags = params->send_resp_to_host;
6336*5113495bSYour Name 
6337*5113495bSYour Name 	cmd->ssid.ssid_len = params->ssid.length;
6338*5113495bSYour Name 	qdf_mem_copy(cmd->ssid.ssid, &params->ssid.ssid, cmd->ssid.ssid_len);
6339*5113495bSYour Name 
6340*5113495bSYour Name 	wmi_mtrace(WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID, cmd->vdev_id, 0);
6341*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
6342*5113495bSYour Name 				      WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID);
6343*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
6344*5113495bSYour Name 		wmi_err("Failed to send invoke neighbor report command %d",
6345*5113495bSYour Name 			status);
6346*5113495bSYour Name 		wmi_buf_free(buf);
6347*5113495bSYour Name 	}
6348*5113495bSYour Name 
6349*5113495bSYour Name 	return status;
6350*5113495bSYour Name }
6351*5113495bSYour Name 
wmi_roam_attach_tlv(wmi_unified_t wmi_handle)6352*5113495bSYour Name void wmi_roam_attach_tlv(wmi_unified_t wmi_handle)
6353*5113495bSYour Name {
6354*5113495bSYour Name 	struct wmi_ops *ops = wmi_handle->ops;
6355*5113495bSYour Name 
6356*5113495bSYour Name 	ops->send_roam_scan_offload_rssi_thresh_cmd =
6357*5113495bSYour Name 			send_roam_scan_offload_rssi_thresh_cmd_tlv;
6358*5113495bSYour Name 	ops->send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv;
6359*5113495bSYour Name 	ops->send_roam_scan_filter_cmd =
6360*5113495bSYour Name 			send_roam_scan_filter_cmd_tlv;
6361*5113495bSYour Name 	ops->send_roam_scan_offload_mode_cmd =
6362*5113495bSYour Name 			send_roam_scan_offload_mode_cmd_tlv;
6363*5113495bSYour Name 	ops->send_roam_scan_offload_ap_profile_cmd =
6364*5113495bSYour Name 			send_roam_scan_offload_ap_profile_cmd_tlv;
6365*5113495bSYour Name 	ops->send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv;
6366*5113495bSYour Name 	ops->send_roam_scan_offload_scan_period_cmd =
6367*5113495bSYour Name 			send_roam_scan_offload_scan_period_cmd_tlv;
6368*5113495bSYour Name 	ops->send_roam_scan_offload_chan_list_cmd =
6369*5113495bSYour Name 			send_roam_scan_offload_chan_list_cmd_tlv;
6370*5113495bSYour Name 	ops->send_roam_scan_offload_rssi_change_cmd =
6371*5113495bSYour Name 			send_roam_scan_offload_rssi_change_cmd_tlv;
6372*5113495bSYour Name 	ops->send_per_roam_config_cmd = send_per_roam_config_cmd_tlv;
6373*5113495bSYour Name 	ops->send_limit_off_chan_cmd = send_limit_off_chan_cmd_tlv;
6374*5113495bSYour Name 	ops->send_btm_config = send_btm_config_cmd_tlv;
6375*5113495bSYour Name 	ops->send_offload_11k_cmd = send_offload_11k_cmd_tlv;
6376*5113495bSYour Name 	ops->send_invoke_neighbor_report_cmd =
6377*5113495bSYour Name 			send_invoke_neighbor_report_cmd_tlv;
6378*5113495bSYour Name 	ops->send_roam_bss_load_config = send_roam_bss_load_config_tlv;
6379*5113495bSYour Name 	ops->send_idle_roam_params = send_idle_roam_params_tlv;
6380*5113495bSYour Name 	ops->send_disconnect_roam_params = send_disconnect_roam_params_tlv;
6381*5113495bSYour Name 	ops->send_roam_preauth_status = send_roam_preauth_status_tlv;
6382*5113495bSYour Name 	ops->extract_roam_event = extract_roam_event_tlv;
6383*5113495bSYour Name 
6384*5113495bSYour Name 	wmi_roam_mlo_attach_tlv(wmi_handle);
6385*5113495bSYour Name 	wmi_lfr_subnet_detection_attach_tlv(wmi_handle);
6386*5113495bSYour Name 	wmi_rssi_monitor_attach_tlv(wmi_handle);
6387*5113495bSYour Name 	wmi_ese_attach_tlv(wmi_handle);
6388*5113495bSYour Name 	wmi_roam_offload_attach_tlv(wmi_handle);
6389*5113495bSYour Name 	wmi_fils_sk_attach_tlv(wmi_handle);
6390*5113495bSYour Name }
6391