blob: c8f7ea5f773339640fc1292347ff652fedcc9d4a [file] [log] [blame]
Qiwei Cai770c90f2018-09-17 19:17:13 +08001/*
Jeff Johnsonfe762b22018-12-23 08:04:17 -08002 * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
Qiwei Cai770c90f2018-09-17 19:17:13 +08003 *
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18/**
19 * DOC: Implement API's specific to roaming component.
20 */
21
22#include <wmi_unified_priv.h>
23#include <wmi_unified_roam_api.h>
Tushnim Bhattacharyya33087cb2019-08-12 15:58:40 -070024#include "wmi.h"
Qiwei Cai770c90f2018-09-17 19:17:13 +080025
26#ifdef FEATURE_LFR_SUBNET_DETECTION
27/**
28 * send_set_gateway_params_cmd_tlv() - set gateway parameters
29 * @wmi_handle: wmi handle
30 * @req: gateway parameter update request structure
31 *
32 * This function reads the incoming @req and fill in the destination
33 * WMI structure and sends down the gateway configs down to the firmware
34 *
35 * Return: QDF_STATUS
36 */
37static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle,
38 struct gateway_update_req_param *req)
39{
40 wmi_roam_subnet_change_config_fixed_param *cmd;
41 wmi_buf_t buf;
42 QDF_STATUS ret;
43 int len = sizeof(*cmd);
44
45 buf = wmi_buf_alloc(wmi_handle, len);
46 if (!buf) {
47 return QDF_STATUS_E_NOMEM;
48 }
49
50 cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf);
51 WMITLV_SET_HDR(&cmd->tlv_header,
52 WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param,
53 WMITLV_GET_STRUCT_TLVLEN(
54 wmi_roam_subnet_change_config_fixed_param));
55
Jeff Johnson9963d872019-02-22 15:53:51 -080056 cmd->vdev_id = req->vdev_id;
Qiwei Cai770c90f2018-09-17 19:17:13 +080057 qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr,
58 QDF_IPV4_ADDR_SIZE);
59 qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr,
60 QDF_IPV6_ADDR_SIZE);
61 WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes,
62 &cmd->inet_gw_mac_addr);
63 cmd->max_retries = req->max_retries;
64 cmd->timeout = req->timeout;
65 cmd->num_skip_subnet_change_detection_bssid_list = 0;
66 cmd->flag = 0;
67 if (req->ipv4_addr_type)
68 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag);
69
70 if (req->ipv6_addr_type)
71 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag);
72
73 wmi_mtrace(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID, cmd->vdev_id, 0);
74 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
75 WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID);
76 if (QDF_IS_STATUS_ERROR(ret)) {
77 WMI_LOGE("Failed to send gw config parameter to fw, ret: %d",
78 ret);
79 wmi_buf_free(buf);
80 }
81
82 return ret;
83}
84
85void wmi_lfr_subnet_detection_attach_tlv(struct wmi_unified *wmi_handle)
86{
87 struct wmi_ops *ops = wmi_handle->ops;
88
89 ops->send_set_gateway_params_cmd = send_set_gateway_params_cmd_tlv;
90}
91#endif /* FEATURE_LFR_SUBNET_DETECTION */
92
93#ifdef FEATURE_RSSI_MONITOR
94/**
95 * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring
96 * @wmi_handle: wmi handle
97 * @req: rssi monitoring request structure
98 *
99 * This function reads the incoming @req and fill in the destination
100 * WMI structure and send down the rssi monitoring configs down to the firmware
101 *
102 * Return: 0 on success; error number otherwise
103 */
104static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle,
105 struct rssi_monitor_param *req)
106{
107 wmi_rssi_breach_monitor_config_fixed_param *cmd;
108 wmi_buf_t buf;
109 QDF_STATUS ret;
110 uint32_t len = sizeof(*cmd);
111
112 buf = wmi_buf_alloc(wmi_handle, len);
113 if (!buf) {
114 return QDF_STATUS_E_NOMEM;
115 }
116
117 cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf);
118 WMITLV_SET_HDR(&cmd->tlv_header,
119 WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param,
120 WMITLV_GET_STRUCT_TLVLEN(
121 wmi_rssi_breach_monitor_config_fixed_param));
122
Jeff Johnson855f0b12019-02-22 20:10:01 -0800123 cmd->vdev_id = req->vdev_id;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800124 cmd->request_id = req->request_id;
125 cmd->lo_rssi_reenable_hysteresis = 0;
126 cmd->hi_rssi_reenable_histeresis = 0;
127 cmd->min_report_interval = 0;
128 cmd->max_num_report = 1;
129 if (req->control) {
130 /* enable one threshold for each min/max */
131 cmd->enabled_bitmap = 0x09;
132 cmd->low_rssi_breach_threshold[0] = req->min_rssi;
133 cmd->hi_rssi_breach_threshold[0] = req->max_rssi;
134 } else {
135 cmd->enabled_bitmap = 0;
136 cmd->low_rssi_breach_threshold[0] = 0;
137 cmd->hi_rssi_breach_threshold[0] = 0;
138 }
139
140 wmi_mtrace(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID, cmd->vdev_id, 0);
141 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
142 WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID);
143 if (QDF_IS_STATUS_ERROR(ret)) {
144 WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID");
145 wmi_buf_free(buf);
146 }
147
148 WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW");
149
150 return ret;
151}
152
153void wmi_rssi_monitor_attach_tlv(struct wmi_unified *wmi_handle)
154{
155 struct wmi_ops *ops = wmi_handle->ops;
156
157 ops->send_set_rssi_monitoring_cmd = send_set_rssi_monitoring_cmd_tlv;
158}
159#endif /* FEATURE_RSSI_MONITOR */
160
161/**
162 * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload
163 * rssi threashold
164 * @wmi_handle: wmi handle
165 * @roam_req: Roaming request buffer
166 *
167 * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
168 *
169 * Return: QDF status
170 */
171static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle,
172 struct roam_offload_scan_rssi_params *roam_req)
173{
174 wmi_buf_t buf = NULL;
175 QDF_STATUS status;
176 int len;
177 uint8_t *buf_ptr;
178 wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp;
179 wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL;
180 wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL;
181 wmi_roam_dense_thres_param *dense_thresholds = NULL;
182 wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL;
183
184 len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
185 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
186 len += sizeof(wmi_roam_scan_extended_threshold_param);
187 len += WMI_TLV_HDR_SIZE;
188 len += sizeof(wmi_roam_earlystop_rssi_thres_param);
189 len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/
190 len += sizeof(wmi_roam_dense_thres_param);
191 len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/
192 len += sizeof(wmi_roam_bg_scan_roaming_param);
193 buf = wmi_buf_alloc(wmi_handle, len);
194 if (!buf) {
195 return QDF_STATUS_E_NOMEM;
196 }
197
198 buf_ptr = (uint8_t *) wmi_buf_data(buf);
199 rssi_threshold_fp =
200 (wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr;
201 WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header,
202 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param,
203 WMITLV_GET_STRUCT_TLVLEN
204 (wmi_roam_scan_rssi_threshold_fixed_param));
205 /* fill in threshold values */
Jeff Johnsona171ad22019-02-22 21:26:31 -0800206 rssi_threshold_fp->vdev_id = roam_req->vdev_id;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800207 rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh;
208 rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff;
209 rssi_threshold_fp->hirssi_scan_max_count =
210 roam_req->hi_rssi_scan_max_count;
211 rssi_threshold_fp->hirssi_scan_delta =
212 roam_req->hi_rssi_scan_rssi_delta;
213 rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub;
214 rssi_threshold_fp->rssi_thresh_offset_5g =
215 roam_req->rssi_thresh_offset_5g;
216
217 buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
218 WMITLV_SET_HDR(buf_ptr,
219 WMITLV_TAG_ARRAY_STRUC,
220 sizeof(wmi_roam_scan_extended_threshold_param));
221 buf_ptr += WMI_TLV_HDR_SIZE;
222 ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr;
223
224 ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g;
225 if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT)
226 ext_thresholds->boost_threshold_5g =
227 roam_req->boost_threshold_5g;
228
229 ext_thresholds->boost_algorithm_5g =
230 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
231 ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g;
232 ext_thresholds->penalty_algorithm_5g =
233 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
234 ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g;
235 ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g;
236 ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g;
237 ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold;
238
239 WMITLV_SET_HDR(&ext_thresholds->tlv_header,
240 WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param,
241 WMITLV_GET_STRUCT_TLVLEN
242 (wmi_roam_scan_extended_threshold_param));
243 buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param);
244 WMITLV_SET_HDR(buf_ptr,
245 WMITLV_TAG_ARRAY_STRUC,
246 sizeof(wmi_roam_earlystop_rssi_thres_param));
247 buf_ptr += WMI_TLV_HDR_SIZE;
248 early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr;
249 early_stop_thresholds->roam_earlystop_thres_min =
250 roam_req->roam_earlystop_thres_min;
251 early_stop_thresholds->roam_earlystop_thres_max =
252 roam_req->roam_earlystop_thres_max;
253 WMITLV_SET_HDR(&early_stop_thresholds->tlv_header,
254 WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param,
255 WMITLV_GET_STRUCT_TLVLEN
256 (wmi_roam_earlystop_rssi_thres_param));
257
258 buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param);
259 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
260 sizeof(wmi_roam_dense_thres_param));
261 buf_ptr += WMI_TLV_HDR_SIZE;
262 dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr;
263 dense_thresholds->roam_dense_rssi_thres_offset =
264 roam_req->dense_rssi_thresh_offset;
265 dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt;
266 dense_thresholds->roam_dense_traffic_thres =
267 roam_req->traffic_threshold;
268 dense_thresholds->roam_dense_status = roam_req->initial_dense_status;
269 WMITLV_SET_HDR(&dense_thresholds->tlv_header,
270 WMITLV_TAG_STRUC_wmi_roam_dense_thres_param,
271 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_dense_thres_param));
272
273 buf_ptr += sizeof(wmi_roam_dense_thres_param);
274 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
275 sizeof(wmi_roam_bg_scan_roaming_param));
276 buf_ptr += WMI_TLV_HDR_SIZE;
277 bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr;
278 bg_scan_params->roam_bg_scan_bad_rssi_thresh =
279 roam_req->bg_scan_bad_rssi_thresh;
280 bg_scan_params->roam_bg_scan_client_bitmap =
281 roam_req->bg_scan_client_bitmap;
282 bg_scan_params->bad_rssi_thresh_offset_2g =
283 roam_req->roam_bad_rssi_thresh_offset_2g;
284 bg_scan_params->flags = roam_req->flags;
285 WMITLV_SET_HDR(&bg_scan_params->tlv_header,
286 WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param,
287 WMITLV_GET_STRUCT_TLVLEN
288 (wmi_roam_bg_scan_roaming_param));
289
290 wmi_mtrace(WMI_ROAM_SCAN_RSSI_THRESHOLD, NO_SESSION, 0);
291 status = wmi_unified_cmd_send(wmi_handle, buf,
292 len, WMI_ROAM_SCAN_RSSI_THRESHOLD);
293 if (QDF_IS_STATUS_ERROR(status)) {
294 WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d",
295 status);
296 wmi_buf_free(buf);
297 }
298
299 return status;
300}
301
302static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle,
303 struct wmi_mawc_roam_params *params)
304{
305 wmi_buf_t buf = NULL;
306 QDF_STATUS status;
307 int len;
308 uint8_t *buf_ptr;
309 wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params;
310
311 len = sizeof(*wmi_roam_mawc_params);
312 buf = wmi_buf_alloc(wmi_handle, len);
313 if (!buf) {
314 return QDF_STATUS_E_NOMEM;
315 }
316
317 buf_ptr = (uint8_t *) wmi_buf_data(buf);
318 wmi_roam_mawc_params =
319 (wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr;
320 WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header,
321 WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param,
322 WMITLV_GET_STRUCT_TLVLEN
323 (wmi_roam_configure_mawc_cmd_fixed_param));
324 wmi_roam_mawc_params->vdev_id = params->vdev_id;
325 if (params->enable)
326 wmi_roam_mawc_params->enable = 1;
327 else
328 wmi_roam_mawc_params->enable = 0;
329 wmi_roam_mawc_params->traffic_load_threshold =
330 params->traffic_load_threshold;
331 wmi_roam_mawc_params->best_ap_rssi_threshold =
332 params->best_ap_rssi_threshold;
333 wmi_roam_mawc_params->rssi_stationary_high_adjust =
334 params->rssi_stationary_high_adjust;
335 wmi_roam_mawc_params->rssi_stationary_low_adjust =
336 params->rssi_stationary_low_adjust;
337 WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"),
338 wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id,
339 wmi_roam_mawc_params->traffic_load_threshold,
340 wmi_roam_mawc_params->best_ap_rssi_threshold,
341 wmi_roam_mawc_params->rssi_stationary_high_adjust,
342 wmi_roam_mawc_params->rssi_stationary_low_adjust);
343
344 wmi_mtrace(WMI_ROAM_CONFIGURE_MAWC_CMDID, NO_SESSION, 0);
345 status = wmi_unified_cmd_send(wmi_handle, buf,
346 len, WMI_ROAM_CONFIGURE_MAWC_CMDID);
347 if (QDF_IS_STATUS_ERROR(status)) {
348 WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d",
349 status);
350 wmi_buf_free(buf);
351 return status;
352 }
353
354 return QDF_STATUS_SUCCESS;
355}
356
357/**
358 * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming
359 * @wmi_handle: wmi handle
360 * @roam_req: Request which contains the filters
361 *
362 * There are filters such as whitelist, blacklist and preferred
363 * list that need to be applied to the scan results to form the
364 * probable candidates for roaming.
365 *
366 * Return: Return success upon successfully passing the
367 * parameters to the firmware, otherwise failure.
368 */
369static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle,
370 struct roam_scan_filter_params *roam_req)
371{
372 wmi_buf_t buf = NULL;
373 QDF_STATUS status;
374 uint32_t i;
375 uint32_t len, blist_len = 0;
376 uint8_t *buf_ptr;
377 wmi_roam_filter_fixed_param *roam_filter;
378 uint8_t *bssid_src_ptr = NULL;
379 wmi_mac_addr *bssid_dst_ptr = NULL;
380 wmi_ssid *ssid_ptr = NULL;
381 uint32_t *bssid_preferred_factor_ptr = NULL;
382 wmi_roam_lca_disallow_config_tlv_param *blist_param;
383 wmi_roam_rssi_rejection_oce_config_param *rssi_rej;
384
385 len = sizeof(wmi_roam_filter_fixed_param);
386
387 len += WMI_TLV_HDR_SIZE;
388 if (roam_req->num_bssid_black_list)
389 len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr);
390 len += WMI_TLV_HDR_SIZE;
391 if (roam_req->num_ssid_white_list)
392 len += roam_req->num_ssid_white_list * sizeof(wmi_ssid);
393 len += 2 * WMI_TLV_HDR_SIZE;
394 if (roam_req->num_bssid_preferred_list) {
395 len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr);
396 len += roam_req->num_bssid_preferred_list * sizeof(uint32_t);
397 }
398 len += WMI_TLV_HDR_SIZE;
399 if (roam_req->lca_disallow_config_present) {
400 len += sizeof(*blist_param);
401 blist_len = sizeof(*blist_param);
402 }
403
404 len += WMI_TLV_HDR_SIZE;
405 if (roam_req->num_rssi_rejection_ap)
406 len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej);
407
408 buf = wmi_buf_alloc(wmi_handle, len);
409 if (!buf) {
410 return QDF_STATUS_E_NOMEM;
411 }
412
413 buf_ptr = (u_int8_t *) wmi_buf_data(buf);
414 roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr;
415 WMITLV_SET_HDR(&roam_filter->tlv_header,
416 WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param,
417 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param));
418 /* fill in fixed values */
Jeff Johnson49352282019-02-28 12:19:23 -0800419 roam_filter->vdev_id = roam_req->vdev_id;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800420 roam_filter->flags = 0;
421 roam_filter->op_bitmap = roam_req->op_bitmap;
422 roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list;
423 roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list;
424 roam_filter->num_bssid_preferred_list =
425 roam_req->num_bssid_preferred_list;
426 roam_filter->num_rssi_rejection_ap =
427 roam_req->num_rssi_rejection_ap;
428 buf_ptr += sizeof(wmi_roam_filter_fixed_param);
429
430 WMITLV_SET_HDR((buf_ptr),
431 WMITLV_TAG_ARRAY_FIXED_STRUC,
432 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)));
433 bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list;
434 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
435 for (i = 0; i < roam_req->num_bssid_black_list; i++) {
436 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr);
437 bssid_src_ptr += ATH_MAC_LEN;
438 bssid_dst_ptr++;
439 }
440 buf_ptr += WMI_TLV_HDR_SIZE +
441 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr));
442 WMITLV_SET_HDR((buf_ptr),
443 WMITLV_TAG_ARRAY_FIXED_STRUC,
444 (roam_req->num_ssid_white_list * sizeof(wmi_ssid)));
445 ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE);
446 for (i = 0; i < roam_req->num_ssid_white_list; i++) {
447 qdf_mem_copy(&ssid_ptr->ssid,
448 &roam_req->ssid_allowed_list[i].mac_ssid,
449 roam_req->ssid_allowed_list[i].length);
450 ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length;
451 ssid_ptr++;
452 }
453 buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list *
454 sizeof(wmi_ssid));
455 WMITLV_SET_HDR((buf_ptr),
456 WMITLV_TAG_ARRAY_FIXED_STRUC,
457 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)));
458 bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored;
459 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
460 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
461 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr,
462 (wmi_mac_addr *)bssid_dst_ptr);
463 bssid_src_ptr += ATH_MAC_LEN;
464 bssid_dst_ptr++;
465 }
466 buf_ptr += WMI_TLV_HDR_SIZE +
467 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr));
468 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
469 (roam_req->num_bssid_preferred_list * sizeof(uint32_t)));
470 bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
471 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
472 *bssid_preferred_factor_ptr =
473 roam_req->bssid_favored_factor[i];
474 bssid_preferred_factor_ptr++;
475 }
476 buf_ptr += WMI_TLV_HDR_SIZE +
477 (roam_req->num_bssid_preferred_list * sizeof(uint32_t));
478
479 WMITLV_SET_HDR(buf_ptr,
480 WMITLV_TAG_ARRAY_STRUC, blist_len);
481 buf_ptr += WMI_TLV_HDR_SIZE;
482 if (roam_req->lca_disallow_config_present) {
483 blist_param =
484 (wmi_roam_lca_disallow_config_tlv_param *) buf_ptr;
485 WMITLV_SET_HDR(&blist_param->tlv_header,
486 WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param,
487 WMITLV_GET_STRUCT_TLVLEN(
488 wmi_roam_lca_disallow_config_tlv_param));
489
490 blist_param->disallow_duration = roam_req->disallow_duration;
491 blist_param->rssi_channel_penalization =
492 roam_req->rssi_channel_penalization;
493 blist_param->num_disallowed_aps = roam_req->num_disallowed_aps;
494 blist_param->disallow_lca_enable_source_bitmap =
495 (WMI_ROAM_LCA_DISALLOW_SOURCE_PER |
496 WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND);
497 buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param));
498 }
499
500 WMITLV_SET_HDR(buf_ptr,
501 WMITLV_TAG_ARRAY_STRUC,
502 (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej)));
503 buf_ptr += WMI_TLV_HDR_SIZE;
504 for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) {
505 rssi_rej =
506 (wmi_roam_rssi_rejection_oce_config_param *) buf_ptr;
507 WMITLV_SET_HDR(&rssi_rej->tlv_header,
508 WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param,
509 WMITLV_GET_STRUCT_TLVLEN(
510 wmi_roam_rssi_rejection_oce_config_param));
511 WMI_CHAR_ARRAY_TO_MAC_ADDR(
512 roam_req->rssi_rejection_ap[i].bssid.bytes,
513 &rssi_rej->bssid);
514 rssi_rej->remaining_disallow_duration =
gaurank kathpalia9f525cb2019-05-28 18:21:18 +0530515 roam_req->rssi_rejection_ap[i].reject_duration;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800516 rssi_rej->requested_rssi =
517 (int32_t)roam_req->rssi_rejection_ap[i].expected_rssi;
518 buf_ptr +=
519 (sizeof(wmi_roam_rssi_rejection_oce_config_param));
520 }
521
522 wmi_mtrace(WMI_ROAM_FILTER_CMDID, NO_SESSION, 0);
523 status = wmi_unified_cmd_send(wmi_handle, buf,
524 len, WMI_ROAM_FILTER_CMDID);
525 if (QDF_IS_STATUS_ERROR(status)) {
526 WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d",
527 status);
528 wmi_buf_free(buf);
529 }
530
531 return status;
532}
533
534#ifdef FEATURE_WLAN_ESE
535/**
536 * send_plm_stop_cmd_tlv() - plm stop request
537 * @wmi_handle: wmi handle
538 * @plm: plm request parameters
539 *
540 * This function request FW to stop PLM.
541 *
542 * Return: CDF status
543 */
544static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle,
545 const struct plm_req_params *plm)
546{
547 wmi_vdev_plmreq_stop_cmd_fixed_param *cmd;
548 int32_t len;
549 wmi_buf_t buf;
550 uint8_t *buf_ptr;
551 int ret;
552
553 len = sizeof(*cmd);
554 buf = wmi_buf_alloc(wmi_handle, len);
555 if (!buf) {
556 return QDF_STATUS_E_NOMEM;
557 }
558
559 cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf);
560
561 buf_ptr = (uint8_t *) cmd;
562
563 WMITLV_SET_HDR(&cmd->tlv_header,
564 WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param,
565 WMITLV_GET_STRUCT_TLVLEN
566 (wmi_vdev_plmreq_stop_cmd_fixed_param));
567
Jeff Johnsonb6966692019-02-25 17:43:27 -0800568 cmd->vdev_id = plm->vdev_id;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800569
570 cmd->meas_token = plm->meas_token;
571 WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token);
572
573 wmi_mtrace(WMI_VDEV_PLMREQ_STOP_CMDID, cmd->vdev_id, 0);
574 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
575 WMI_VDEV_PLMREQ_STOP_CMDID);
576 if (ret) {
577 WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__);
578 wmi_buf_free(buf);
579 return QDF_STATUS_E_FAILURE;
580 }
581
582 return QDF_STATUS_SUCCESS;
583}
584
585/**
586 * send_plm_start_cmd_tlv() - plm start request
587 * @wmi_handle: wmi handle
588 * @plm: plm request parameters
589 *
590 * This function request FW to start PLM.
591 *
592 * Return: CDF status
593 */
594static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle,
wadesongc3ac05e2019-11-04 15:18:35 +0800595 const struct plm_req_params *plm)
Qiwei Cai770c90f2018-09-17 19:17:13 +0800596{
597 wmi_vdev_plmreq_start_cmd_fixed_param *cmd;
598 uint32_t *channel_list;
599 int32_t len;
600 wmi_buf_t buf;
601 uint8_t *buf_ptr;
602 uint8_t count;
603 int ret;
604
605 /* TLV place holder for channel_list */
606 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
607 len += sizeof(uint32_t) * plm->plm_num_ch;
608
609 buf = wmi_buf_alloc(wmi_handle, len);
610 if (!buf) {
611 return QDF_STATUS_E_NOMEM;
612 }
613 cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf);
614
615 buf_ptr = (uint8_t *) cmd;
616
617 WMITLV_SET_HDR(&cmd->tlv_header,
618 WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param,
619 WMITLV_GET_STRUCT_TLVLEN
620 (wmi_vdev_plmreq_start_cmd_fixed_param));
621
Jeff Johnsonb6966692019-02-25 17:43:27 -0800622 cmd->vdev_id = plm->vdev_id;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800623
624 cmd->meas_token = plm->meas_token;
625 cmd->dialog_token = plm->diag_token;
626 cmd->number_bursts = plm->num_bursts;
627 cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int);
628 cmd->off_duration = plm->meas_duration;
629 cmd->burst_cycle = plm->burst_len;
630 cmd->tx_power = plm->desired_tx_pwr;
631 WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac);
632 cmd->num_chans = plm->plm_num_ch;
633
634 buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param);
635
636 WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token);
637 WMI_LOGD("dialog_token: %d", cmd->dialog_token);
638 WMI_LOGD("number_bursts: %d", cmd->number_bursts);
639 WMI_LOGD("burst_interval: %d", cmd->burst_interval);
640 WMI_LOGD("off_duration: %d", cmd->off_duration);
641 WMI_LOGD("burst_cycle: %d", cmd->burst_cycle);
642 WMI_LOGD("tx_power: %d", cmd->tx_power);
643 WMI_LOGD("Number of channels : %d", cmd->num_chans);
644
645 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
646 (cmd->num_chans * sizeof(uint32_t)));
647
648 buf_ptr += WMI_TLV_HDR_SIZE;
649 if (cmd->num_chans) {
650 channel_list = (uint32_t *) buf_ptr;
651 for (count = 0; count < cmd->num_chans; count++) {
wadesongc3ac05e2019-11-04 15:18:35 +0800652 channel_list[count] = plm->plm_ch_freq_list[count];
Qiwei Cai770c90f2018-09-17 19:17:13 +0800653 WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]);
654 }
655 buf_ptr += cmd->num_chans * sizeof(uint32_t);
656 }
657
658 wmi_mtrace(WMI_VDEV_PLMREQ_START_CMDID, cmd->vdev_id, 0);
659 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
660 WMI_VDEV_PLMREQ_START_CMDID);
661 if (ret) {
662 WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__);
663 wmi_buf_free(buf);
664 return QDF_STATUS_E_FAILURE;
665 }
666
667 return QDF_STATUS_SUCCESS;
668}
669
670void wmi_ese_attach_tlv(wmi_unified_t wmi_handle)
671{
672 struct wmi_ops *ops = wmi_handle->ops;
673
674 ops->send_plm_stop_cmd = send_plm_stop_cmd_tlv;
675 ops->send_plm_start_cmd = send_plm_start_cmd_tlv;
676}
677#endif /* FEATURE_WLAN_ESE */
678
679#ifdef WLAN_FEATURE_ROAM_OFFLOAD
680/* send_set_ric_req_cmd_tlv() - set ric request element
681 * @wmi_handle: wmi handle
682 * @msg: message
683 * @is_add_ts: is addts required
684 *
685 * This function sets ric request element for 11r roaming.
686 *
687 * Return: CDF status
688 */
689static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle,
690 void *msg, uint8_t is_add_ts)
691{
692 wmi_ric_request_fixed_param *cmd;
693 wmi_ric_tspec *tspec_param;
694 wmi_buf_t buf;
695 uint8_t *buf_ptr;
Jeff Johnsonfe762b22018-12-23 08:04:17 -0800696 struct mac_tspec_ie *tspec_ie = NULL;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800697 int32_t len = sizeof(wmi_ric_request_fixed_param) +
698 WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec);
699
700 buf = wmi_buf_alloc(wmi_handle, len);
701 if (!buf) {
702 return QDF_STATUS_E_NOMEM;
703 }
704
705 buf_ptr = (uint8_t *) wmi_buf_data(buf);
706
707 cmd = (wmi_ric_request_fixed_param *) buf_ptr;
708 WMITLV_SET_HDR(&cmd->tlv_header,
709 WMITLV_TAG_STRUC_wmi_ric_request_fixed_param,
710 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param));
711 if (is_add_ts)
Jeff Johnson7929ba92019-01-20 14:22:42 -0800712 cmd->vdev_id = ((struct add_ts_param *)msg)->vdev_id;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800713 else
Jeff Johnson7929ba92019-01-20 14:22:42 -0800714 cmd->vdev_id = ((struct del_ts_params *)msg)->sessionId;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800715 cmd->num_ric_request = 1;
716 cmd->is_add_ric = is_add_ts;
717
718 buf_ptr += sizeof(wmi_ric_request_fixed_param);
719 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec));
720
721 buf_ptr += WMI_TLV_HDR_SIZE;
722 tspec_param = (wmi_ric_tspec *) buf_ptr;
723 WMITLV_SET_HDR(&tspec_param->tlv_header,
724 WMITLV_TAG_STRUC_wmi_ric_tspec,
725 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec));
726
727 if (is_add_ts)
Jeff Johnsonfe762b22018-12-23 08:04:17 -0800728 tspec_ie = &(((struct add_ts_param *) msg)->tspec);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800729 else
Jeff Johnsonfe762b22018-12-23 08:04:17 -0800730 tspec_ie = &(((struct del_ts_params *) msg)->delTsInfo.tspec);
731 if (tspec_ie) {
Qiwei Cai770c90f2018-09-17 19:17:13 +0800732 /* Fill the tsinfo in the format expected by firmware */
733#ifndef ANI_LITTLE_BIT_ENDIAN
734 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1,
Jeff Johnsonfe762b22018-12-23 08:04:17 -0800735 ((uint8_t *) &tspec_ie->tsinfo) + 1, 2);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800736#else
737 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info),
Jeff Johnsonfe762b22018-12-23 08:04:17 -0800738 ((uint8_t *) &tspec_ie->tsinfo) + 1, 2);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800739#endif /* ANI_LITTLE_BIT_ENDIAN */
740
Jeff Johnsonfe762b22018-12-23 08:04:17 -0800741 tspec_param->nominal_msdu_size = tspec_ie->nomMsduSz;
742 tspec_param->maximum_msdu_size = tspec_ie->maxMsduSz;
743 tspec_param->min_service_interval = tspec_ie->minSvcInterval;
744 tspec_param->max_service_interval = tspec_ie->maxSvcInterval;
745 tspec_param->inactivity_interval = tspec_ie->inactInterval;
746 tspec_param->suspension_interval = tspec_ie->suspendInterval;
747 tspec_param->svc_start_time = tspec_ie->svcStartTime;
748 tspec_param->min_data_rate = tspec_ie->minDataRate;
749 tspec_param->mean_data_rate = tspec_ie->meanDataRate;
750 tspec_param->peak_data_rate = tspec_ie->peakDataRate;
751 tspec_param->max_burst_size = tspec_ie->maxBurstSz;
752 tspec_param->delay_bound = tspec_ie->delayBound;
753 tspec_param->min_phy_rate = tspec_ie->minPhyRate;
754 tspec_param->surplus_bw_allowance = tspec_ie->surplusBw;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800755 tspec_param->medium_time = 0;
756 }
757 WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts);
758
759 wmi_mtrace(WMI_ROAM_SET_RIC_REQUEST_CMDID, cmd->vdev_id, 0);
760 if (wmi_unified_cmd_send(wmi_handle, buf, len,
761 WMI_ROAM_SET_RIC_REQUEST_CMDID)) {
762 WMI_LOGP("%s: Failed to send vdev Set RIC Req command",
763 __func__);
764 if (is_add_ts)
765 ((struct add_ts_param *) msg)->status =
766 QDF_STATUS_E_FAILURE;
767 wmi_buf_free(buf);
768 return QDF_STATUS_E_FAILURE;
769 }
770
771 return QDF_STATUS_SUCCESS;
772}
773
774/**
775 * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw.
776 * @wmi_handle: wmi handle
777 * @vdev_id: vdev id
778 *
779 * This function sends roam synch complete event to fw.
780 *
781 * Return: CDF STATUS
782 */
783static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle,
784 uint8_t vdev_id)
785{
786 wmi_roam_synch_complete_fixed_param *cmd;
787 wmi_buf_t wmi_buf;
788 uint8_t *buf_ptr;
789 uint16_t len;
790 len = sizeof(wmi_roam_synch_complete_fixed_param);
791
792 wmi_buf = wmi_buf_alloc(wmi_handle, len);
793 if (!wmi_buf) {
794 return QDF_STATUS_E_NOMEM;
795 }
796 cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf);
797 buf_ptr = (uint8_t *) cmd;
798 WMITLV_SET_HDR(&cmd->tlv_header,
799 WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param,
800 WMITLV_GET_STRUCT_TLVLEN
801 (wmi_roam_synch_complete_fixed_param));
802 cmd->vdev_id = vdev_id;
803 wmi_mtrace(WMI_ROAM_SYNCH_COMPLETE, cmd->vdev_id, 0);
804 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
805 WMI_ROAM_SYNCH_COMPLETE)) {
806 WMI_LOGP("%s: failed to send roam synch confirmation",
807 __func__);
808 wmi_buf_free(wmi_buf);
809 return QDF_STATUS_E_FAILURE;
810 }
811
812 return QDF_STATUS_SUCCESS;
813}
814
815/**
816 * send_roam_invoke_cmd_tlv() - send roam invoke command to fw.
817 * @wmi_handle: wma handle
818 * @roaminvoke: roam invoke command
819 *
820 * Send roam invoke command to fw for fastreassoc.
821 *
822 * Return: CDF STATUS
823 */
824static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,
825 struct wmi_roam_invoke_cmd *roaminvoke,
826 uint32_t ch_hz)
827{
828 wmi_roam_invoke_cmd_fixed_param *cmd;
829 wmi_buf_t wmi_buf;
830 u_int8_t *buf_ptr;
831 u_int16_t len, args_tlv_len;
832 uint32_t *channel_list;
833 wmi_mac_addr *bssid_list;
834 wmi_tlv_buf_len_param *buf_len_tlv;
835
Qiwei Cai770c90f2018-09-17 19:17:13 +0800836 args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) +
837 sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) +
838 roundup(roaminvoke->frame_len, sizeof(uint32_t));
839 len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len;
840 wmi_buf = wmi_buf_alloc(wmi_handle, len);
841 if (!wmi_buf) {
842 return QDF_STATUS_E_NOMEM;
843 }
844
845 cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf);
846 buf_ptr = (u_int8_t *) cmd;
847 WMITLV_SET_HDR(&cmd->tlv_header,
848 WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param,
849 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param));
850 cmd->vdev_id = roaminvoke->vdev_id;
851 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE);
852 if (roaminvoke->is_same_bssid)
853 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP);
854 WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid);
855
856 if (roaminvoke->frame_len) {
857 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP;
858 /* packing 1 beacon/probe_rsp frame with WMI cmd */
859 cmd->num_buf = 1;
860 } else {
861 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH;
862 cmd->num_buf = 0;
863 }
864
865 cmd->roam_ap_sel_mode = 0;
866 cmd->roam_delay = 0;
867 cmd->num_chan = 1;
868 cmd->num_bssid = 1;
869
gaurank kathpalia9f525cb2019-05-28 18:21:18 +0530870 if (roaminvoke->forced_roaming) {
871 cmd->num_chan = 0;
872 cmd->num_bssid = 0;
873 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_CACHE_MAP;
874 }
875
Qiwei Cai770c90f2018-09-17 19:17:13 +0800876 buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param);
877 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
878 (sizeof(u_int32_t)));
879 channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
880 *channel_list = ch_hz;
881 buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE;
882 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
883 (sizeof(wmi_mac_addr)));
884 bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
885 WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list);
886
887 /* move to next tlv i.e. bcn_prb_buf_list */
888 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr);
889
890 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
891 sizeof(wmi_tlv_buf_len_param));
892
893 buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE);
894 buf_len_tlv->buf_len = roaminvoke->frame_len;
895
896 /* move to next tlv i.e. bcn_prb_frm */
897 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param);
898 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
899 roundup(roaminvoke->frame_len, sizeof(uint32_t)));
900
901 /* copy frame after the header */
902 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
903 roaminvoke->frame_buf,
904 roaminvoke->frame_len);
905
906 WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len);
907 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
908 buf_ptr + WMI_TLV_HDR_SIZE,
909 roaminvoke->frame_len);
910 WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"),
911 cmd->flags, cmd->roam_scan_mode,
912 cmd->roam_ap_sel_mode, cmd->roam_delay,
913 cmd->num_chan, cmd->num_bssid);
914 WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz);
915
916 wmi_mtrace(WMI_ROAM_INVOKE_CMDID, cmd->vdev_id, 0);
917 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
918 WMI_ROAM_INVOKE_CMDID)) {
919 WMI_LOGP("%s: failed to send roam invoke command", __func__);
920 wmi_buf_free(wmi_buf);
921 return QDF_STATUS_E_FAILURE;
922 }
923
924 return QDF_STATUS_SUCCESS;
925}
926
927void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
928{
929 struct wmi_ops *ops = wmi_handle->ops;
930
931 ops->send_set_ric_req_cmd = send_set_ric_req_cmd_tlv;
932 ops->send_process_roam_synch_complete_cmd =
933 send_process_roam_synch_complete_cmd_tlv;
934 ops->send_roam_invoke_cmd = send_roam_invoke_cmd_tlv;
935}
936#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
937
938#if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
939/**
940 * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command
941 * @wmi_handle: wmi handle
942 * @roam_req: Roam scan offload params
943 * @buf_ptr: command buffer to send
944 * @fils_tlv_len: fils tlv length
945 *
946 * Return: Updated buffer pointer
947 */
948static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
949 struct roam_offload_scan_params *roam_req,
950 uint8_t *buf_ptr, uint32_t fils_tlv_len)
951{
952 wmi_roam_fils_offload_tlv_param *fils_tlv;
953 wmi_erp_info *erp_info;
954 struct roam_fils_params *roam_fils_params;
955
956 if (!roam_req->add_fils_tlv)
957 return buf_ptr;
958
959 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
960 sizeof(*fils_tlv));
961 buf_ptr += WMI_TLV_HDR_SIZE;
962
963 fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr;
964 WMITLV_SET_HDR(&fils_tlv->tlv_header,
965 WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param,
966 WMITLV_GET_STRUCT_TLVLEN
967 (wmi_roam_fils_offload_tlv_param));
968
969 roam_fils_params = &roam_req->roam_fils_params;
970 erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info);
971
972 erp_info->username_length = roam_fils_params->username_length;
973 qdf_mem_copy(erp_info->username, roam_fils_params->username,
974 erp_info->username_length);
975
976 erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num;
977
978 erp_info->rRk_length = roam_fils_params->rrk_length;
979 qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk,
980 erp_info->rRk_length);
981
982 erp_info->rIk_length = roam_fils_params->rik_length;
983 qdf_mem_copy(erp_info->rIk, roam_fils_params->rik,
984 erp_info->rIk_length);
985
986 erp_info->realm_len = roam_fils_params->realm_len;
987 qdf_mem_copy(erp_info->realm, roam_fils_params->realm,
988 erp_info->realm_len);
989
990 buf_ptr += sizeof(*fils_tlv);
991 return buf_ptr;
992}
993#else
994static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
995 struct roam_offload_scan_params *roam_req,
996 uint8_t *buf_ptr, uint32_t fils_tlv_len)
997{
998 return buf_ptr;
999}
1000#endif
1001
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301002#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1003/**
1004 * fill_roam_offload_11r_params() - Fill roam scan params to send it to fw
1005 * @auth_mode: Authentication mode
1006 * @roam_offload_11r: TLV to be filled with 11r params
1007 * @roam_req: roam request param
1008 */
1009static void
1010fill_roam_offload_11r_params(uint32_t auth_mode,
1011 wmi_roam_11r_offload_tlv_param *roam_offload_11r,
1012 struct roam_offload_scan_params *roam_req)
1013{
1014 uint8_t *psk_msk, len;
1015
1016 if (auth_mode == WMI_AUTH_FT_RSNA_FILS_SHA256 ||
1017 auth_mode == WMI_AUTH_FT_RSNA_FILS_SHA384) {
1018 psk_msk = roam_req->roam_fils_params.fils_ft;
1019 len = roam_req->roam_fils_params.fils_ft_len;
1020 } else {
1021 psk_msk = roam_req->psk_pmk;
1022 len = roam_req->pmk_len;
1023 }
1024
1025 /*
1026 * For SHA384 based akm, the pmk length is 48 bytes. So fill
1027 * first 32 bytes in roam_offload_11r->psk_msk and the remaining
1028 * bytes in roam_offload_11r->psk_msk_ext buffer
1029 */
1030 roam_offload_11r->psk_msk_len = len > ROAM_OFFLOAD_PSK_MSK_BYTES ?
1031 ROAM_OFFLOAD_PSK_MSK_BYTES : len;
1032 qdf_mem_copy(roam_offload_11r->psk_msk, psk_msk,
1033 roam_offload_11r->psk_msk_len);
1034 roam_offload_11r->psk_msk_ext_len = 0;
1035
1036 if (len > ROAM_OFFLOAD_PSK_MSK_BYTES) {
1037 roam_offload_11r->psk_msk_ext_len =
1038 len - roam_offload_11r->psk_msk_len;
1039 qdf_mem_copy(roam_offload_11r->psk_msk_ext,
1040 &psk_msk[roam_offload_11r->psk_msk_len],
1041 roam_offload_11r->psk_msk_ext_len);
1042 }
1043}
1044#endif
1045
Qiwei Cai770c90f2018-09-17 19:17:13 +08001046/**
1047 * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw
1048 * @wmi_handle: wmi handle
1049 * @scan_cmd_fp: start scan command ptr
1050 * @roam_req: roam request param
1051 *
1052 * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
1053 * of WMI_ROAM_SCAN_MODE.
1054 *
1055 * Return: QDF status
1056 */
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301057static QDF_STATUS
1058send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle,
1059 wmi_start_scan_cmd_fixed_param *scan_cmd_fp,
1060 struct roam_offload_scan_params *roam_req)
Qiwei Cai770c90f2018-09-17 19:17:13 +08001061{
1062 wmi_buf_t buf = NULL;
1063 QDF_STATUS status;
1064 int len;
1065 uint8_t *buf_ptr;
1066 wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp;
1067
1068#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1069 int auth_mode = roam_req->auth_mode;
1070 roam_offload_param *req_offload_params =
1071 &roam_req->roam_offload_params;
1072 wmi_roam_offload_tlv_param *roam_offload_params;
1073 wmi_roam_11i_offload_tlv_param *roam_offload_11i;
1074 wmi_roam_11r_offload_tlv_param *roam_offload_11r;
1075 wmi_roam_ese_offload_tlv_param *roam_offload_ese;
1076 wmi_tlv_buf_len_param *assoc_ies;
1077 uint32_t fils_tlv_len = 0;
1078#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
1079 /* Need to create a buf with roam_scan command at
1080 * front and piggyback with scan command */
1081 len = sizeof(wmi_roam_scan_mode_fixed_param) +
1082#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1083 (2 * WMI_TLV_HDR_SIZE) +
1084#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
1085 sizeof(wmi_start_scan_cmd_fixed_param);
1086#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1087 WMI_LOGD("auth_mode = %d", auth_mode);
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301088 if (roam_req->is_roam_req_valid &&
1089 roam_req->roam_offload_enabled) {
1090 len += sizeof(wmi_roam_offload_tlv_param);
1091 len += WMI_TLV_HDR_SIZE;
1092 if ((auth_mode != WMI_AUTH_NONE) &&
1093 ((auth_mode != WMI_AUTH_OPEN) ||
1094 (auth_mode == WMI_AUTH_OPEN &&
1095 roam_req->mdid.mdie_present &&
1096 roam_req->is_11r_assoc) ||
1097 roam_req->is_ese_assoc)) {
Qiwei Cai770c90f2018-09-17 19:17:13 +08001098 len += WMI_TLV_HDR_SIZE;
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301099 if (roam_req->is_ese_assoc)
1100 len += sizeof(wmi_roam_ese_offload_tlv_param);
1101 else if ((auth_mode == WMI_AUTH_FT_RSNA) ||
1102 (auth_mode == WMI_AUTH_FT_RSNA_PSK) ||
1103 (auth_mode == WMI_AUTH_FT_RSNA_SAE) ||
1104 (auth_mode ==
1105 WMI_AUTH_FT_RSNA_SUITE_B_8021X_SHA384) ||
1106 (auth_mode ==
1107 WMI_AUTH_FT_RSNA_FILS_SHA256) ||
1108 (auth_mode ==
1109 WMI_AUTH_FT_RSNA_FILS_SHA384) ||
Qiwei Cai770c90f2018-09-17 19:17:13 +08001110 (auth_mode == WMI_AUTH_OPEN &&
1111 roam_req->mdid.mdie_present &&
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301112 roam_req->is_11r_assoc))
1113 len += sizeof(wmi_roam_11r_offload_tlv_param);
Qiwei Cai770c90f2018-09-17 19:17:13 +08001114 else
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301115 len += sizeof(wmi_roam_11i_offload_tlv_param);
1116 } else {
1117 len += WMI_TLV_HDR_SIZE;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001118 }
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301119
1120 len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE)
1121 + roundup(roam_req->assoc_ie_length, sizeof(uint32_t)));
1122
1123 if (roam_req->add_fils_tlv) {
1124 fils_tlv_len = sizeof(wmi_roam_fils_offload_tlv_param);
1125 len += WMI_TLV_HDR_SIZE + fils_tlv_len;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001126 }
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301127 } else {
1128 if (roam_req->is_roam_req_valid)
1129 WMI_LOGD("%s : roam offload = %d", __func__,
1130 roam_req->roam_offload_enabled);
1131 else
1132 WMI_LOGD("%s : roam_req is NULL", __func__);
1133
1134 len += (4 * WMI_TLV_HDR_SIZE);
1135 }
1136
1137 if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled)
1138 roam_req->mode |= WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001139#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
1140
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301141 if (roam_req->mode ==
1142 (WMI_ROAM_SCAN_MODE_NONE | WMI_ROAM_SCAN_MODE_ROAMOFFLOAD))
Qiwei Cai770c90f2018-09-17 19:17:13 +08001143 len = sizeof(wmi_roam_scan_mode_fixed_param);
1144
1145 buf = wmi_buf_alloc(wmi_handle, len);
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301146 if (!buf)
Qiwei Cai770c90f2018-09-17 19:17:13 +08001147 return QDF_STATUS_E_NOMEM;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001148
1149 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1150 roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr;
1151 WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header,
1152 WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param,
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301153 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_mode_fixed_param));
Qiwei Cai770c90f2018-09-17 19:17:13 +08001154
1155 roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask =
1156 roam_req->roam_trigger_reason_bitmask;
1157 roam_scan_mode_fp->min_delay_btw_scans =
1158 WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans);
1159 roam_scan_mode_fp->roam_scan_mode = roam_req->mode;
1160 roam_scan_mode_fp->vdev_id = roam_req->vdev_id;
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301161 if (roam_req->mode ==
1162 (WMI_ROAM_SCAN_MODE_NONE | WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) {
Qiwei Cai770c90f2018-09-17 19:17:13 +08001163 roam_scan_mode_fp->flags |=
1164 WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS;
1165 goto send_roam_scan_mode_cmd;
1166 }
1167
1168 /* Fill in scan parameters suitable for roaming scan */
1169 buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param);
1170
1171 qdf_mem_copy(buf_ptr, scan_cmd_fp,
1172 sizeof(wmi_start_scan_cmd_fixed_param));
1173 /* Ensure there is no additional IEs */
1174 scan_cmd_fp->ie_len = 0;
1175 WMITLV_SET_HDR(buf_ptr,
1176 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301177 WMITLV_GET_STRUCT_TLVLEN(wmi_start_scan_cmd_fixed_param));
Qiwei Cai770c90f2018-09-17 19:17:13 +08001178#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1179 buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param);
1180 if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) {
1181 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1182 sizeof(wmi_roam_offload_tlv_param));
1183 buf_ptr += WMI_TLV_HDR_SIZE;
1184 roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr;
1185 WMITLV_SET_HDR(buf_ptr,
1186 WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param,
1187 WMITLV_GET_STRUCT_TLVLEN
1188 (wmi_roam_offload_tlv_param));
1189 roam_offload_params->prefer_5g = roam_req->prefer_5ghz;
1190 roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap;
1191 roam_offload_params->select_5g_margin =
1192 roam_req->select_5ghz_margin;
1193 roam_offload_params->handoff_delay_for_rx =
1194 req_offload_params->ho_delay_for_rx;
1195 roam_offload_params->max_mlme_sw_retries =
1196 req_offload_params->roam_preauth_retry_count;
1197 roam_offload_params->no_ack_timeout =
1198 req_offload_params->roam_preauth_no_ack_timeout;
1199 roam_offload_params->reassoc_failure_timeout =
1200 roam_req->reassoc_failure_timeout;
Pragaspathi Thilagaraj13130eb2018-12-12 18:32:46 +05301201 roam_offload_params->roam_candidate_validity_time =
1202 roam_req->rct_validity_timer;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001203
1204 /* Fill the capabilities */
1205 roam_offload_params->capability =
1206 req_offload_params->capability;
1207 roam_offload_params->ht_caps_info =
1208 req_offload_params->ht_caps_info;
1209 roam_offload_params->ampdu_param =
1210 req_offload_params->ampdu_param;
1211 roam_offload_params->ht_ext_cap =
1212 req_offload_params->ht_ext_cap;
1213 roam_offload_params->ht_txbf = req_offload_params->ht_txbf;
1214 roam_offload_params->asel_cap = req_offload_params->asel_cap;
1215 roam_offload_params->qos_caps = req_offload_params->qos_caps;
1216 roam_offload_params->qos_enabled =
1217 req_offload_params->qos_enabled;
1218 roam_offload_params->wmm_caps = req_offload_params->wmm_caps;
1219 qdf_mem_copy((uint8_t *)roam_offload_params->mcsset,
1220 (uint8_t *)req_offload_params->mcsset,
1221 ROAM_OFFLOAD_NUM_MCS_SET);
1222
1223 buf_ptr += sizeof(wmi_roam_offload_tlv_param);
1224 /* The TLV's are in the order of 11i, 11R, ESE. Hence,
1225 * they are filled in the same order.Depending on the
1226 * authentication type, the other mode TLV's are nullified
1227 * and only headers are filled.*/
1228 if ((auth_mode != WMI_AUTH_NONE) &&
1229 ((auth_mode != WMI_AUTH_OPEN) ||
1230 (auth_mode == WMI_AUTH_OPEN
1231 && roam_req->mdid.mdie_present &&
1232 roam_req->is_11r_assoc) ||
1233 roam_req->is_ese_assoc)) {
1234 if (roam_req->is_ese_assoc) {
1235 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1236 WMITLV_GET_STRUCT_TLVLEN(0));
1237 buf_ptr += WMI_TLV_HDR_SIZE;
1238 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1239 WMITLV_GET_STRUCT_TLVLEN(0));
1240 buf_ptr += WMI_TLV_HDR_SIZE;
1241 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1242 sizeof(wmi_roam_ese_offload_tlv_param));
1243 buf_ptr += WMI_TLV_HDR_SIZE;
1244 roam_offload_ese =
1245 (wmi_roam_ese_offload_tlv_param *) buf_ptr;
1246 qdf_mem_copy(roam_offload_ese->krk,
1247 roam_req->krk,
1248 sizeof(roam_req->krk));
1249 qdf_mem_copy(roam_offload_ese->btk,
1250 roam_req->btk,
1251 sizeof(roam_req->btk));
1252 WMITLV_SET_HDR(&roam_offload_ese->tlv_header,
1253 WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param,
1254 WMITLV_GET_STRUCT_TLVLEN
1255 (wmi_roam_ese_offload_tlv_param));
1256 buf_ptr +=
1257 sizeof(wmi_roam_ese_offload_tlv_param);
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301258 } else if (auth_mode == WMI_AUTH_FT_RSNA ||
1259 auth_mode == WMI_AUTH_FT_RSNA_PSK ||
1260 auth_mode == WMI_AUTH_FT_RSNA_SAE ||
1261 (auth_mode ==
1262 WMI_AUTH_FT_RSNA_SUITE_B_8021X_SHA384) ||
1263 (auth_mode ==
1264 WMI_AUTH_FT_RSNA_FILS_SHA256) ||
1265 (auth_mode ==
1266 WMI_AUTH_FT_RSNA_FILS_SHA384) ||
1267 (auth_mode == WMI_AUTH_OPEN
1268 && roam_req->mdid.mdie_present &&
1269 roam_req->is_11r_assoc)) {
Qiwei Cai770c90f2018-09-17 19:17:13 +08001270 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1271 0);
1272 buf_ptr += WMI_TLV_HDR_SIZE;
1273 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1274 sizeof(wmi_roam_11r_offload_tlv_param));
1275 buf_ptr += WMI_TLV_HDR_SIZE;
1276 roam_offload_11r =
1277 (wmi_roam_11r_offload_tlv_param *) buf_ptr;
1278 roam_offload_11r->r0kh_id_len =
1279 roam_req->rokh_id_length;
1280 qdf_mem_copy(roam_offload_11r->r0kh_id,
1281 roam_req->rokh_id,
1282 roam_offload_11r->r0kh_id_len);
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301283 fill_roam_offload_11r_params(auth_mode,
1284 roam_offload_11r,
1285 roam_req);
Qiwei Cai770c90f2018-09-17 19:17:13 +08001286 roam_offload_11r->mdie_present =
1287 roam_req->mdid.mdie_present;
1288 roam_offload_11r->mdid =
1289 roam_req->mdid.mobility_domain;
Pragaspathi Thilagaraj5132bc62019-04-25 17:30:11 +05301290 roam_offload_11r->adaptive_11r =
1291 roam_req->is_adaptive_11r;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001292 if (auth_mode == WMI_AUTH_OPEN) {
1293 /* If FT-Open ensure pmk length
1294 and r0khid len are zero */
1295 roam_offload_11r->r0kh_id_len = 0;
1296 roam_offload_11r->psk_msk_len = 0;
1297 }
1298 WMITLV_SET_HDR(&roam_offload_11r->tlv_header,
1299 WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param,
1300 WMITLV_GET_STRUCT_TLVLEN
1301 (wmi_roam_11r_offload_tlv_param));
1302 buf_ptr +=
1303 sizeof(wmi_roam_11r_offload_tlv_param);
1304 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1305 WMITLV_GET_STRUCT_TLVLEN(0));
1306 buf_ptr += WMI_TLV_HDR_SIZE;
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301307 WMI_LOGD("psk_msk_len = %d psk_msk_ext:%d",
1308 roam_offload_11r->psk_msk_len,
1309 roam_offload_11r->psk_msk_ext_len);
Qiwei Cai770c90f2018-09-17 19:17:13 +08001310 if (roam_offload_11r->psk_msk_len)
1311 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
1312 QDF_TRACE_LEVEL_DEBUG,
1313 roam_offload_11r->psk_msk,
1314 roam_offload_11r->psk_msk_len);
1315 } else {
1316 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1317 sizeof(wmi_roam_11i_offload_tlv_param));
1318 buf_ptr += WMI_TLV_HDR_SIZE;
1319 roam_offload_11i =
1320 (wmi_roam_11i_offload_tlv_param *) buf_ptr;
1321
Pragaspathi Thilagarajfc54cc72019-07-17 00:45:20 +05301322 if (roam_req->fw_okc) {
Qiwei Cai770c90f2018-09-17 19:17:13 +08001323 WMI_SET_ROAM_OFFLOAD_OKC_ENABLED
1324 (roam_offload_11i->flags);
1325 WMI_LOGI("LFR3:OKC enabled");
1326 } else {
1327 WMI_SET_ROAM_OFFLOAD_OKC_DISABLED
1328 (roam_offload_11i->flags);
1329 WMI_LOGI("LFR3:OKC disabled");
1330 }
Pragaspathi Thilagarajfc54cc72019-07-17 00:45:20 +05301331
1332 if (roam_req->fw_pmksa_cache) {
Qiwei Cai770c90f2018-09-17 19:17:13 +08001333 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED
1334 (roam_offload_11i->flags);
1335 WMI_LOGI("LFR3:PMKSA caching enabled");
1336 } else {
1337 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED
1338 (roam_offload_11i->flags);
1339 WMI_LOGI("LFR3:PMKSA caching disabled");
1340 }
1341
Abhinav Kumarb2669ba2019-12-04 11:48:10 +05301342 roam_offload_11i->pmk_len = roam_req->pmk_len >
1343 ROAM_OFFLOAD_PMK_BYTES ?
1344 ROAM_OFFLOAD_PMK_BYTES :
1345 roam_req->pmk_len;
1346
Qiwei Cai770c90f2018-09-17 19:17:13 +08001347 qdf_mem_copy(roam_offload_11i->pmk,
1348 roam_req->psk_pmk,
Abhinav Kumarb2669ba2019-12-04 11:48:10 +05301349 roam_offload_11i->pmk_len);
1350
Qiwei Cai770c90f2018-09-17 19:17:13 +08001351 WMITLV_SET_HDR(&roam_offload_11i->tlv_header,
1352 WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param,
1353 WMITLV_GET_STRUCT_TLVLEN
1354 (wmi_roam_11i_offload_tlv_param));
1355 buf_ptr +=
1356 sizeof(wmi_roam_11i_offload_tlv_param);
1357 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1358 0);
1359 buf_ptr += WMI_TLV_HDR_SIZE;
1360 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1361 0);
1362 buf_ptr += WMI_TLV_HDR_SIZE;
1363 WMI_LOGD("pmk_len = %d",
1364 roam_offload_11i->pmk_len);
1365 if (roam_offload_11i->pmk_len)
1366 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
1367 QDF_TRACE_LEVEL_DEBUG,
1368 roam_offload_11i->pmk,
1369 roam_offload_11i->pmk_len);
1370 }
1371 } else {
1372 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1373 WMITLV_GET_STRUCT_TLVLEN(0));
1374 buf_ptr += WMI_TLV_HDR_SIZE;
1375 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1376 WMITLV_GET_STRUCT_TLVLEN(0));
1377 buf_ptr += WMI_TLV_HDR_SIZE;
1378 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1379 WMITLV_GET_STRUCT_TLVLEN(0));
1380 buf_ptr += WMI_TLV_HDR_SIZE;
1381 }
1382
1383 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1384 sizeof(*assoc_ies));
1385 buf_ptr += WMI_TLV_HDR_SIZE;
1386
1387 assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr;
1388 WMITLV_SET_HDR(&assoc_ies->tlv_header,
1389 WMITLV_TAG_STRUC_wmi_tlv_buf_len_param,
1390 WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param));
1391 assoc_ies->buf_len = roam_req->assoc_ie_length;
1392
1393 buf_ptr += sizeof(*assoc_ies);
1394
1395 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
1396 roundup(assoc_ies->buf_len, sizeof(uint32_t)));
1397 buf_ptr += WMI_TLV_HDR_SIZE;
1398
1399 if (assoc_ies->buf_len != 0) {
1400 qdf_mem_copy(buf_ptr, roam_req->assoc_ie,
1401 assoc_ies->buf_len);
1402 }
1403 buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t));
1404 buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req,
1405 buf_ptr, fils_tlv_len);
1406 } else {
1407 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1408 WMITLV_GET_STRUCT_TLVLEN(0));
1409 buf_ptr += WMI_TLV_HDR_SIZE;
1410 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1411 WMITLV_GET_STRUCT_TLVLEN(0));
1412 buf_ptr += WMI_TLV_HDR_SIZE;
1413 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1414 WMITLV_GET_STRUCT_TLVLEN(0));
1415 buf_ptr += WMI_TLV_HDR_SIZE;
1416 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1417 WMITLV_GET_STRUCT_TLVLEN(0));
1418 buf_ptr += WMI_TLV_HDR_SIZE;
1419 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1420 WMITLV_GET_STRUCT_TLVLEN(0));
1421 buf_ptr += WMI_TLV_HDR_SIZE;
1422 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
1423 WMITLV_GET_STRUCT_TLVLEN(0));
1424 }
1425#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
1426
1427send_roam_scan_mode_cmd:
1428 wmi_mtrace(WMI_ROAM_SCAN_MODE, NO_SESSION, 0);
1429 status = wmi_unified_cmd_send(wmi_handle, buf,
1430 len, WMI_ROAM_SCAN_MODE);
Pragaspathi Thilagaraj69e39d92019-03-16 18:06:22 +05301431 if (QDF_IS_STATUS_ERROR(status))
Qiwei Cai770c90f2018-09-17 19:17:13 +08001432 wmi_buf_free(buf);
Qiwei Cai770c90f2018-09-17 19:17:13 +08001433
1434 return status;
1435}
1436
1437/**
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301438 * convert_roam_trigger_reason() - Function to convert unified Roam trigger
1439 * enum to TLV specific WMI_ROAM_TRIGGER_REASON_ID
1440 * @reason: Roam trigger reason
1441 *
1442 * Return: WMI_ROAM_TRIGGER_REASON_ID
1443 */
1444static WMI_ROAM_TRIGGER_REASON_ID
1445convert_roam_trigger_reason(enum roam_trigger_reason trigger_reason) {
1446
1447 switch (trigger_reason) {
1448 case ROAM_TRIGGER_REASON_NONE:
1449 return WMI_ROAM_TRIGGER_REASON_NONE;
1450 case ROAM_TRIGGER_REASON_PER:
1451 return WMI_ROAM_TRIGGER_REASON_PER;
1452 case ROAM_TRIGGER_REASON_BMISS:
1453 return WMI_ROAM_TRIGGER_REASON_BMISS;
1454 case ROAM_TRIGGER_REASON_LOW_RSSI:
1455 return WMI_ROAM_TRIGGER_REASON_LOW_RSSI;
1456 case ROAM_TRIGGER_REASON_HIGH_RSSI:
1457 return WMI_ROAM_TRIGGER_REASON_HIGH_RSSI;
1458 case ROAM_TRIGGER_REASON_PERIODIC:
1459 return WMI_ROAM_TRIGGER_REASON_PERIODIC;
1460 case ROAM_TRIGGER_REASON_MAWC:
1461 return WMI_ROAM_TRIGGER_REASON_MAWC;
1462 case ROAM_TRIGGER_REASON_DENSE:
1463 return WMI_ROAM_TRIGGER_REASON_DENSE;
1464 case ROAM_TRIGGER_REASON_BACKGROUND:
1465 return WMI_ROAM_TRIGGER_REASON_BACKGROUND;
1466 case ROAM_TRIGGER_REASON_FORCED:
1467 return WMI_ROAM_TRIGGER_REASON_FORCED;
1468 case ROAM_TRIGGER_REASON_BTM:
1469 return WMI_ROAM_TRIGGER_REASON_BTM;
1470 case ROAM_TRIGGER_REASON_UNIT_TEST:
1471 return WMI_ROAM_TRIGGER_REASON_UNIT_TEST;
1472 case ROAM_TRIGGER_REASON_BSS_LOAD:
1473 return WMI_ROAM_TRIGGER_REASON_BSS_LOAD;
1474 case ROAM_TRIGGER_REASON_DEAUTH:
1475 return WMI_ROAM_TRIGGER_REASON_DEAUTH;
1476 case ROAM_TRIGGER_REASON_IDLE:
1477 return WMI_ROAM_TRIGGER_REASON_IDLE;
1478 case ROAM_TRIGGER_REASON_MAX:
1479 return WMI_ROAM_TRIGGER_REASON_MAX;
1480 default:
1481 return WMI_ROAM_TRIGGER_REASON_NONE;
1482 }
1483}
1484
1485/**
Qiwei Cai770c90f2018-09-17 19:17:13 +08001486 * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw
1487 * @wmi_handle: wmi handle
1488 * @ap_profile_p: ap profile
Qiwei Cai770c90f2018-09-17 19:17:13 +08001489 *
1490 * Send WMI_ROAM_AP_PROFILE to firmware
1491 *
1492 * Return: CDF status
1493 */
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301494static QDF_STATUS
1495send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
1496 struct ap_profile_params *ap_profile)
Qiwei Cai770c90f2018-09-17 19:17:13 +08001497{
1498 wmi_buf_t buf = NULL;
1499 QDF_STATUS status;
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301500 size_t len;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001501 uint8_t *buf_ptr;
1502 wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp;
1503 wmi_roam_cnd_scoring_param *score_param;
1504 wmi_ap_profile *profile;
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301505 wmi_roam_score_delta_param *score_delta_param;
1506 wmi_roam_cnd_min_rssi_param *min_rssi_param;
1507 enum roam_trigger_reason trig_reason;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001508
1509 len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile);
1510 len += sizeof(*score_param);
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301511 len += WMI_TLV_HDR_SIZE;
1512 len += NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param);
1513 len += WMI_TLV_HDR_SIZE;
1514 len += NUM_OF_ROAM_TRIGGERS * sizeof(*min_rssi_param);
Qiwei Cai770c90f2018-09-17 19:17:13 +08001515 buf = wmi_buf_alloc(wmi_handle, len);
1516 if (!buf) {
1517 return QDF_STATUS_E_NOMEM;
1518 }
1519
1520 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1521 roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr;
1522 WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header,
1523 WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param,
1524 WMITLV_GET_STRUCT_TLVLEN
1525 (wmi_roam_ap_profile_fixed_param));
1526 /* fill in threshold values */
1527 roam_ap_profile_fp->vdev_id = ap_profile->vdev_id;
1528 roam_ap_profile_fp->id = 0;
1529 buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param);
1530
1531 profile = (wmi_ap_profile *)buf_ptr;
1532 WMITLV_SET_HDR(&profile->tlv_header,
1533 WMITLV_TAG_STRUC_wmi_ap_profile,
1534 WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile));
1535 profile->flags = ap_profile->profile.flags;
1536 profile->rssi_threshold = ap_profile->profile.rssi_threshold;
1537 profile->ssid.ssid_len = ap_profile->profile.ssid.length;
1538 qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid,
1539 profile->ssid.ssid_len);
1540 profile->rsn_authmode = ap_profile->profile.rsn_authmode;
1541 profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset;
1542 profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset;
1543 profile->rsn_mcastmgmtcipherset =
1544 ap_profile->profile.rsn_mcastmgmtcipherset;
1545 profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh;
1546
1547 WMI_LOGD("AP profile: flags %x rssi_threshold %d ssid:%.*s authmode %d uc cipher %d mc cipher %d mc mgmt cipher %d rssi abs thresh %d",
1548 profile->flags, profile->rssi_threshold,
1549 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid,
1550 profile->rsn_authmode, profile->rsn_ucastcipherset,
1551 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset,
1552 profile->rssi_abs_thresh);
1553
1554 buf_ptr += sizeof(wmi_ap_profile);
1555
1556 score_param = (wmi_roam_cnd_scoring_param *)buf_ptr;
1557 WMITLV_SET_HDR(&score_param->tlv_header,
1558 WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param,
1559 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param));
1560 score_param->disable_bitmap = ap_profile->param.disable_bitmap;
1561 score_param->rssi_weightage_pcnt =
1562 ap_profile->param.rssi_weightage;
1563 score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage;
1564 score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage;
1565 score_param->he_weightage_pcnt = ap_profile->param.he_weightage;
1566 score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage;
1567 score_param->band_weightage_pcnt = ap_profile->param.band_weightage;
1568 score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage;
1569 score_param->esp_qbss_weightage_pcnt =
1570 ap_profile->param.esp_qbss_weightage;
1571 score_param->beamforming_weightage_pcnt =
1572 ap_profile->param.beamforming_weightage;
1573 score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage;
1574 score_param->oce_wan_weightage_pcnt =
1575 ap_profile->param.oce_wan_weightage;
sheenam monga446837d2019-08-28 21:11:46 +05301576 score_param->vendor_roam_score_algorithm_id =
1577 ap_profile->param.vendor_roam_score_algorithm;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001578
sheenam monga446837d2019-08-28 21:11:46 +05301579 WMI_LOGD("Score params weightage: disable_bitmap %x rssi %d ht %d vht %d he %d BW %d band %d NSS %d ESP %d BF %d PCL %d OCE WAN %d roam score algo %d",
Qiwei Cai770c90f2018-09-17 19:17:13 +08001580 score_param->disable_bitmap, score_param->rssi_weightage_pcnt,
1581 score_param->ht_weightage_pcnt,
1582 score_param->vht_weightage_pcnt,
1583 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt,
1584 score_param->band_weightage_pcnt,
1585 score_param->nss_weightage_pcnt,
1586 score_param->esp_qbss_weightage_pcnt,
1587 score_param->beamforming_weightage_pcnt,
1588 score_param->pcl_weightage_pcnt,
sheenam monga446837d2019-08-28 21:11:46 +05301589 score_param->oce_wan_weightage_pcnt,
1590 score_param->vendor_roam_score_algorithm_id);
Qiwei Cai770c90f2018-09-17 19:17:13 +08001591
1592 score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score;
1593 score_param->band_scoring.score_pcnt =
1594 ap_profile->param.band_index_score;
1595 score_param->nss_scoring.score_pcnt =
1596 ap_profile->param.nss_index_score;
1597
1598 WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x",
1599 score_param->bw_scoring.score_pcnt,
1600 score_param->band_scoring.score_pcnt,
1601 score_param->nss_scoring.score_pcnt);
1602
1603 score_param->rssi_scoring.best_rssi_threshold =
1604 (-1) * ap_profile->param.rssi_scoring.best_rssi_threshold;
1605 score_param->rssi_scoring.good_rssi_threshold =
1606 (-1) * ap_profile->param.rssi_scoring.good_rssi_threshold;
1607 score_param->rssi_scoring.bad_rssi_threshold =
1608 (-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold;
1609 score_param->rssi_scoring.good_rssi_pcnt =
1610 ap_profile->param.rssi_scoring.good_rssi_pcnt;
1611 score_param->rssi_scoring.bad_rssi_pcnt =
1612 ap_profile->param.rssi_scoring.bad_rssi_pcnt;
1613 score_param->rssi_scoring.good_bucket_size =
1614 ap_profile->param.rssi_scoring.good_bucket_size;
1615 score_param->rssi_scoring.bad_bucket_size =
1616 ap_profile->param.rssi_scoring.bad_bucket_size;
1617 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh =
1618 (-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh;
1619
1620 WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d",
1621 score_param->rssi_scoring.best_rssi_threshold,
1622 score_param->rssi_scoring.good_rssi_threshold,
1623 score_param->rssi_scoring.bad_rssi_threshold,
1624 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh);
1625 WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d",
1626 score_param->rssi_scoring.good_rssi_pcnt,
1627 score_param->rssi_scoring.bad_rssi_pcnt,
1628 score_param->rssi_scoring.good_bucket_size,
1629 score_param->rssi_scoring.bad_bucket_size);
1630
1631 score_param->esp_qbss_scoring.num_slot =
1632 ap_profile->param.esp_qbss_scoring.num_slot;
1633 score_param->esp_qbss_scoring.score_pcnt3_to_0 =
1634 ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0;
1635 score_param->esp_qbss_scoring.score_pcnt7_to_4 =
1636 ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4;
1637 score_param->esp_qbss_scoring.score_pcnt11_to_8 =
1638 ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8;
1639 score_param->esp_qbss_scoring.score_pcnt15_to_12 =
1640 ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12;
1641
1642 WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
1643 score_param->esp_qbss_scoring.num_slot,
1644 score_param->esp_qbss_scoring.score_pcnt3_to_0,
1645 score_param->esp_qbss_scoring.score_pcnt7_to_4,
1646 score_param->esp_qbss_scoring.score_pcnt11_to_8,
1647 score_param->esp_qbss_scoring.score_pcnt15_to_12);
1648
1649 score_param->oce_wan_scoring.num_slot =
1650 ap_profile->param.oce_wan_scoring.num_slot;
1651 score_param->oce_wan_scoring.score_pcnt3_to_0 =
1652 ap_profile->param.oce_wan_scoring.score_pcnt3_to_0;
1653 score_param->oce_wan_scoring.score_pcnt7_to_4 =
1654 ap_profile->param.oce_wan_scoring.score_pcnt7_to_4;
1655 score_param->oce_wan_scoring.score_pcnt11_to_8 =
1656 ap_profile->param.oce_wan_scoring.score_pcnt11_to_8;
1657 score_param->oce_wan_scoring.score_pcnt15_to_12 =
1658 ap_profile->param.oce_wan_scoring.score_pcnt15_to_12;
1659
1660 WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
1661 score_param->oce_wan_scoring.num_slot,
1662 score_param->oce_wan_scoring.score_pcnt3_to_0,
1663 score_param->oce_wan_scoring.score_pcnt7_to_4,
1664 score_param->oce_wan_scoring.score_pcnt11_to_8,
1665 score_param->oce_wan_scoring.score_pcnt15_to_12);
1666
Pragaspathi Thilagaraj2937e1a2018-12-12 16:12:07 +05301667 score_param->roam_score_delta_pcnt = ap_profile->param.roam_score_delta;
1668 score_param->roam_score_delta_mask =
1669 ap_profile->param.roam_trigger_bitmap;
1670 WMI_LOGD("Roam score delta:%d Roam_trigger_bitmap:%x",
1671 score_param->roam_score_delta_pcnt,
1672 score_param->roam_score_delta_mask);
1673
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301674 buf_ptr += sizeof(*score_param);
1675 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1676 (NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param)));
1677 buf_ptr += WMI_TLV_HDR_SIZE;
1678
1679 score_delta_param = (wmi_roam_score_delta_param *)buf_ptr;
1680 WMITLV_SET_HDR(&score_delta_param->tlv_header,
1681 WMITLV_TAG_STRUC_wmi_roam_score_delta_param,
1682 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_score_delta_param));
1683 trig_reason =
1684 ap_profile->score_delta_param[IDLE_ROAM_TRIGGER].trigger_reason;
1685 score_delta_param->roam_trigger_reason =
1686 convert_roam_trigger_reason(trig_reason);
1687 score_delta_param->roam_score_delta =
1688 ap_profile->score_delta_param[IDLE_ROAM_TRIGGER].roam_score_delta;
1689
1690 buf_ptr += sizeof(*score_delta_param);
1691 score_delta_param = (wmi_roam_score_delta_param *)buf_ptr;
1692 WMITLV_SET_HDR(&score_delta_param->tlv_header,
1693 WMITLV_TAG_STRUC_wmi_roam_score_delta_param,
1694 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_score_delta_param));
1695 trig_reason =
1696 ap_profile->score_delta_param[BTM_ROAM_TRIGGER].trigger_reason;
1697 score_delta_param->roam_trigger_reason =
1698 convert_roam_trigger_reason(trig_reason);
1699 score_delta_param->roam_score_delta =
1700 ap_profile->score_delta_param[BTM_ROAM_TRIGGER].roam_score_delta;
1701
1702 buf_ptr += sizeof(*score_delta_param);
1703 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1704 (NUM_OF_ROAM_TRIGGERS * sizeof(*min_rssi_param)));
1705 buf_ptr += WMI_TLV_HDR_SIZE;
1706
1707 min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr;
1708 WMITLV_SET_HDR(&min_rssi_param->tlv_header,
1709 WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param,
1710 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param));
1711 trig_reason =
1712 ap_profile->min_rssi_params[DEAUTH_MIN_RSSI].trigger_reason;
1713 min_rssi_param->roam_trigger_reason =
1714 convert_roam_trigger_reason(trig_reason);
1715 min_rssi_param->candidate_min_rssi =
1716 ap_profile->min_rssi_params[DEAUTH_MIN_RSSI].min_rssi;
1717
1718 buf_ptr += sizeof(*min_rssi_param);
1719 min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr;
1720 WMITLV_SET_HDR(&min_rssi_param->tlv_header,
1721 WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param,
1722 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param));
1723 trig_reason =
1724 ap_profile->min_rssi_params[BMISS_MIN_RSSI].trigger_reason;
1725 min_rssi_param->roam_trigger_reason =
1726 convert_roam_trigger_reason(trig_reason);
1727 min_rssi_param->candidate_min_rssi =
1728 ap_profile->min_rssi_params[BMISS_MIN_RSSI].min_rssi;
1729
Qiwei Cai770c90f2018-09-17 19:17:13 +08001730 wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0);
1731 status = wmi_unified_cmd_send(wmi_handle, buf,
1732 len, WMI_ROAM_AP_PROFILE);
1733 if (QDF_IS_STATUS_ERROR(status)) {
1734 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d",
1735 status);
1736 wmi_buf_free(buf);
1737 }
1738
1739 WMI_LOGD("WMI --> WMI_ROAM_AP_PROFILE and other parameters");
1740
1741 return status;
1742}
1743
1744/**
1745 * send_roam_scan_offload_cmd_tlv() - set roam offload command
1746 * @wmi_handle: wmi handle
1747 * @command: command
1748 * @vdev_id: vdev id
1749 *
1750 * This function set roam offload command to fw.
1751 *
1752 * Return: CDF status
1753 */
1754static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle,
1755 uint32_t command, uint32_t vdev_id)
1756{
1757 QDF_STATUS status;
1758 wmi_roam_scan_cmd_fixed_param *cmd_fp;
1759 wmi_buf_t buf = NULL;
1760 int len;
1761 uint8_t *buf_ptr;
1762
1763 len = sizeof(wmi_roam_scan_cmd_fixed_param);
1764 buf = wmi_buf_alloc(wmi_handle, len);
1765 if (!buf) {
1766 return QDF_STATUS_E_NOMEM;
1767 }
1768
1769 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1770
1771 cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr;
1772 WMITLV_SET_HDR(&cmd_fp->tlv_header,
1773 WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param,
1774 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param));
1775 cmd_fp->vdev_id = vdev_id;
1776 cmd_fp->command_arg = command;
1777
1778 wmi_mtrace(WMI_ROAM_SCAN_CMD, NO_SESSION, 0);
1779 status = wmi_unified_cmd_send(wmi_handle, buf,
1780 len, WMI_ROAM_SCAN_CMD);
1781 if (QDF_IS_STATUS_ERROR(status)) {
1782 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d",
1783 status);
1784 goto error;
1785 }
1786
1787 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__);
1788 return QDF_STATUS_SUCCESS;
1789
1790error:
1791 wmi_buf_free(buf);
1792
1793 return status;
1794}
1795
1796/**
1797 * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period
1798 * @wmi_handle: wmi handle
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301799 * @param: roam scan parameters to be sent to firmware
Qiwei Cai770c90f2018-09-17 19:17:13 +08001800 *
1801 * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
1802 *
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301803 * Return: QDF status
Qiwei Cai770c90f2018-09-17 19:17:13 +08001804 */
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301805static QDF_STATUS
1806send_roam_scan_offload_scan_period_cmd_tlv(
1807 wmi_unified_t wmi_handle,
1808 struct roam_scan_period_params *param)
Qiwei Cai770c90f2018-09-17 19:17:13 +08001809{
1810 QDF_STATUS status;
1811 wmi_buf_t buf = NULL;
1812 int len;
1813 uint8_t *buf_ptr;
1814 wmi_roam_scan_period_fixed_param *scan_period_fp;
1815
1816 /* Send scan period values */
1817 len = sizeof(wmi_roam_scan_period_fixed_param);
1818 buf = wmi_buf_alloc(wmi_handle, len);
1819 if (!buf) {
1820 return QDF_STATUS_E_NOMEM;
1821 }
1822
1823 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1824 scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr;
1825 WMITLV_SET_HDR(&scan_period_fp->tlv_header,
1826 WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param,
1827 WMITLV_GET_STRUCT_TLVLEN
1828 (wmi_roam_scan_period_fixed_param));
1829 /* fill in scan period values */
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301830 scan_period_fp->vdev_id = param->vdev_id;
Srinivas Dasari5276ece2019-08-04 23:26:30 +05301831 scan_period_fp->roam_scan_period = param->scan_period;
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301832 scan_period_fp->roam_scan_age = param->scan_age;
1833 scan_period_fp->inactivity_time_period =
1834 param->roam_scan_inactivity_time;
1835 scan_period_fp->roam_inactive_count =
1836 param->roam_inactive_data_packet_count;
1837 scan_period_fp->roam_scan_period_after_inactivity =
1838 param->roam_scan_period_after_inactivity;
Srinivas Dasari5276ece2019-08-04 23:26:30 +05301839 /* Firmware expects the full scan preriod in msec whereas host
1840 * provides the same in seconds.
1841 * Convert it to msec and send to firmware
1842 */
1843 scan_period_fp->roam_full_scan_period = param->full_scan_period * 1000;
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301844
Srinivas Dasari5276ece2019-08-04 23:26:30 +05301845 WMI_LOGD("%s: roam_scan_period=%d, roam_scan_age=%d, full_scan_period= %u",
1846 __func__, scan_period_fp->roam_scan_period,
1847 scan_period_fp->roam_scan_age,
1848 scan_period_fp->roam_full_scan_period);
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301849 WMI_LOGD("%s: inactiviy period:%d inactive count:%d period after inactivity:%d",
1850 __func__, scan_period_fp->inactivity_time_period,
1851 scan_period_fp->roam_inactive_count,
1852 scan_period_fp->roam_scan_period_after_inactivity);
Qiwei Cai770c90f2018-09-17 19:17:13 +08001853
1854 wmi_mtrace(WMI_ROAM_SCAN_PERIOD, NO_SESSION, 0);
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301855 status = wmi_unified_cmd_send(wmi_handle, buf, len,
1856 WMI_ROAM_SCAN_PERIOD);
Qiwei Cai770c90f2018-09-17 19:17:13 +08001857 if (QDF_IS_STATUS_ERROR(status)) {
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05301858 wmi_buf_free(buf);
1859 return status;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001860 }
1861
Qiwei Cai770c90f2018-09-17 19:17:13 +08001862 return QDF_STATUS_SUCCESS;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001863}
1864
1865/**
1866 * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list
1867 * @wmi_handle: wmi handle
1868 * @chan_count: channel count
1869 * @chan_list: channel list
1870 * @list_type: list type
1871 * @vdev_id: vdev id
1872 *
1873 * Set roam offload channel list.
1874 *
1875 * Return: CDF status
1876 */
1877static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
1878 uint8_t chan_count,
1879 uint32_t *chan_list,
1880 uint8_t list_type, uint32_t vdev_id)
1881{
1882 wmi_buf_t buf = NULL;
1883 QDF_STATUS status;
1884 int len, list_tlv_len;
1885 int i;
1886 uint8_t *buf_ptr;
1887 wmi_roam_chan_list_fixed_param *chan_list_fp;
1888 uint32_t *roam_chan_list_array;
1889
Qiwei Cai770c90f2018-09-17 19:17:13 +08001890 /* Channel list is a table of 2 TLV's */
1891 list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t);
1892 len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len;
1893 buf = wmi_buf_alloc(wmi_handle, len);
1894 if (!buf) {
1895 return QDF_STATUS_E_NOMEM;
1896 }
1897
1898 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1899 chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr;
1900 WMITLV_SET_HDR(&chan_list_fp->tlv_header,
1901 WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param,
1902 WMITLV_GET_STRUCT_TLVLEN
1903 (wmi_roam_chan_list_fixed_param));
1904 chan_list_fp->vdev_id = vdev_id;
1905 chan_list_fp->num_chan = chan_count;
Abhishek Amburefac1d4e2019-12-04 17:34:31 +05301906 if (list_type == WMI_CHANNEL_LIST_STATIC) {
Qiwei Cai770c90f2018-09-17 19:17:13 +08001907 /* external app is controlling channel list */
1908 chan_list_fp->chan_list_type =
1909 WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC;
1910 } else {
1911 /* umac supplied occupied channel list in LFR */
1912 chan_list_fp->chan_list_type =
1913 WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC;
1914 }
1915
1916 buf_ptr += sizeof(wmi_roam_chan_list_fixed_param);
1917 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
1918 (chan_list_fp->num_chan * sizeof(uint32_t)));
1919 roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
1920 WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan);
1921 for (i = 0; ((i < chan_list_fp->num_chan) &&
1922 (i < WMI_ROAM_MAX_CHANNELS)); i++) {
1923 roam_chan_list_array[i] = chan_list[i];
1924 WMI_LOGD("%d,", roam_chan_list_array[i]);
1925 }
1926
1927 wmi_mtrace(WMI_ROAM_CHAN_LIST, NO_SESSION, 0);
1928 status = wmi_unified_cmd_send(wmi_handle, buf,
1929 len, WMI_ROAM_CHAN_LIST);
1930 if (QDF_IS_STATUS_ERROR(status)) {
1931 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d",
1932 status);
1933 goto error;
1934 }
1935
1936 WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__);
1937 return QDF_STATUS_SUCCESS;
1938error:
1939 wmi_buf_free(buf);
1940
1941 return status;
1942}
1943
1944/**
1945 * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th
1946 * @wmi_handle: wmi handle
1947 * @rssi_change_thresh: RSSI Change threshold
1948 * @bcn_rssi_weight: beacon RSSI weight
1949 * @vdev_id: vdev id
1950 *
1951 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
1952 *
1953 * Return: CDF status
1954 */
1955static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle,
1956 uint32_t vdev_id,
1957 int32_t rssi_change_thresh,
1958 uint32_t bcn_rssi_weight,
1959 uint32_t hirssi_delay_btw_scans)
1960{
1961 wmi_buf_t buf = NULL;
1962 QDF_STATUS status;
1963 int len;
1964 uint8_t *buf_ptr;
1965 wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp;
1966
1967 /* Send rssi change parameters */
1968 len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param);
1969 buf = wmi_buf_alloc(wmi_handle, len);
1970 if (!buf) {
1971 return QDF_STATUS_E_NOMEM;
1972 }
1973
1974 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1975 rssi_change_fp =
1976 (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr;
1977 WMITLV_SET_HDR(&rssi_change_fp->tlv_header,
1978 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param,
1979 WMITLV_GET_STRUCT_TLVLEN
1980 (wmi_roam_scan_rssi_change_threshold_fixed_param));
1981 /* fill in rssi change threshold (hysteresis) values */
1982 rssi_change_fp->vdev_id = vdev_id;
1983 rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh;
1984 rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight;
1985 rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans;
1986
1987 wmi_mtrace(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, NO_SESSION, 0);
1988 status = wmi_unified_cmd_send(wmi_handle, buf,
1989 len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD);
1990 if (QDF_IS_STATUS_ERROR(status)) {
1991 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d",
1992 status);
1993 goto error;
1994 }
1995
1996 WMI_LOGD(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"),
1997 rssi_change_thresh, bcn_rssi_weight);
1998 WMI_LOGD(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans);
1999 return QDF_STATUS_SUCCESS;
2000error:
2001 wmi_buf_free(buf);
2002
2003 return status;
2004}
2005
2006/**
2007 * send_per_roam_config_cmd_tlv() - set per roaming config to FW
2008 * @wmi_handle: wmi handle
2009 * @req_buf: per roam config buffer
2010 *
2011 * Return: QDF status
2012 */
2013static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle,
2014 struct wmi_per_roam_config_req *req_buf)
2015{
2016 wmi_buf_t buf = NULL;
2017 QDF_STATUS status;
2018 int len;
2019 uint8_t *buf_ptr;
2020 wmi_roam_per_config_fixed_param *wmi_per_config;
2021
2022 len = sizeof(wmi_roam_per_config_fixed_param);
2023 buf = wmi_buf_alloc(wmi_handle, len);
2024 if (!buf) {
2025 return QDF_STATUS_E_NOMEM;
2026 }
2027
2028 buf_ptr = (uint8_t *) wmi_buf_data(buf);
2029 wmi_per_config =
2030 (wmi_roam_per_config_fixed_param *) buf_ptr;
2031 WMITLV_SET_HDR(&wmi_per_config->tlv_header,
2032 WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param,
2033 WMITLV_GET_STRUCT_TLVLEN
2034 (wmi_roam_per_config_fixed_param));
2035
2036 /* fill in per roam config values */
2037 wmi_per_config->vdev_id = req_buf->vdev_id;
2038
2039 wmi_per_config->enable = req_buf->per_config.enable;
2040 wmi_per_config->high_rate_thresh =
2041 (req_buf->per_config.tx_high_rate_thresh << 16) |
2042 (req_buf->per_config.rx_high_rate_thresh & 0x0000ffff);
2043 wmi_per_config->low_rate_thresh =
2044 (req_buf->per_config.tx_low_rate_thresh << 16) |
2045 (req_buf->per_config.rx_low_rate_thresh & 0x0000ffff);
2046 wmi_per_config->pkt_err_rate_thresh_pct =
2047 (req_buf->per_config.tx_rate_thresh_percnt << 16) |
2048 (req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff);
2049 wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time;
2050 wmi_per_config->pkt_err_rate_mon_time =
2051 (req_buf->per_config.tx_per_mon_time << 16) |
2052 (req_buf->per_config.rx_per_mon_time & 0x0000ffff);
2053 wmi_per_config->min_candidate_rssi =
2054 req_buf->per_config.min_candidate_rssi;
2055
2056 /* Send per roam config parameters */
2057 wmi_mtrace(WMI_ROAM_PER_CONFIG_CMDID, NO_SESSION, 0);
2058 status = wmi_unified_cmd_send(wmi_handle, buf,
2059 len, WMI_ROAM_PER_CONFIG_CMDID);
2060 if (QDF_IS_STATUS_ERROR(status)) {
2061 WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d",
2062 status);
2063 wmi_buf_free(buf);
2064 return status;
2065 }
2066 WMI_LOGD(FL("per roam enable=%d, vdev=%d"),
2067 req_buf->per_config.enable, req_buf->vdev_id);
2068
2069 return QDF_STATUS_SUCCESS;
2070}
2071
2072/**
2073 * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan
2074 * configuration params
2075 * @wmi_handle: wmi handler
2076 * @limit_off_chan_param: pointer to wmi_off_chan_param
2077 *
2078 * Return: 0 for success and non zero for failure
2079 */
2080static
2081QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle,
2082 struct wmi_limit_off_chan_param *limit_off_chan_param)
2083{
2084 wmi_vdev_limit_offchan_cmd_fixed_param *cmd;
2085 wmi_buf_t buf;
2086 uint32_t len = sizeof(*cmd);
2087 int err;
2088
2089 buf = wmi_buf_alloc(wmi_handle, len);
2090 if (!buf) {
2091 return QDF_STATUS_E_NOMEM;
2092 }
2093
2094 cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf);
2095
2096 WMITLV_SET_HDR(&cmd->tlv_header,
2097 WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param,
2098 WMITLV_GET_STRUCT_TLVLEN(
2099 wmi_vdev_limit_offchan_cmd_fixed_param));
2100
2101 cmd->vdev_id = limit_off_chan_param->vdev_id;
2102
2103 cmd->flags &= 0;
2104 if (limit_off_chan_param->status)
2105 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE;
2106 if (limit_off_chan_param->skip_dfs_chans)
2107 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS;
2108
2109 cmd->max_offchan_time = limit_off_chan_param->max_offchan_time;
2110 cmd->rest_time = limit_off_chan_param->rest_time;
2111
2112 WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d",
2113 __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time,
2114 cmd->rest_time);
2115
2116 wmi_mtrace(WMI_VDEV_LIMIT_OFFCHAN_CMDID, cmd->vdev_id, 0);
2117 err = wmi_unified_cmd_send(wmi_handle, buf,
2118 len, WMI_VDEV_LIMIT_OFFCHAN_CMDID);
2119 if (QDF_IS_STATUS_ERROR(err)) {
2120 WMI_LOGE("Failed to send limit off chan cmd err=%d", err);
2121 wmi_buf_free(buf);
2122 return QDF_STATUS_E_FAILURE;
2123 }
2124
2125 return QDF_STATUS_SUCCESS;
2126}
2127
2128#ifdef WLAN_FEATURE_FILS_SK
2129static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle,
2130 struct hlp_params *params)
2131{
2132 uint32_t len;
2133 uint8_t *buf_ptr;
2134 wmi_buf_t buf = NULL;
2135 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params;
2136
2137 len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param);
2138 len += WMI_TLV_HDR_SIZE;
2139 len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t));
2140
2141 buf = wmi_buf_alloc(wmi_handle, len);
2142 if (!buf) {
2143 return QDF_STATUS_E_NOMEM;
2144 }
2145
2146 buf_ptr = (uint8_t *) wmi_buf_data(buf);
2147 hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr;
2148 WMITLV_SET_HDR(&hlp_params->tlv_header,
2149 WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param,
2150 WMITLV_GET_STRUCT_TLVLEN(
2151 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param));
2152
2153 hlp_params->vdev_id = params->vdev_id;
2154 hlp_params->size = params->hlp_ie_len;
2155 hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER;
2156
2157 buf_ptr += sizeof(*hlp_params);
2158
2159 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2160 round_up(params->hlp_ie_len,
2161 sizeof(uint32_t)));
2162 buf_ptr += WMI_TLV_HDR_SIZE;
2163 qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len);
2164
2165 WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"),
2166 hlp_params->vdev_id, hlp_params->size);
2167 wmi_mtrace(WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID, NO_SESSION, 0);
2168 if (wmi_unified_cmd_send(wmi_handle, buf, len,
2169 WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) {
2170 WMI_LOGE(FL("Failed to send FILS HLP pkt cmd"));
2171 wmi_buf_free(buf);
2172 return QDF_STATUS_E_FAILURE;
2173 }
2174
2175 return QDF_STATUS_SUCCESS;
2176}
2177
2178void wmi_fils_sk_attach_tlv(wmi_unified_t wmi_handle)
2179{
2180 struct wmi_ops *ops = wmi_handle->ops;
2181
2182 ops->send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv;
2183}
2184#endif /* WLAN_FEATURE_FILS_SK */
2185
2186/*
2187 * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config
2188 * @wmi_handle: wmi handle
2189 * @params: pointer to wmi_btm_config
2190 *
2191 * Return: QDF_STATUS
2192 */
2193static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle,
2194 struct wmi_btm_config *params)
2195{
2196
2197 wmi_btm_config_fixed_param *cmd;
2198 wmi_buf_t buf;
2199 uint32_t len;
2200
2201 len = sizeof(*cmd);
2202 buf = wmi_buf_alloc(wmi_handle, len);
2203 if (!buf) {
2204 return QDF_STATUS_E_NOMEM;
2205 }
2206
2207 cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf);
2208 WMITLV_SET_HDR(&cmd->tlv_header,
2209 WMITLV_TAG_STRUC_wmi_btm_config_fixed_param,
2210 WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param));
2211 cmd->vdev_id = params->vdev_id;
2212 cmd->flags = params->btm_offload_config;
2213 cmd->max_attempt_cnt = params->btm_max_attempt_cnt;
2214 cmd->solicited_timeout_ms = params->btm_solicited_timeout;
2215 cmd->stick_time_seconds = params->btm_sticky_time;
Pragaspathi Thilagaraj13130eb2018-12-12 18:32:46 +05302216 cmd->disassoc_timer_threshold = params->disassoc_timer_threshold;
Abhinav Kumara211a9d2019-03-01 19:02:39 +05302217 cmd->btm_bitmap = params->btm_query_bitmask;
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05302218 cmd->btm_candidate_min_score = params->btm_candidate_min_score;
Qiwei Cai770c90f2018-09-17 19:17:13 +08002219
2220 wmi_mtrace(WMI_ROAM_BTM_CONFIG_CMDID, cmd->vdev_id, 0);
2221 if (wmi_unified_cmd_send(wmi_handle, buf, len,
2222 WMI_ROAM_BTM_CONFIG_CMDID)) {
2223 WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID",
2224 __func__);
2225 wmi_buf_free(buf);
2226 return QDF_STATUS_E_FAILURE;
2227 }
2228
2229 return QDF_STATUS_SUCCESS;
2230}
2231
2232/**
Pragaspathi Thilagaraj9341ee32018-12-16 23:17:10 +05302233 * send_roam_bss_load_config_tlv() - send roam load bss trigger configuration
2234 * @wmi_handle: wmi handle
2235 * @parms: pointer to wmi_bss_load_config
2236 *
2237 * This function sends the roam load bss trigger configuration to fw.
2238 * the bss_load_threshold parameter is used to configure the maximum
2239 * bss load percentage, above which the firmware should trigger roaming
2240 *
2241 * Return: QDF status
2242 */
2243static QDF_STATUS
2244send_roam_bss_load_config_tlv(wmi_unified_t wmi_handle,
2245 struct wmi_bss_load_config *params)
2246{
2247 wmi_roam_bss_load_config_cmd_fixed_param *cmd;
2248 wmi_buf_t buf;
2249 uint32_t len;
2250
2251 len = sizeof(*cmd);
2252 buf = wmi_buf_alloc(wmi_handle, len);
2253 if (!buf)
2254 return QDF_STATUS_E_NOMEM;
2255
2256 cmd = (wmi_roam_bss_load_config_cmd_fixed_param *)wmi_buf_data(buf);
2257 WMITLV_SET_HDR(
2258 &cmd->tlv_header,
2259 WMITLV_TAG_STRUC_wmi_roam_bss_load_config_cmd_fixed_param,
2260 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_bss_load_config_cmd_fixed_param));
2261 cmd->vdev_id = params->vdev_id;
2262 cmd->bss_load_threshold = params->bss_load_threshold;
Pragaspathi Thilagaraj93277252018-12-24 15:17:04 +05302263 cmd->monitor_time_window = params->bss_load_sample_time;
Pragaspathi Thilagaraj7cc507f2019-04-14 23:56:47 +05302264 cmd->rssi_2g_threshold = params->rssi_threshold_24ghz;
2265 cmd->rssi_5g_threshold = params->rssi_threshold_5ghz;
2266
2267 WMI_LOGD("%s: vdev:%d bss_load_thres:%d monitor_time:%d rssi_2g:%d rssi_5g:%d",
2268 __func__, cmd->vdev_id, cmd->bss_load_threshold,
2269 cmd->monitor_time_window, cmd->rssi_2g_threshold,
2270 cmd->rssi_5g_threshold);
Pragaspathi Thilagaraj9341ee32018-12-16 23:17:10 +05302271
2272 wmi_mtrace(WMI_ROAM_BSS_LOAD_CONFIG_CMDID, cmd->vdev_id, 0);
2273 if (wmi_unified_cmd_send(wmi_handle, buf, len,
2274 WMI_ROAM_BSS_LOAD_CONFIG_CMDID)) {
2275 WMI_LOGE("%s: failed to send WMI_ROAM_BSS_LOAD_CONFIG_CMDID ",
2276 __func__);
2277 wmi_buf_free(buf);
2278 return QDF_STATUS_E_FAILURE;
2279 }
2280
2281 return QDF_STATUS_SUCCESS;
2282}
2283
Pragaspathi Thilagaraj5e3cd0a2019-03-31 16:46:28 +05302284#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2285/**
2286 * send_disconnect_roam_params_tlv() - send disconnect roam trigger parameters
2287 * @wmi_handle: wmi handle
2288 * @disconnect_roam: pointer to wmi_disconnect_roam_params which carries the
2289 * disconnect_roam_trigger parameters from CSR
2290 *
2291 * This function sends the disconnect roam trigger parameters to fw.
2292 *
2293 * Return: QDF status
2294 */
2295static QDF_STATUS
2296send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle,
2297 struct wmi_disconnect_roam_params *req)
2298{
2299 wmi_roam_deauth_config_cmd_fixed_param *cmd;
2300 wmi_buf_t buf;
2301 uint32_t len;
2302
2303 len = sizeof(*cmd);
2304 buf = wmi_buf_alloc(wmi_handle, len);
2305 if (!buf)
2306 return QDF_STATUS_E_NOMEM;
2307
2308 cmd = (wmi_roam_deauth_config_cmd_fixed_param *)wmi_buf_data(buf);
2309 WMITLV_SET_HDR(
2310 &cmd->tlv_header,
2311 WMITLV_TAG_STRUC_wmi_roam_deauth_config_cmd_fixed_param,
2312 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_deauth_config_cmd_fixed_param));
2313
2314 cmd->vdev_id = req->vdev_id;
2315 cmd->enable = req->enable;
2316 WMI_LOGD("%s: Send WMI_ROAM_DEAUTH_CONFIG vdev_id:%d enable:%d",
2317 __func__, cmd->vdev_id, cmd->enable);
2318
2319 wmi_mtrace(WMI_ROAM_DEAUTH_CONFIG_CMDID, cmd->vdev_id, 0);
2320 if (wmi_unified_cmd_send(wmi_handle, buf, len,
2321 WMI_ROAM_DEAUTH_CONFIG_CMDID)) {
2322 WMI_LOGE("%s: failed to send WMI_ROAM_DEAUTH_CONFIG_CMDID",
2323 __func__);
2324 wmi_buf_free(buf);
2325 return QDF_STATUS_E_FAILURE;
2326 }
2327
2328 return QDF_STATUS_SUCCESS;
2329}
2330
2331/**
2332 * send_idle_roam_params_tlv() - send idle roam trigger parameters
2333 * @wmi_handle: wmi handle
2334 * @idle_roam_params: pointer to wmi_idle_roam_params which carries the
2335 * idle roam parameters from CSR
2336 *
2337 * This function sends the idle roam trigger parameters to fw.
2338 *
2339 * Return: QDF status
2340 */
2341static QDF_STATUS
2342send_idle_roam_params_tlv(wmi_unified_t wmi_handle,
2343 struct wmi_idle_roam_params *idle_roam_params)
2344{
2345 wmi_roam_idle_config_cmd_fixed_param *cmd;
2346 wmi_buf_t buf;
2347 uint32_t len;
2348
2349 len = sizeof(*cmd);
2350 buf = wmi_buf_alloc(wmi_handle, len);
2351 if (!buf)
2352 return QDF_STATUS_E_NOMEM;
2353
2354 cmd = (wmi_roam_idle_config_cmd_fixed_param *)wmi_buf_data(buf);
2355 WMITLV_SET_HDR(
2356 &cmd->tlv_header,
2357 WMITLV_TAG_STRUC_wmi_roam_idle_config_cmd_fixed_param,
2358 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_idle_config_cmd_fixed_param));
2359
2360 cmd->vdev_id = idle_roam_params->vdev_id;
2361 cmd->enable = idle_roam_params->enable;
2362 cmd->band = idle_roam_params->band;
2363 cmd->rssi_delta = idle_roam_params->conn_ap_rssi_delta;
2364 cmd->min_rssi = idle_roam_params->conn_ap_min_rssi;
2365 cmd->idle_time = idle_roam_params->inactive_time;
2366 cmd->data_packet_count = idle_roam_params->data_pkt_count;
2367 WMI_LOGD("%s: Send WMI_ROAM_IDLE_CONFIG_CMDID vdev_id:%d enable:%d",
2368 __func__, cmd->vdev_id, cmd->enable);
2369 WMI_LOGD("%s: band:%d rssi_delta:%d min_rssi:%d idle_time:%d data_pkt:%d",
2370 __func__, cmd->band, cmd->rssi_delta, cmd->min_rssi,
2371 cmd->idle_time, cmd->data_packet_count);
2372
2373 wmi_mtrace(WMI_ROAM_IDLE_CONFIG_CMDID, cmd->vdev_id, 0);
2374 if (wmi_unified_cmd_send(wmi_handle, buf, len,
2375 WMI_ROAM_IDLE_CONFIG_CMDID)) {
2376 WMI_LOGE("%s: failed to send WMI_ROAM_IDLE_CONFIG_CMDID",
2377 __func__);
2378 wmi_buf_free(buf);
2379 return QDF_STATUS_E_FAILURE;
2380 }
2381
2382 return QDF_STATUS_SUCCESS;
2383}
Pragaspathi Thilagarajfc54cc72019-07-17 00:45:20 +05302384
2385/**
2386 * send_roam_preauth_status_tlv() - send roam pre-authentication status
2387 * @wmi_handle: wmi handle
2388 * @params: pre-auth status params
2389 *
2390 * This function sends the roam pre-authentication status for WPA3 SAE
2391 * pre-auth to target.
2392 *
2393 * Return: QDF status
2394 */
2395static QDF_STATUS
2396send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
2397 struct wmi_roam_auth_status_params *params)
2398{
2399 wmi_roam_preauth_status_cmd_fixed_param *cmd;
2400 wmi_buf_t buf;
2401 uint32_t len;
2402 uint8_t *buf_ptr;
2403
2404 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + PMKID_LEN;
2405 buf = wmi_buf_alloc(wmi_handle, len);
2406 if (!buf)
2407 return QDF_STATUS_E_NOMEM;
2408
2409 buf_ptr = (uint8_t *)wmi_buf_data(buf);
2410 cmd = (wmi_roam_preauth_status_cmd_fixed_param *)buf_ptr;
2411 WMITLV_SET_HDR(
2412 &cmd->tlv_header,
2413 WMITLV_TAG_STRUC_wmi_roam_preauth_status_cmd_fixed_param,
2414 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_preauth_status_cmd_fixed_param));
2415
2416 cmd->vdev_id = params->vdev_id;
2417 cmd->preauth_status = params->preauth_status;
2418 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->bssid.bytes,
2419 &cmd->candidate_ap_bssid);
2420
2421 buf_ptr += sizeof(wmi_roam_preauth_status_cmd_fixed_param);
2422 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, PMKID_LEN);
2423 buf_ptr += WMI_TLV_HDR_SIZE;
2424
2425 qdf_mem_copy(buf_ptr, params->pmkid, PMKID_LEN);
2426 WMI_LOGD("%s: vdev_id:%d status:%d bssid:%pM", __func__, cmd->vdev_id,
2427 cmd->preauth_status, params->bssid.bytes);
2428
2429 wmi_mtrace(WMI_ROAM_PREAUTH_STATUS_CMDID, cmd->vdev_id, 0);
2430 if (wmi_unified_cmd_send(wmi_handle, buf, len,
2431 WMI_ROAM_PREAUTH_STATUS_CMDID)) {
2432 wmi_buf_free(buf);
2433 return QDF_STATUS_E_FAILURE;
2434 }
2435
2436 return QDF_STATUS_SUCCESS;
2437}
Srinivas Dasaride39f3f2019-08-14 14:41:30 +05302438
2439/**
2440 * convert_control_roam_trigger_reason_bitmap() - Convert roam trigger bitmap
2441 *
2442 * @trigger_reason_bitmap: Roam trigger reason bitmap received from upper layers
2443 *
2444 * Converts the controlled roam trigger reason bitmap of
2445 * type @roam_control_trigger_reason to firmware trigger
2446 * reason bitmap as defined in
2447 * trigger_reason_bitmask @wmi_roam_enable_disable_trigger_reason_fixed_param
2448 *
2449 * Return: trigger_reason_bitmask as defined in
2450 * wmi_roam_enable_disable_trigger_reason_fixed_param
2451 */
2452static uint32_t
2453convert_control_roam_trigger_reason_bitmap(uint32_t trigger_reason_bitmap)
2454{
2455 uint32_t fw_trigger_bitmap = 0, all_bitmap;
2456
2457 /* Enable the complete trigger bitmap when all bits are set in
2458 * the control config bitmap
2459 */
2460 all_bitmap = (ROAM_CONTROL_TRIGGER_REASON_BSS_LOAD << 1) - 1;
2461 if (trigger_reason_bitmap == all_bitmap)
2462 return (BIT(WMI_ROAM_TRIGGER_REASON_MAX) - 1);
2463
2464 if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_PER)
2465 fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PER);
2466
2467 if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BEACON_MISS)
2468 fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BMISS);
2469
2470 if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_POOR_RSSI)
2471 fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_LOW_RSSI);
2472
2473 if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BETTER_RSSI)
2474 fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_HIGH_RSSI);
2475
2476 if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_PERIODIC)
2477 fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PERIODIC);
2478
2479 if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_DENSE)
2480 fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DENSE);
2481
2482 if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BTM)
2483 fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BTM);
2484
2485 if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BSS_LOAD)
2486 fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BSS_LOAD);
2487
2488 return fw_trigger_bitmap;
2489}
2490
2491/**
2492 * get_internal_mandatory_roam_triggers() - Internal triggers to be added
2493 *
2494 * Return: the bitmap of mandatory triggers to be sent to firmware but not given
2495 * by user.
2496 */
2497static uint32_t
2498get_internal_mandatory_roam_triggers(void)
2499{
2500 return BIT(WMI_ROAM_TRIGGER_REASON_FORCED);
2501}
2502
2503/**
2504 * send_set_roam_trigger_cmd_tlv() - send set roam triggers to fw
2505 *
2506 * @wmi_handle: wmi handle
2507 * @vdev_id: vdev id
2508 * @trigger_bitmap: roam trigger bitmap to be enabled
2509 *
2510 * Send WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID to fw.
2511 *
2512 * Return: QDF_STATUS
2513 */
2514static QDF_STATUS send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle,
2515 uint32_t vdev_id,
2516 uint32_t trigger_bitmap)
2517{
2518 wmi_buf_t buf;
2519 wmi_roam_enable_disable_trigger_reason_fixed_param *cmd;
2520 uint16_t len = sizeof(*cmd);
2521 int ret;
2522
2523 buf = wmi_buf_alloc(wmi_handle, len);
2524 if (!buf) {
2525 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
2526 return QDF_STATUS_E_NOMEM;
2527 }
2528
2529 cmd = (wmi_roam_enable_disable_trigger_reason_fixed_param *)
2530 wmi_buf_data(buf);
2531 WMITLV_SET_HDR(&cmd->tlv_header,
2532 WMITLV_TAG_STRUC_wmi_roam_enable_disable_trigger_reason_fixed_param,
2533 WMITLV_GET_STRUCT_TLVLEN
2534 (wmi_roam_enable_disable_trigger_reason_fixed_param));
2535 cmd->vdev_id = vdev_id;
2536 cmd->trigger_reason_bitmask =
2537 convert_control_roam_trigger_reason_bitmap(trigger_bitmap);
2538 WMI_LOGD("Received trigger bitmap: 0x%x converted trigger_bitmap: 0x%x",
2539 trigger_bitmap, cmd->trigger_reason_bitmask);
2540 cmd->trigger_reason_bitmask |= get_internal_mandatory_roam_triggers();
2541 WMI_LOGD("WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID vdev id: %d final trigger_bitmap: 0x%x",
2542 cmd->vdev_id, cmd->trigger_reason_bitmask);
2543 wmi_mtrace(WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID, vdev_id, 0);
2544 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2545 WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID);
2546 if (QDF_IS_STATUS_ERROR(ret)) {
2547 WMI_LOGE("Failed to send set roam triggers command ret = %d",
2548 ret);
2549 wmi_buf_free(buf);
2550 }
2551 return ret;
2552}
Pragaspathi Thilagaraj5e3cd0a2019-03-31 16:46:28 +05302553#else
2554static inline QDF_STATUS
2555send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle,
2556 struct wmi_disconnect_roam_params *req)
2557{
2558 return QDF_STATUS_E_FAILURE;
2559}
2560
2561static inline QDF_STATUS
2562send_idle_roam_params_tlv(wmi_unified_t wmi_handle,
2563 struct wmi_idle_roam_params *idle_roam_params)
2564{
2565 return QDF_STATUS_E_FAILURE;
2566}
Pragaspathi Thilagarajfc54cc72019-07-17 00:45:20 +05302567
2568static inline QDF_STATUS
2569send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
2570 struct wmi_roam_auth_status_params *params)
2571{
2572 return QDF_STATUS_E_FAILURE;
2573}
Srinivas Dasaride39f3f2019-08-14 14:41:30 +05302574
2575static QDF_STATUS
2576send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle,
2577 uint32_t vdev_id,
2578 uint32_t trigger_bitmap)
2579{
2580 return QDF_STATUS_E_FAILURE;
2581}
Pragaspathi Thilagaraj5e3cd0a2019-03-31 16:46:28 +05302582#endif
2583
Pragaspathi Thilagaraj9341ee32018-12-16 23:17:10 +05302584/**
Qiwei Cai770c90f2018-09-17 19:17:13 +08002585 * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params
2586 * @wmi_handle: wmi handler
2587 * @params: pointer to 11k offload params
2588 *
2589 * Return: 0 for success and non zero for failure
2590 */
2591static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle,
2592 struct wmi_11k_offload_params *params)
2593{
2594 wmi_11k_offload_report_fixed_param *cmd;
2595 wmi_buf_t buf;
2596 QDF_STATUS status;
2597 uint8_t *buf_ptr;
2598 wmi_neighbor_report_11k_offload_tlv_param
2599 *neighbor_report_offload_params;
2600 wmi_neighbor_report_offload *neighbor_report_offload;
2601
2602 uint32_t len = sizeof(*cmd);
2603
2604 if (params->offload_11k_bitmask &
2605 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ)
2606 len += WMI_TLV_HDR_SIZE +
2607 sizeof(wmi_neighbor_report_11k_offload_tlv_param);
2608
2609 buf = wmi_buf_alloc(wmi_handle, len);
2610 if (!buf) {
2611 return QDF_STATUS_E_NOMEM;
2612 }
2613
2614 buf_ptr = (uint8_t *) wmi_buf_data(buf);
2615 cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr;
2616
2617 WMITLV_SET_HDR(&cmd->tlv_header,
2618 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param,
2619 WMITLV_GET_STRUCT_TLVLEN(
2620 wmi_11k_offload_report_fixed_param));
2621
2622 cmd->vdev_id = params->vdev_id;
2623 cmd->offload_11k = params->offload_11k_bitmask;
2624
2625 if (params->offload_11k_bitmask &
2626 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) {
2627 buf_ptr += sizeof(wmi_11k_offload_report_fixed_param);
2628
2629 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2630 sizeof(wmi_neighbor_report_11k_offload_tlv_param));
2631 buf_ptr += WMI_TLV_HDR_SIZE;
2632
2633 neighbor_report_offload_params =
2634 (wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr;
2635 WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header,
2636 WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param,
2637 WMITLV_GET_STRUCT_TLVLEN(
2638 wmi_neighbor_report_11k_offload_tlv_param));
2639
2640 neighbor_report_offload = &neighbor_report_offload_params->
2641 neighbor_rep_ofld_params;
2642
2643 neighbor_report_offload->time_offset =
2644 params->neighbor_report_params.time_offset;
2645 neighbor_report_offload->low_rssi_offset =
2646 params->neighbor_report_params.low_rssi_offset;
2647 neighbor_report_offload->bmiss_count_trigger =
2648 params->neighbor_report_params.bmiss_count_trigger;
2649 neighbor_report_offload->per_threshold_offset =
2650 params->neighbor_report_params.per_threshold_offset;
2651 neighbor_report_offload->neighbor_report_cache_timeout =
2652 params->neighbor_report_params.
2653 neighbor_report_cache_timeout;
2654 neighbor_report_offload->max_neighbor_report_req_cap =
2655 params->neighbor_report_params.
2656 max_neighbor_report_req_cap;
2657 neighbor_report_offload->ssid.ssid_len =
2658 params->neighbor_report_params.ssid.length;
2659 qdf_mem_copy(neighbor_report_offload->ssid.ssid,
2660 &params->neighbor_report_params.ssid.mac_ssid,
2661 neighbor_report_offload->ssid.ssid_len);
2662 }
2663
2664 wmi_mtrace(WMI_11K_OFFLOAD_REPORT_CMDID, cmd->vdev_id, 0);
2665 status = wmi_unified_cmd_send(wmi_handle, buf, len,
2666 WMI_11K_OFFLOAD_REPORT_CMDID);
2667 if (status != QDF_STATUS_SUCCESS) {
2668 WMI_LOGE("%s: failed to send 11k offload command %d",
2669 __func__, status);
2670 wmi_buf_free(buf);
2671 }
2672
2673 return status;
2674}
2675
2676/**
2677 * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report
2678 * command
2679 * @wmi_handle: wmi handler
2680 * @params: pointer to neighbor report invoke params
2681 *
2682 * Return: 0 for success and non zero for failure
2683 */
2684static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle,
2685 struct wmi_invoke_neighbor_report_params *params)
2686{
2687 wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd;
2688 wmi_buf_t buf;
2689 QDF_STATUS status;
2690 uint8_t *buf_ptr;
2691 uint32_t len = sizeof(*cmd);
2692
2693 buf = wmi_buf_alloc(wmi_handle, len);
2694 if (!buf) {
2695 return QDF_STATUS_E_NOMEM;
2696 }
2697
2698 buf_ptr = (uint8_t *) wmi_buf_data(buf);
2699 cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr;
2700
2701 WMITLV_SET_HDR(&cmd->tlv_header,
2702 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param,
2703 WMITLV_GET_STRUCT_TLVLEN(
2704 wmi_11k_offload_invoke_neighbor_report_fixed_param));
2705
2706 cmd->vdev_id = params->vdev_id;
2707 cmd->flags = params->send_resp_to_host;
2708
2709 cmd->ssid.ssid_len = params->ssid.length;
2710 qdf_mem_copy(cmd->ssid.ssid,
2711 &params->ssid.mac_ssid,
2712 cmd->ssid.ssid_len);
2713
2714 wmi_mtrace(WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID, cmd->vdev_id, 0);
2715 status = wmi_unified_cmd_send(wmi_handle, buf, len,
2716 WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID);
2717 if (status != QDF_STATUS_SUCCESS) {
2718 WMI_LOGE("%s: failed to send invoke neighbor report command %d",
2719 __func__, status);
2720 wmi_buf_free(buf);
2721 }
2722
2723 return status;
2724}
2725
2726void wmi_roam_attach_tlv(wmi_unified_t wmi_handle)
2727{
2728 struct wmi_ops *ops = wmi_handle->ops;
2729
2730 ops->send_roam_scan_offload_rssi_thresh_cmd =
2731 send_roam_scan_offload_rssi_thresh_cmd_tlv;
2732 ops->send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv;
2733 ops->send_roam_scan_filter_cmd =
2734 send_roam_scan_filter_cmd_tlv;
2735 ops->send_roam_scan_offload_mode_cmd =
2736 send_roam_scan_offload_mode_cmd_tlv;
2737 ops->send_roam_scan_offload_ap_profile_cmd =
2738 send_roam_scan_offload_ap_profile_cmd_tlv;
2739 ops->send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv;
2740 ops->send_roam_scan_offload_scan_period_cmd =
2741 send_roam_scan_offload_scan_period_cmd_tlv;
2742 ops->send_roam_scan_offload_chan_list_cmd =
2743 send_roam_scan_offload_chan_list_cmd_tlv;
2744 ops->send_roam_scan_offload_rssi_change_cmd =
2745 send_roam_scan_offload_rssi_change_cmd_tlv;
2746 ops->send_per_roam_config_cmd = send_per_roam_config_cmd_tlv;
2747 ops->send_limit_off_chan_cmd = send_limit_off_chan_cmd_tlv;
2748 ops->send_btm_config = send_btm_config_cmd_tlv;
2749 ops->send_offload_11k_cmd = send_offload_11k_cmd_tlv;
2750 ops->send_invoke_neighbor_report_cmd =
2751 send_invoke_neighbor_report_cmd_tlv;
Pragaspathi Thilagaraj9341ee32018-12-16 23:17:10 +05302752 ops->send_roam_bss_load_config = send_roam_bss_load_config_tlv;
Pragaspathi Thilagaraj5e3cd0a2019-03-31 16:46:28 +05302753 ops->send_idle_roam_params = send_idle_roam_params_tlv;
2754 ops->send_disconnect_roam_params = send_disconnect_roam_params_tlv;
Pragaspathi Thilagarajfc54cc72019-07-17 00:45:20 +05302755 ops->send_roam_preauth_status = send_roam_preauth_status_tlv;
Srinivas Dasaride39f3f2019-08-14 14:41:30 +05302756 ops->send_set_roam_trigger_cmd = send_set_roam_trigger_cmd_tlv,
Qiwei Cai770c90f2018-09-17 19:17:13 +08002757
2758 wmi_lfr_subnet_detection_attach_tlv(wmi_handle);
2759 wmi_rssi_monitor_attach_tlv(wmi_handle);
2760 wmi_ese_attach_tlv(wmi_handle);
2761 wmi_roam_offload_attach_tlv(wmi_handle);
2762 wmi_fils_sk_attach_tlv(wmi_handle);
2763}
2764