1 /* 2 * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. 3 * 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 #include <osdep.h> 20 #include "wmi.h" 21 #include "wmi_unified_priv.h" 22 23 /** 24 * send_reset_passpoint_network_list_cmd_tlv() - reset passpoint network list 25 * @wmi_handle: wmi handle 26 * @req: passpoint network request structure 27 * 28 * This function sends down WMI command with network id set to wildcard id. 29 * firmware shall clear all the config entries 30 * 31 * Return: QDF_STATUS enumeration 32 */ 33 static QDF_STATUS send_reset_passpoint_network_list_cmd_tlv 34 (wmi_unified_t wmi_handle, 35 struct wifi_passpoint_req_param *req) 36 { 37 wmi_passpoint_config_cmd_fixed_param *cmd; 38 wmi_buf_t buf; 39 uint32_t len; 40 int ret; 41 42 len = sizeof(*cmd); 43 buf = wmi_buf_alloc(wmi_handle, len); 44 if (!buf) { 45 wmi_err("Failed allocate wmi buffer"); 46 return QDF_STATUS_E_NOMEM; 47 } 48 49 cmd = (wmi_passpoint_config_cmd_fixed_param *) wmi_buf_data(buf); 50 51 WMITLV_SET_HDR(&cmd->tlv_header, 52 WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param, 53 WMITLV_GET_STRUCT_TLVLEN( 54 wmi_passpoint_config_cmd_fixed_param)); 55 cmd->id = WMI_PASSPOINT_NETWORK_ID_WILDCARD; 56 57 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 58 WMI_PASSPOINT_LIST_CONFIG_CMDID); 59 if (ret) { 60 wmi_err("Failed to send reset passpoint network list wmi cmd"); 61 wmi_buf_free(buf); 62 return QDF_STATUS_E_FAILURE; 63 } 64 65 return QDF_STATUS_SUCCESS; 66 } 67 68 /** 69 * send_set_passpoint_network_list_cmd_tlv() - set passpoint network list 70 * @wmi_handle: wmi handle 71 * @req: passpoint network request structure 72 * 73 * This function reads the incoming @req and fill in the destination 74 * WMI structure and send down the passpoint configs down to the firmware 75 * 76 * Return: QDF_STATUS enumeration 77 */ 78 static QDF_STATUS send_set_passpoint_network_list_cmd_tlv 79 (wmi_unified_t wmi_handle, 80 struct wifi_passpoint_req_param *req) 81 { 82 wmi_passpoint_config_cmd_fixed_param *cmd; 83 u_int8_t i, j, *bytes; 84 wmi_buf_t buf; 85 uint32_t len; 86 int ret; 87 88 len = sizeof(*cmd); 89 for (i = 0; i < req->num_networks; i++) { 90 buf = wmi_buf_alloc(wmi_handle, len); 91 if (!buf) { 92 wmi_err("Failed allocate wmi buffer"); 93 return QDF_STATUS_E_NOMEM; 94 } 95 96 cmd = (wmi_passpoint_config_cmd_fixed_param *) 97 wmi_buf_data(buf); 98 99 WMITLV_SET_HDR(&cmd->tlv_header, 100 WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param, 101 WMITLV_GET_STRUCT_TLVLEN( 102 wmi_passpoint_config_cmd_fixed_param)); 103 cmd->id = req->networks[i].id; 104 wmi_debug("network id: %u", cmd->id); 105 qdf_mem_copy(cmd->realm, req->networks[i].realm, 106 strlen(req->networks[i].realm) + 1); 107 wmi_debug("realm: %s", cmd->realm); 108 for (j = 0; j < PASSPOINT_ROAMING_CONSORTIUM_ID_NUM; j++) { 109 bytes = (uint8_t *) &req->networks[i].roaming_consortium_ids[j]; 110 wmi_debug("index: %d rcids: %02x %02x %02x %02x %02x %02x %02x %02x", 111 j, bytes[0], bytes[1], bytes[2], bytes[3], 112 bytes[4], bytes[5], bytes[6], bytes[7]); 113 114 qdf_mem_copy(&cmd->roaming_consortium_ids[j], 115 &req->networks[i].roaming_consortium_ids[j], 116 PASSPOINT_ROAMING_CONSORTIUM_ID_LEN); 117 } 118 qdf_mem_copy(cmd->plmn, req->networks[i].plmn, 119 PASSPOINT_PLMN_ID_LEN); 120 wmi_debug("plmn: %02x:%02x:%02x", 121 cmd->plmn[0], cmd->plmn[1], cmd->plmn[2]); 122 123 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 124 WMI_PASSPOINT_LIST_CONFIG_CMDID); 125 if (ret) { 126 wmi_err("Failed to send set passpoint network list wmi cmd"); 127 wmi_buf_free(buf); 128 return QDF_STATUS_E_FAILURE; 129 } 130 } 131 132 return QDF_STATUS_SUCCESS; 133 } 134 135 /** send_set_epno_network_list_cmd_tlv() - set epno network list 136 * @wmi_handle: wmi handle 137 * @req: epno config params request structure 138 * 139 * This function reads the incoming epno config request structure 140 * and constructs the WMI message to the firmware. 141 * 142 * Returns: 0 on success, error number otherwise 143 */ 144 static QDF_STATUS send_set_epno_network_list_cmd_tlv(wmi_unified_t wmi_handle, 145 struct wifi_enhanced_pno_params *req) 146 { 147 wmi_nlo_config_cmd_fixed_param *cmd; 148 nlo_configured_parameters *nlo_list; 149 enlo_candidate_score_params *cand_score_params; 150 u_int8_t i, *buf_ptr; 151 wmi_buf_t buf; 152 uint32_t len; 153 QDF_STATUS ret; 154 155 /* Fixed Params */ 156 len = sizeof(*cmd); 157 if (req->num_networks) { 158 /* TLV place holder for array of structures 159 * then each nlo_configured_parameters(nlo_list) TLV. 160 */ 161 len += WMI_TLV_HDR_SIZE; 162 len += (sizeof(nlo_configured_parameters) 163 * QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS)); 164 /* TLV for array of uint32 channel_list */ 165 len += WMI_TLV_HDR_SIZE; 166 /* TLV for nlo_channel_prediction_cfg */ 167 len += WMI_TLV_HDR_SIZE; 168 /* TLV for candidate score params */ 169 len += sizeof(enlo_candidate_score_params); 170 } 171 172 buf = wmi_buf_alloc(wmi_handle, len); 173 if (!buf) { 174 wmi_err("Failed allocate wmi buffer"); 175 return QDF_STATUS_E_NOMEM; 176 } 177 178 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 179 180 buf_ptr = (u_int8_t *) cmd; 181 WMITLV_SET_HDR(&cmd->tlv_header, 182 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 183 WMITLV_GET_STRUCT_TLVLEN( 184 wmi_nlo_config_cmd_fixed_param)); 185 cmd->vdev_id = req->vdev_id; 186 187 /* set flag to reset if num of networks are 0 */ 188 cmd->flags = (req->num_networks == 0 ? 189 WMI_NLO_CONFIG_ENLO_RESET : WMI_NLO_CONFIG_ENLO); 190 191 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 192 193 cmd->no_of_ssids = QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS); 194 wmi_debug("SSID count: %d flags: %d", 195 cmd->no_of_ssids, cmd->flags); 196 197 /* Fill nlo_config only when num_networks are non zero */ 198 if (cmd->no_of_ssids) { 199 /* Fill networks */ 200 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 201 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 202 buf_ptr += WMI_TLV_HDR_SIZE; 203 204 nlo_list = (nlo_configured_parameters *) buf_ptr; 205 for (i = 0; i < cmd->no_of_ssids; i++) { 206 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 207 WMITLV_TAG_ARRAY_BYTE, 208 WMITLV_GET_STRUCT_TLVLEN( 209 nlo_configured_parameters)); 210 /* Copy ssid and it's length */ 211 nlo_list[i].ssid.valid = true; 212 nlo_list[i].ssid.ssid.ssid_len = 213 req->networks[i].ssid.length; 214 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 215 req->networks[i].ssid.ssid, 216 nlo_list[i].ssid.ssid.ssid_len); 217 wmi_debug("index: %d ssid: %.*s len: %d", i, 218 nlo_list[i].ssid.ssid.ssid_len, 219 (char *) nlo_list[i].ssid.ssid.ssid, 220 nlo_list[i].ssid.ssid.ssid_len); 221 222 /* Copy pno flags */ 223 nlo_list[i].bcast_nw_type.valid = true; 224 nlo_list[i].bcast_nw_type.bcast_nw_type = 225 req->networks[i].flags; 226 wmi_debug("PNO flags: %u", 227 nlo_list[i].bcast_nw_type.bcast_nw_type); 228 229 /* Copy auth bit field */ 230 nlo_list[i].auth_type.valid = true; 231 nlo_list[i].auth_type.auth_type = 232 req->networks[i].auth_bit_field; 233 wmi_debug("Auth bit field: %u", 234 nlo_list[i].auth_type.auth_type); 235 } 236 237 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 238 /* Fill the channel list */ 239 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 240 buf_ptr += WMI_TLV_HDR_SIZE; 241 242 /* Fill prediction_param */ 243 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 244 buf_ptr += WMI_TLV_HDR_SIZE; 245 246 /* Fill epno candidate score params */ 247 cand_score_params = (enlo_candidate_score_params *) buf_ptr; 248 WMITLV_SET_HDR(buf_ptr, 249 WMITLV_TAG_STRUC_enlo_candidate_score_param, 250 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 251 cand_score_params->min5GHz_rssi = 252 req->min_5ghz_rssi; 253 cand_score_params->min24GHz_rssi = 254 req->min_24ghz_rssi; 255 cand_score_params->initial_score_max = 256 req->initial_score_max; 257 cand_score_params->current_connection_bonus = 258 req->current_connection_bonus; 259 cand_score_params->same_network_bonus = 260 req->same_network_bonus; 261 cand_score_params->secure_bonus = 262 req->secure_bonus; 263 cand_score_params->band5GHz_bonus = 264 req->band_5ghz_bonus; 265 buf_ptr += sizeof(enlo_candidate_score_params); 266 } 267 268 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 269 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 270 if (QDF_IS_STATUS_ERROR(ret)) { 271 wmi_err("Failed to send nlo wmi cmd"); 272 wmi_buf_free(buf); 273 return QDF_STATUS_E_INVAL; 274 } 275 276 wmi_debug("set ePNO list request sent successfully for vdev %d", 277 req->vdev_id); 278 279 return ret; 280 } 281 282 /** 283 * send_extscan_get_capabilities_cmd_tlv() - extscan get capabilities 284 * @wmi_handle: wmi handle 285 * @pgetcapab: get capabilities params 286 * 287 * This function send request to fw to get extscan capabilities. 288 * 289 * Return: CDF status 290 */ 291 static QDF_STATUS send_extscan_get_capabilities_cmd_tlv(wmi_unified_t wmi_handle, 292 struct extscan_capabilities_params *pgetcapab) 293 { 294 wmi_extscan_get_capabilities_cmd_fixed_param *cmd; 295 wmi_buf_t wmi_buf; 296 uint32_t len; 297 uint8_t *buf_ptr; 298 299 len = sizeof(*cmd); 300 wmi_buf = wmi_buf_alloc(wmi_handle, len); 301 if (!wmi_buf) { 302 wmi_err("wmi_buf_alloc failed"); 303 return QDF_STATUS_E_NOMEM; 304 } 305 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 306 307 cmd = (wmi_extscan_get_capabilities_cmd_fixed_param *) buf_ptr; 308 WMITLV_SET_HDR(&cmd->tlv_header, 309 WMITLV_TAG_STRUC_wmi_extscan_get_capabilities_cmd_fixed_param, 310 WMITLV_GET_STRUCT_TLVLEN 311 (wmi_extscan_get_capabilities_cmd_fixed_param)); 312 313 cmd->request_id = pgetcapab->request_id; 314 315 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 316 WMI_EXTSCAN_GET_CAPABILITIES_CMDID)) { 317 wmi_err("Failed to send extscan get capabilities cmd"); 318 wmi_buf_free(wmi_buf); 319 return QDF_STATUS_E_FAILURE; 320 } 321 return QDF_STATUS_SUCCESS; 322 } 323 324 /** 325 * send_extscan_get_cached_results_cmd_tlv() - extscan get cached results 326 * @wmi_handle: wmi handle 327 * @pcached_results: cached results parameters 328 * 329 * This function send request to fw to get cached results. 330 * 331 * Return: CDF status 332 */ 333 static QDF_STATUS send_extscan_get_cached_results_cmd_tlv(wmi_unified_t wmi_handle, 334 struct extscan_cached_result_params *pcached_results) 335 { 336 wmi_extscan_get_cached_results_cmd_fixed_param *cmd; 337 wmi_buf_t wmi_buf; 338 uint32_t len; 339 uint8_t *buf_ptr; 340 341 len = sizeof(*cmd); 342 wmi_buf = wmi_buf_alloc(wmi_handle, len); 343 if (!wmi_buf) { 344 wmi_err("wmi_buf_alloc failed"); 345 return QDF_STATUS_E_NOMEM; 346 } 347 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 348 349 cmd = (wmi_extscan_get_cached_results_cmd_fixed_param *) buf_ptr; 350 WMITLV_SET_HDR(&cmd->tlv_header, 351 WMITLV_TAG_STRUC_wmi_extscan_get_cached_results_cmd_fixed_param, 352 WMITLV_GET_STRUCT_TLVLEN 353 (wmi_extscan_get_cached_results_cmd_fixed_param)); 354 355 cmd->request_id = pcached_results->request_id; 356 cmd->vdev_id = pcached_results->vdev_id; 357 cmd->control_flags = pcached_results->flush; 358 359 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 360 WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID)) { 361 wmi_err("failed to command", __func__); 362 wmi_buf_free(wmi_buf); 363 return QDF_STATUS_E_FAILURE; 364 } 365 return QDF_STATUS_SUCCESS; 366 } 367 368 /** 369 * send_extscan_stop_change_monitor_cmd_tlv() - send stop change monitor cmd 370 * @wmi_handle: wmi handle 371 * @reset_req: Reset change request params 372 * 373 * This function sends stop change monitor request to fw. 374 * 375 * Return: CDF status 376 */ 377 static QDF_STATUS send_extscan_stop_change_monitor_cmd_tlv 378 (wmi_unified_t wmi_handle, 379 struct extscan_capabilities_reset_params *reset_req) 380 { 381 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd; 382 wmi_buf_t wmi_buf; 383 uint32_t len; 384 uint8_t *buf_ptr; 385 int change_list = 0; 386 387 len = sizeof(*cmd); 388 389 /* reset significant change tlv is set to 0 */ 390 len += WMI_TLV_HDR_SIZE; 391 len += change_list * sizeof(wmi_extscan_wlan_change_bssid_param); 392 wmi_buf = wmi_buf_alloc(wmi_handle, len); 393 if (!wmi_buf) { 394 wmi_err("wmi_buf_alloc failed"); 395 return QDF_STATUS_E_NOMEM; 396 } 397 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 398 399 cmd = (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *) 400 buf_ptr; 401 WMITLV_SET_HDR(&cmd->tlv_header, 402 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, 403 WMITLV_GET_STRUCT_TLVLEN 404 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param)); 405 406 cmd->request_id = reset_req->request_id; 407 cmd->vdev_id = reset_req->vdev_id; 408 cmd->mode = 0; 409 410 buf_ptr += sizeof(*cmd); 411 WMITLV_SET_HDR(buf_ptr, 412 WMITLV_TAG_ARRAY_STRUC, 413 change_list * 414 sizeof(wmi_extscan_wlan_change_bssid_param)); 415 buf_ptr += WMI_TLV_HDR_SIZE + (change_list * 416 sizeof 417 (wmi_extscan_wlan_change_bssid_param)); 418 419 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 420 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) { 421 wmi_err("Failed to send extscan change monitor cmd"); 422 wmi_buf_free(wmi_buf); 423 return QDF_STATUS_E_FAILURE; 424 } 425 return QDF_STATUS_SUCCESS; 426 } 427 428 /** 429 * wmi_get_buf_extscan_change_monitor_cmd() - fill change monitor request 430 * @wmi_handle: wmi handle 431 * @psigchange: change monitor request params 432 * @buf: wmi buffer 433 * @buf_len: buffer length 434 * 435 * This function fills elements of change monitor request buffer. 436 * 437 * Return: QDF status 438 */ 439 static QDF_STATUS wmi_get_buf_extscan_change_monitor_cmd 440 (wmi_unified_t wmi_handle, 441 struct extscan_set_sig_changereq_params 442 *psigchange, wmi_buf_t *buf, int *buf_len) 443 { 444 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd; 445 wmi_extscan_wlan_change_bssid_param *dest_chglist; 446 uint8_t *buf_ptr; 447 int j; 448 int len = sizeof(*cmd); 449 uint32_t numap = psigchange->num_ap; 450 struct ap_threshold_params *src_ap = psigchange->ap; 451 452 if (!numap || (numap > WMI_WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS)) { 453 wmi_err("Invalid number of bssid's"); 454 return QDF_STATUS_E_INVAL; 455 } 456 len += WMI_TLV_HDR_SIZE; 457 len += numap * sizeof(wmi_extscan_wlan_change_bssid_param); 458 459 *buf = wmi_buf_alloc(wmi_handle, len); 460 if (!*buf) { 461 wmi_err("Failed to allocate memory for change monitor cmd"); 462 return QDF_STATUS_E_FAILURE; 463 } 464 buf_ptr = (uint8_t *) wmi_buf_data(*buf); 465 cmd = 466 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *) 467 buf_ptr; 468 WMITLV_SET_HDR(&cmd->tlv_header, 469 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, 470 WMITLV_GET_STRUCT_TLVLEN 471 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param)); 472 473 cmd->request_id = psigchange->request_id; 474 cmd->vdev_id = psigchange->vdev_id; 475 cmd->total_entries = numap; 476 cmd->mode = 1; 477 cmd->num_entries_in_page = numap; 478 cmd->lost_ap_scan_count = psigchange->lostap_sample_size; 479 cmd->max_rssi_samples = psigchange->rssi_sample_size; 480 cmd->rssi_averaging_samples = psigchange->rssi_sample_size; 481 cmd->max_out_of_range_count = psigchange->min_breaching; 482 483 buf_ptr += sizeof(*cmd); 484 WMITLV_SET_HDR(buf_ptr, 485 WMITLV_TAG_ARRAY_STRUC, 486 numap * sizeof(wmi_extscan_wlan_change_bssid_param)); 487 dest_chglist = (wmi_extscan_wlan_change_bssid_param *) 488 (buf_ptr + WMI_TLV_HDR_SIZE); 489 490 for (j = 0; j < numap; j++) { 491 WMITLV_SET_HDR(dest_chglist, 492 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 493 WMITLV_GET_STRUCT_TLVLEN 494 (wmi_extscan_wlan_change_bssid_param)); 495 496 dest_chglist->lower_rssi_limit = src_ap->low; 497 dest_chglist->upper_rssi_limit = src_ap->high; 498 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes, 499 &dest_chglist->bssid); 500 501 wmi_debug("min_rssi: %d", dest_chglist->lower_rssi_limit); 502 dest_chglist++; 503 src_ap++; 504 } 505 buf_ptr += WMI_TLV_HDR_SIZE + 506 (numap * sizeof(wmi_extscan_wlan_change_bssid_param)); 507 *buf_len = len; 508 return QDF_STATUS_SUCCESS; 509 } 510 511 /** 512 * send_extscan_start_change_monitor_cmd_tlv() - send start change monitor cmd 513 * @wmi_handle: wmi handle 514 * @psigchange: change monitor request params 515 * 516 * This function sends start change monitor request to fw. 517 * 518 * Return: CDF status 519 */ 520 static QDF_STATUS send_extscan_start_change_monitor_cmd_tlv 521 (wmi_unified_t wmi_handle, 522 struct extscan_set_sig_changereq_params * 523 psigchange) 524 { 525 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 526 wmi_buf_t buf; 527 int len; 528 529 530 qdf_status = wmi_get_buf_extscan_change_monitor_cmd(wmi_handle, 531 psigchange, &buf, 532 &len); 533 if (qdf_status != QDF_STATUS_SUCCESS) { 534 wmi_err("Failed to get buffer for change monitor cmd"); 535 return QDF_STATUS_E_FAILURE; 536 } 537 if (!buf) { 538 wmi_err("Failed to get buffer"); 539 return QDF_STATUS_E_FAILURE; 540 } 541 if (wmi_unified_cmd_send(wmi_handle, buf, len, 542 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) { 543 wmi_err("Failed to send command"); 544 wmi_buf_free(buf); 545 return QDF_STATUS_E_FAILURE; 546 } 547 return QDF_STATUS_SUCCESS; 548 } 549 550 /** 551 * send_extscan_stop_hotlist_monitor_cmd_tlv() - stop hotlist monitor 552 * @wmi_handle: wmi handle 553 * @photlist_reset: hotlist reset params 554 * 555 * This function configures hotlist monitor to stop in fw. 556 * 557 * Return: CDF status 558 */ 559 static QDF_STATUS send_extscan_stop_hotlist_monitor_cmd_tlv 560 (wmi_unified_t wmi_handle, 561 struct extscan_bssid_hotlist_reset_params *photlist_reset) 562 { 563 wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd; 564 wmi_buf_t wmi_buf; 565 uint32_t len; 566 uint8_t *buf_ptr; 567 int hotlist_entries = 0; 568 569 len = sizeof(*cmd); 570 571 /* reset bssid hotlist with tlv set to 0 */ 572 len += WMI_TLV_HDR_SIZE; 573 len += hotlist_entries * sizeof(wmi_extscan_hotlist_entry); 574 575 wmi_buf = wmi_buf_alloc(wmi_handle, len); 576 if (!wmi_buf) { 577 wmi_err("wmi_buf_alloc failed"); 578 return QDF_STATUS_E_NOMEM; 579 } 580 581 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 582 cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *) 583 buf_ptr; 584 WMITLV_SET_HDR(&cmd->tlv_header, 585 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, 586 WMITLV_GET_STRUCT_TLVLEN 587 (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param)); 588 589 cmd->request_id = photlist_reset->request_id; 590 cmd->vdev_id = photlist_reset->vdev_id; 591 cmd->mode = 0; 592 593 buf_ptr += sizeof(*cmd); 594 WMITLV_SET_HDR(buf_ptr, 595 WMITLV_TAG_ARRAY_STRUC, 596 hotlist_entries * sizeof(wmi_extscan_hotlist_entry)); 597 buf_ptr += WMI_TLV_HDR_SIZE + 598 (hotlist_entries * sizeof(wmi_extscan_hotlist_entry)); 599 600 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 601 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) { 602 wmi_err("Failed to send extscan cfg hotlist cmd"); 603 wmi_buf_free(wmi_buf); 604 return QDF_STATUS_E_FAILURE; 605 } 606 return QDF_STATUS_SUCCESS; 607 } 608 609 /** 610 * send_stop_extscan_cmd_tlv() - stop extscan command to fw. 611 * @wmi_handle: wmi handle 612 * @pstopcmd: stop scan command request params 613 * 614 * This function sends stop extscan request to fw. 615 * 616 * Return: CDF Status. 617 */ 618 static QDF_STATUS send_stop_extscan_cmd_tlv(wmi_unified_t wmi_handle, 619 struct extscan_stop_req_params *pstopcmd) 620 { 621 wmi_extscan_stop_cmd_fixed_param *cmd; 622 wmi_buf_t wmi_buf; 623 uint32_t len; 624 uint8_t *buf_ptr; 625 626 len = sizeof(*cmd); 627 wmi_buf = wmi_buf_alloc(wmi_handle, len); 628 if (!wmi_buf) { 629 wmi_err("wmi_buf_alloc failed"); 630 return QDF_STATUS_E_NOMEM; 631 } 632 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 633 cmd = (wmi_extscan_stop_cmd_fixed_param *) buf_ptr; 634 WMITLV_SET_HDR(&cmd->tlv_header, 635 WMITLV_TAG_STRUC_wmi_extscan_stop_cmd_fixed_param, 636 WMITLV_GET_STRUCT_TLVLEN 637 (wmi_extscan_stop_cmd_fixed_param)); 638 639 cmd->request_id = pstopcmd->request_id; 640 cmd->vdev_id = pstopcmd->vdev_id; 641 642 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 643 WMI_EXTSCAN_STOP_CMDID)) { 644 wmi_err("Failed to send extscan stop cmd"); 645 wmi_buf_free(wmi_buf); 646 return QDF_STATUS_E_FAILURE; 647 } 648 649 return QDF_STATUS_SUCCESS; 650 } 651 652 /** 653 * wmi_get_buf_extscan_start_cmd() - Fill extscan start request 654 * @wmi_handle: wmi handle 655 * @pstart: scan command request params 656 * @buf: event buffer 657 * @buf_len: length of buffer 658 * 659 * This function fills individual elements of extscan request and 660 * TLV for buckets, channel list. 661 * 662 * Return: CDF Status. 663 */ 664 static 665 QDF_STATUS wmi_get_buf_extscan_start_cmd(wmi_unified_t wmi_handle, 666 struct wifi_scan_cmd_req_params *pstart, 667 wmi_buf_t *buf, int *buf_len) 668 { 669 wmi_extscan_start_cmd_fixed_param *cmd; 670 wmi_extscan_bucket *dest_blist; 671 wmi_extscan_bucket_channel *dest_clist; 672 struct wifi_scan_bucket_params *src_bucket = pstart->buckets; 673 struct wifi_scan_channelspec_params *src_channel = src_bucket->channels; 674 struct wifi_scan_channelspec_params save_channel[WMI_WLAN_EXTSCAN_MAX_CHANNELS]; 675 676 uint8_t *buf_ptr; 677 int i, k, count = 0; 678 int len = sizeof(*cmd); 679 int nbuckets = pstart->num_buckets; 680 int nchannels = 0; 681 682 /* These TLV's are are NULL by default */ 683 uint32_t ie_len_with_pad = 0; 684 int num_ssid = 0; 685 int num_bssid = 0; 686 int ie_len = 0; 687 688 uint32_t base_period = pstart->base_period; 689 690 /* TLV placeholder for ssid_list (NULL) */ 691 len += WMI_TLV_HDR_SIZE; 692 len += num_ssid * sizeof(wmi_ssid); 693 694 /* TLV placeholder for bssid_list (NULL) */ 695 len += WMI_TLV_HDR_SIZE; 696 len += num_bssid * sizeof(wmi_mac_addr); 697 698 /* TLV placeholder for ie_data (NULL) */ 699 len += WMI_TLV_HDR_SIZE; 700 len += ie_len * sizeof(uint32_t); 701 702 /* TLV placeholder for bucket */ 703 len += WMI_TLV_HDR_SIZE; 704 len += nbuckets * sizeof(wmi_extscan_bucket); 705 706 /* TLV channel placeholder */ 707 len += WMI_TLV_HDR_SIZE; 708 for (i = 0; i < nbuckets; i++) { 709 nchannels += src_bucket->num_channels; 710 src_bucket++; 711 } 712 713 wmi_debug("Total buckets: %d total #of channels is %d", 714 nbuckets, nchannels); 715 len += nchannels * sizeof(wmi_extscan_bucket_channel); 716 /* Allocate the memory */ 717 *buf = wmi_buf_alloc(wmi_handle, len); 718 if (!*buf) { 719 wmi_err("Failed to allocate memory for start extscan cmd"); 720 return QDF_STATUS_E_NOMEM; 721 } 722 buf_ptr = (uint8_t *) wmi_buf_data(*buf); 723 cmd = (wmi_extscan_start_cmd_fixed_param *) buf_ptr; 724 WMITLV_SET_HDR(&cmd->tlv_header, 725 WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param, 726 WMITLV_GET_STRUCT_TLVLEN 727 (wmi_extscan_start_cmd_fixed_param)); 728 729 cmd->request_id = pstart->request_id; 730 cmd->vdev_id = pstart->vdev_id; 731 cmd->base_period = pstart->base_period; 732 cmd->num_buckets = nbuckets; 733 cmd->configuration_flags = 0; 734 if (pstart->configuration_flags & WMI_EXTSCAN_LP_EXTENDED_BATCHING) 735 cmd->configuration_flags |= WMI_EXTSCAN_EXTENDED_BATCHING_EN; 736 wmi_debug("configuration_flags: 0x%x", cmd->configuration_flags); 737 #ifdef FEATURE_WLAN_EXTSCAN 738 cmd->min_rest_time = WMI_EXTSCAN_REST_TIME; 739 cmd->max_rest_time = WMI_EXTSCAN_REST_TIME; 740 cmd->max_scan_time = WMI_EXTSCAN_MAX_SCAN_TIME; 741 cmd->burst_duration = WMI_EXTSCAN_BURST_DURATION; 742 #endif 743 744 /* The max dwell time is retrieved from the first channel 745 * of the first bucket and kept common for all channels. 746 */ 747 cmd->min_dwell_time_active = pstart->min_dwell_time_active; 748 cmd->max_dwell_time_active = pstart->max_dwell_time_active; 749 cmd->min_dwell_time_passive = pstart->min_dwell_time_passive; 750 cmd->max_dwell_time_passive = pstart->max_dwell_time_passive; 751 cmd->max_bssids_per_scan_cycle = pstart->max_ap_per_scan; 752 cmd->max_table_usage = pstart->report_threshold_percent; 753 cmd->report_threshold_num_scans = pstart->report_threshold_num_scans; 754 755 cmd->repeat_probe_time = cmd->max_dwell_time_active / 756 WMI_SCAN_NPROBES_DEFAULT; 757 cmd->probe_delay = 0; 758 cmd->probe_spacing_time = 0; 759 cmd->idle_time = 0; 760 cmd->scan_ctrl_flags = WMI_SCAN_ADD_BCAST_PROBE_REQ | 761 WMI_SCAN_ADD_CCK_RATES | 762 WMI_SCAN_ADD_OFDM_RATES | 763 WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ | 764 WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 765 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 766 pstart->extscan_adaptive_dwell_mode); 767 cmd->scan_priority = WMI_SCAN_PRIORITY_VERY_LOW; 768 cmd->num_ssids = 0; 769 cmd->num_bssid = 0; 770 cmd->ie_len = 0; 771 cmd->n_probes = (cmd->repeat_probe_time > 0) ? 772 cmd->max_dwell_time_active / cmd->repeat_probe_time : 0; 773 774 buf_ptr += sizeof(*cmd); 775 WMITLV_SET_HDR(buf_ptr, 776 WMITLV_TAG_ARRAY_FIXED_STRUC, 777 num_ssid * sizeof(wmi_ssid)); 778 buf_ptr += WMI_TLV_HDR_SIZE + (num_ssid * sizeof(wmi_ssid)); 779 780 WMITLV_SET_HDR(buf_ptr, 781 WMITLV_TAG_ARRAY_FIXED_STRUC, 782 num_bssid * sizeof(wmi_mac_addr)); 783 buf_ptr += WMI_TLV_HDR_SIZE + (num_bssid * sizeof(wmi_mac_addr)); 784 785 ie_len_with_pad = 0; 786 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 787 ie_len_with_pad); 788 buf_ptr += WMI_TLV_HDR_SIZE + ie_len_with_pad; 789 790 WMITLV_SET_HDR(buf_ptr, 791 WMITLV_TAG_ARRAY_STRUC, 792 nbuckets * sizeof(wmi_extscan_bucket)); 793 dest_blist = (wmi_extscan_bucket *) 794 (buf_ptr + WMI_TLV_HDR_SIZE); 795 src_bucket = pstart->buckets; 796 797 /* Retrieve scanning information from each bucket and 798 * channels and send it to the target 799 */ 800 for (i = 0; i < nbuckets; i++) { 801 WMITLV_SET_HDR(dest_blist, 802 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 803 WMITLV_GET_STRUCT_TLVLEN(wmi_extscan_bucket)); 804 805 dest_blist->bucket_id = src_bucket->bucket; 806 dest_blist->base_period_multiplier = 807 src_bucket->period / base_period; 808 dest_blist->min_period = src_bucket->period; 809 dest_blist->max_period = src_bucket->max_period; 810 dest_blist->exp_backoff = src_bucket->exponent; 811 dest_blist->exp_max_step_count = src_bucket->step_count; 812 dest_blist->channel_band = src_bucket->band; 813 dest_blist->num_channels = src_bucket->num_channels; 814 dest_blist->notify_extscan_events = 0; 815 816 if (src_bucket->report_events & 817 WMI_EXTSCAN_REPORT_EVENTS_EACH_SCAN) 818 dest_blist->notify_extscan_events = 819 WMI_EXTSCAN_CYCLE_COMPLETED_EVENT | 820 WMI_EXTSCAN_CYCLE_STARTED_EVENT; 821 822 if (src_bucket->report_events & 823 WMI_EXTSCAN_REPORT_EVENTS_FULL_RESULTS) { 824 dest_blist->forwarding_flags = 825 WMI_EXTSCAN_FORWARD_FRAME_TO_HOST; 826 dest_blist->notify_extscan_events |= 827 WMI_EXTSCAN_BUCKET_COMPLETED_EVENT | 828 WMI_EXTSCAN_CYCLE_STARTED_EVENT | 829 WMI_EXTSCAN_CYCLE_COMPLETED_EVENT; 830 } else { 831 dest_blist->forwarding_flags = 832 WMI_EXTSCAN_NO_FORWARDING; 833 } 834 835 if (src_bucket->report_events & 836 WMI_EXTSCAN_REPORT_EVENTS_NO_BATCH) 837 dest_blist->configuration_flags = 0; 838 else 839 dest_blist->configuration_flags = 840 WMI_EXTSCAN_BUCKET_CACHE_RESULTS; 841 842 wmi_debug("ntfy_extscan_events:%u cfg_flags:%u fwd_flags:%u", 843 dest_blist->notify_extscan_events, 844 dest_blist->configuration_flags, 845 dest_blist->forwarding_flags); 846 847 dest_blist->min_dwell_time_active = 848 src_bucket->min_dwell_time_active; 849 dest_blist->max_dwell_time_active = 850 src_bucket->max_dwell_time_active; 851 dest_blist->min_dwell_time_passive = 852 src_bucket->min_dwell_time_passive; 853 dest_blist->max_dwell_time_passive = 854 src_bucket->max_dwell_time_passive; 855 src_channel = src_bucket->channels; 856 857 /* save the channel info to later populate 858 * the channel TLV 859 */ 860 for (k = 0; k < src_bucket->num_channels; k++) { 861 save_channel[count++].channel = src_channel->channel; 862 src_channel++; 863 } 864 dest_blist++; 865 src_bucket++; 866 } 867 buf_ptr += WMI_TLV_HDR_SIZE + (nbuckets * sizeof(wmi_extscan_bucket)); 868 WMITLV_SET_HDR(buf_ptr, 869 WMITLV_TAG_ARRAY_STRUC, 870 nchannels * sizeof(wmi_extscan_bucket_channel)); 871 dest_clist = (wmi_extscan_bucket_channel *) 872 (buf_ptr + WMI_TLV_HDR_SIZE); 873 874 /* Active or passive scan is based on the bucket dwell time 875 * and channel specific active,passive scans are not 876 * supported yet 877 */ 878 for (i = 0; i < nchannels; i++) { 879 WMITLV_SET_HDR(dest_clist, 880 WMITLV_TAG_STRUC_wmi_extscan_bucket_channel_event_fixed_param, 881 WMITLV_GET_STRUCT_TLVLEN 882 (wmi_extscan_bucket_channel)); 883 dest_clist->channel = save_channel[i].channel; 884 dest_clist++; 885 } 886 buf_ptr += WMI_TLV_HDR_SIZE + 887 (nchannels * sizeof(wmi_extscan_bucket_channel)); 888 *buf_len = len; 889 return QDF_STATUS_SUCCESS; 890 } 891 892 /** 893 * send_start_extscan_cmd_tlv() - start extscan command to fw. 894 * @wmi_handle: wmi handle 895 * @pstart: scan command request params 896 * 897 * This function sends start extscan request to fw. 898 * 899 * Return: CDF Status. 900 */ 901 static QDF_STATUS send_start_extscan_cmd_tlv(wmi_unified_t wmi_handle, 902 struct wifi_scan_cmd_req_params *pstart) 903 { 904 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 905 wmi_buf_t buf; 906 int len; 907 908 /* Fill individual elements of extscan request and 909 * TLV for buckets, channel list. 910 */ 911 qdf_status = wmi_get_buf_extscan_start_cmd(wmi_handle, 912 pstart, &buf, &len); 913 if (qdf_status != QDF_STATUS_SUCCESS) { 914 wmi_err("Failed to get buffer for ext scan cmd"); 915 return QDF_STATUS_E_FAILURE; 916 } 917 if (!buf) { 918 wmi_err("Failed to get buffer for current extscan info"); 919 return QDF_STATUS_E_FAILURE; 920 } 921 if (wmi_unified_cmd_send(wmi_handle, buf, 922 len, WMI_EXTSCAN_START_CMDID)) { 923 wmi_err("Failed to send extscan start cmd"); 924 wmi_buf_free(buf); 925 return QDF_STATUS_E_FAILURE; 926 } 927 928 return QDF_STATUS_SUCCESS; 929 } 930 931 /** wmi_get_hotlist_entries_per_page() - hotlist entries per page 932 * @wmi_handle: wmi handle. 933 * @cmd: size of command structure. 934 * @per_entry_size: per entry size. 935 * 936 * This utility function calculates how many hotlist entries can 937 * fit in one page. 938 * 939 * Return: number of entries 940 */ 941 static inline int wmi_get_hotlist_entries_per_page 942 (wmi_unified_t wmi_handle, 943 size_t cmd_size, 944 size_t per_entry_size) 945 { 946 uint32_t avail_space = 0; 947 int num_entries = 0; 948 uint16_t max_msg_len = wmi_get_max_msg_len(wmi_handle); 949 950 /* Calculate number of hotlist entries that can 951 * be passed in wma message request. 952 */ 953 avail_space = max_msg_len - cmd_size; 954 num_entries = avail_space / per_entry_size; 955 return num_entries; 956 } 957 958 /** 959 * send_extscan_start_hotlist_monitor_cmd_tlv() - start hotlist monitor 960 * @wmi_handle: wmi handle 961 * @params: hotlist params 962 * 963 * This function configures hotlist monitor to start in fw. 964 * 965 * Return: QDF status 966 */ 967 static QDF_STATUS send_extscan_start_hotlist_monitor_cmd_tlv 968 (wmi_unified_t wmi_handle, 969 struct extscan_bssid_hotlist_set_params *params) 970 { 971 wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd = NULL; 972 wmi_extscan_hotlist_entry *dest_hotlist; 973 struct ap_threshold_params *src_ap = params->ap; 974 wmi_buf_t buf; 975 uint8_t *buf_ptr; 976 977 int j, index = 0; 978 int cmd_len = 0; 979 int num_entries; 980 int min_entries = 0; 981 uint32_t numap = params->num_ap; 982 int len = sizeof(*cmd); 983 984 len += WMI_TLV_HDR_SIZE; 985 cmd_len = len; 986 987 num_entries = wmi_get_hotlist_entries_per_page(wmi_handle, 988 cmd_len, 989 sizeof(*dest_hotlist)); 990 /* setbssid hotlist expects the bssid list 991 * to be non zero value 992 */ 993 if (!numap || (numap > WMI_WLAN_EXTSCAN_MAX_HOTLIST_APS)) { 994 wmi_err("Invalid number of APs: %d", numap); 995 return QDF_STATUS_E_INVAL; 996 } 997 998 /* Split the hot list entry pages and send multiple command 999 * requests if the buffer reaches the maximum request size 1000 */ 1001 while (index < numap) { 1002 min_entries = QDF_MIN(num_entries, numap); 1003 len += min_entries * sizeof(wmi_extscan_hotlist_entry); 1004 buf = wmi_buf_alloc(wmi_handle, len); 1005 if (!buf) { 1006 wmi_err("wmi_buf_alloc failed"); 1007 return QDF_STATUS_E_FAILURE; 1008 } 1009 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1010 cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *) 1011 buf_ptr; 1012 WMITLV_SET_HDR(&cmd->tlv_header, 1013 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, 1014 WMITLV_GET_STRUCT_TLVLEN 1015 (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param)); 1016 1017 /* Multiple requests are sent until the num_entries_in_page 1018 * matches the total_entries 1019 */ 1020 cmd->request_id = params->request_id; 1021 cmd->vdev_id = params->vdev_id; 1022 cmd->total_entries = numap; 1023 cmd->mode = 1; 1024 cmd->num_entries_in_page = min_entries; 1025 cmd->lost_ap_scan_count = params->lost_ap_sample_size; 1026 cmd->first_entry_index = index; 1027 1028 wmi_debug("vdev id:%d total_entries: %d num_entries: %d lost_ap_sample_size: %d", 1029 cmd->vdev_id, cmd->total_entries, 1030 cmd->num_entries_in_page, 1031 cmd->lost_ap_scan_count); 1032 1033 buf_ptr += sizeof(*cmd); 1034 WMITLV_SET_HDR(buf_ptr, 1035 WMITLV_TAG_ARRAY_STRUC, 1036 min_entries * sizeof(wmi_extscan_hotlist_entry)); 1037 dest_hotlist = (wmi_extscan_hotlist_entry *) 1038 (buf_ptr + WMI_TLV_HDR_SIZE); 1039 1040 /* Populate bssid, channel info and rssi 1041 * for the bssid's that are sent as hotlists. 1042 */ 1043 for (j = 0; j < min_entries; j++) { 1044 WMITLV_SET_HDR(dest_hotlist, 1045 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 1046 WMITLV_GET_STRUCT_TLVLEN 1047 (wmi_extscan_hotlist_entry)); 1048 1049 dest_hotlist->min_rssi = src_ap->low; 1050 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes, 1051 &dest_hotlist->bssid); 1052 1053 wmi_debug("channel:%d min_rssi %d", 1054 dest_hotlist->channel, 1055 dest_hotlist->min_rssi); 1056 wmi_debug("bssid mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 1057 dest_hotlist->bssid.mac_addr31to0, 1058 dest_hotlist->bssid.mac_addr47to32); 1059 dest_hotlist++; 1060 src_ap++; 1061 } 1062 buf_ptr += WMI_TLV_HDR_SIZE + 1063 (min_entries * sizeof(wmi_extscan_hotlist_entry)); 1064 1065 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1066 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) { 1067 wmi_err("Failed to send extscan cfg hotlist monitor cmd"); 1068 wmi_buf_free(buf); 1069 return QDF_STATUS_E_FAILURE; 1070 } 1071 index = index + min_entries; 1072 num_entries = numap - min_entries; 1073 len = cmd_len; 1074 } 1075 return QDF_STATUS_SUCCESS; 1076 } 1077 1078 void wmi_extscan_attach_tlv(wmi_unified_t wmi_handle) 1079 { 1080 struct wmi_ops *ops = wmi_handle->ops; 1081 ops->send_reset_passpoint_network_list_cmd = 1082 send_reset_passpoint_network_list_cmd_tlv; 1083 ops->send_set_passpoint_network_list_cmd = 1084 send_set_passpoint_network_list_cmd_tlv; 1085 ops->send_set_epno_network_list_cmd = 1086 send_set_epno_network_list_cmd_tlv; 1087 ops->send_extscan_get_capabilities_cmd = 1088 send_extscan_get_capabilities_cmd_tlv; 1089 ops->send_extscan_get_cached_results_cmd = 1090 send_extscan_get_cached_results_cmd_tlv; 1091 ops->send_extscan_stop_change_monitor_cmd = 1092 send_extscan_stop_change_monitor_cmd_tlv; 1093 ops->send_extscan_start_change_monitor_cmd = 1094 send_extscan_start_change_monitor_cmd_tlv; 1095 ops->send_extscan_stop_hotlist_monitor_cmd = 1096 send_extscan_stop_hotlist_monitor_cmd_tlv; 1097 ops->send_extscan_start_hotlist_monitor_cmd = 1098 send_extscan_start_hotlist_monitor_cmd_tlv; 1099 ops->send_stop_extscan_cmd = send_stop_extscan_cmd_tlv; 1100 ops->send_start_extscan_cmd = send_start_extscan_cmd_tlv; 1101 } 1102