1 /* 2 * Copyright (c) 2013-2019 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_version.h" 22 #include "wmi_unified_priv.h" 23 #include "wmi_unified_sta_param.h" 24 #include "wmi_unified_sta_api.h" 25 #ifdef FEATURE_WLAN_TDLS 26 #include <wlan_tdls_public_structs.h> 27 #endif 28 29 /** 30 * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters 31 * @wmi_handle: wmi handle 32 * @vdev_id: vdev id 33 * @max_retries: max retries 34 * @retry_interval: retry interval 35 * This function sets sta query related parameters in fw. 36 * 37 * Return: QDF_STATUS_SUCCESS for success otherwise failure 38 */ 39 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle, 40 uint8_t vdev_id, 41 uint32_t max_retries, 42 uint32_t retry_interval) 43 { 44 wmi_buf_t buf; 45 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd; 46 int len; 47 48 len = sizeof(*cmd); 49 buf = wmi_buf_alloc(wmi_handle, len); 50 if (!buf) { 51 return QDF_STATUS_E_FAILURE; 52 } 53 54 cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf); 55 WMITLV_SET_HDR(&cmd->tlv_header, 56 WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param, 57 WMITLV_GET_STRUCT_TLVLEN 58 (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param)); 59 60 cmd->vdev_id = vdev_id; 61 cmd->sa_query_max_retry_count = max_retries; 62 cmd->sa_query_retry_interval = retry_interval; 63 64 WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"), 65 vdev_id, retry_interval, max_retries); 66 67 wmi_mtrace(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID, cmd->vdev_id, 0); 68 if (wmi_unified_cmd_send(wmi_handle, buf, len, 69 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) { 70 WMI_LOGE(FL("Failed to offload STA SA Query")); 71 wmi_buf_free(buf); 72 return QDF_STATUS_E_FAILURE; 73 } 74 75 WMI_LOGD(FL("Exit :")); 76 return 0; 77 } 78 79 /** 80 * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters 81 * @wmi_handle: wmi handle 82 * @params: sta keep alive parameter 83 * 84 * This function sets keep alive related parameters in fw. 85 * 86 * Return: CDF status 87 */ 88 static QDF_STATUS 89 send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle, 90 struct sta_keep_alive_params *params) 91 { 92 wmi_buf_t buf; 93 WMI_STA_KEEPALIVE_CMD_fixed_param *cmd; 94 WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp; 95 uint8_t *buf_ptr; 96 int len; 97 QDF_STATUS ret; 98 99 WMI_LOGD("%s: Enter", __func__); 100 101 len = sizeof(*cmd) + sizeof(*arp_rsp); 102 buf = wmi_buf_alloc(wmi_handle, len); 103 if (!buf) { 104 return QDF_STATUS_E_FAILURE; 105 } 106 107 cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf); 108 buf_ptr = (uint8_t *) cmd; 109 WMITLV_SET_HDR(&cmd->tlv_header, 110 WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param, 111 WMITLV_GET_STRUCT_TLVLEN 112 (WMI_STA_KEEPALIVE_CMD_fixed_param)); 113 cmd->interval = params->timeperiod; 114 cmd->enable = (params->timeperiod) ? 1 : 0; 115 cmd->vdev_id = params->vdev_id; 116 WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", 117 params->vdev_id, params->timeperiod, params->method); 118 arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd)); 119 WMITLV_SET_HDR(&arp_rsp->tlv_header, 120 WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE, 121 WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE)); 122 123 if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) || 124 (params->method == 125 WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) { 126 cmd->method = params->method; 127 qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr, 128 QDF_IPV4_ADDR_SIZE); 129 qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr, 130 QDF_IPV4_ADDR_SIZE); 131 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, 132 &arp_rsp->dest_mac_addr); 133 } else { 134 cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME; 135 } 136 137 wmi_mtrace(WMI_STA_KEEPALIVE_CMDID, cmd->vdev_id, 0); 138 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 139 WMI_STA_KEEPALIVE_CMDID); 140 if (QDF_IS_STATUS_ERROR(ret)) { 141 WMI_LOGE("Failed to set KeepAlive"); 142 wmi_buf_free(buf); 143 } 144 145 WMI_LOGD("%s: Exit", __func__); 146 return ret; 147 } 148 149 /** 150 * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params 151 * @wmi_handle: wmi handle 152 * @if_id: vdev id 153 * @gtx_info: GTX config params 154 * 155 * This function set GTX related params in firmware. 156 * 157 * Return: QDF_STATUS_SUCCESS for success or error code 158 */ 159 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id, 160 struct wmi_gtx_config *gtx_info) 161 { 162 wmi_vdev_set_gtx_params_cmd_fixed_param *cmd; 163 wmi_buf_t buf; 164 QDF_STATUS ret; 165 int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param); 166 167 buf = wmi_buf_alloc(wmi_handle, len); 168 if (!buf) { 169 return QDF_STATUS_E_NOMEM; 170 } 171 cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf); 172 WMITLV_SET_HDR(&cmd->tlv_header, 173 WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param, 174 WMITLV_GET_STRUCT_TLVLEN 175 (wmi_vdev_set_gtx_params_cmd_fixed_param)); 176 cmd->vdev_id = if_id; 177 178 cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0]; 179 cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1]; 180 cmd->userGtxMask = gtx_info->gtx_usrcfg; 181 cmd->gtxPERThreshold = gtx_info->gtx_threshold; 182 cmd->gtxPERMargin = gtx_info->gtx_margin; 183 cmd->gtxTPCstep = gtx_info->gtx_tpcstep; 184 cmd->gtxTPCMin = gtx_info->gtx_tpcmin; 185 cmd->gtxBWMask = gtx_info->gtx_bwmask; 186 187 WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \ 188 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \ 189 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1], 190 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin, 191 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask); 192 193 wmi_mtrace(WMI_VDEV_SET_GTX_PARAMS_CMDID, cmd->vdev_id, 0); 194 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 195 WMI_VDEV_SET_GTX_PARAMS_CMDID); 196 if (QDF_IS_STATUS_ERROR(ret)) { 197 WMI_LOGE("Failed to set GTX PARAMS"); 198 wmi_buf_free(buf); 199 } 200 return ret; 201 } 202 203 /** 204 * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME 205 * @wmi_handle: wmi handle 206 * @ta_dhcp_ind: DHCP indication parameter 207 * 208 * Return: CDF Status 209 */ 210 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle, 211 wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind) 212 { 213 QDF_STATUS status; 214 wmi_buf_t buf = NULL; 215 uint8_t *buf_ptr; 216 wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp; 217 int len = sizeof(wmi_peer_set_param_cmd_fixed_param); 218 219 buf = wmi_buf_alloc(wmi_handle, len); 220 if (!buf) { 221 return QDF_STATUS_E_NOMEM; 222 } 223 224 buf_ptr = (uint8_t *) wmi_buf_data(buf); 225 peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr; 226 WMITLV_SET_HDR(&peer_set_param_fp->tlv_header, 227 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 228 WMITLV_GET_STRUCT_TLVLEN 229 (wmi_peer_set_param_cmd_fixed_param)); 230 231 /* fill in values */ 232 peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id; 233 peer_set_param_fp->param_id = ta_dhcp_ind->param_id; 234 peer_set_param_fp->param_value = ta_dhcp_ind->param_value; 235 qdf_mem_copy(&peer_set_param_fp->peer_macaddr, 236 &ta_dhcp_ind->peer_macaddr, 237 sizeof(ta_dhcp_ind->peer_macaddr)); 238 239 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, NO_SESSION, 0); 240 status = wmi_unified_cmd_send(wmi_handle, buf, 241 len, WMI_PEER_SET_PARAM_CMDID); 242 if (QDF_IS_STATUS_ERROR(status)) { 243 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 244 " returned Error %d", __func__, status); 245 wmi_buf_free(buf); 246 } 247 248 return status; 249 } 250 251 /** 252 * send_get_link_speed_cmd_tlv() -send command to get linkspeed 253 * @wmi_handle: wmi handle 254 * @pLinkSpeed: link speed info 255 * 256 * Return: CDF status 257 */ 258 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle, 259 wmi_mac_addr peer_macaddr) 260 { 261 wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd; 262 wmi_buf_t wmi_buf; 263 uint32_t len; 264 uint8_t *buf_ptr; 265 266 len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param); 267 wmi_buf = wmi_buf_alloc(wmi_handle, len); 268 if (!wmi_buf) { 269 return QDF_STATUS_E_NOMEM; 270 } 271 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 272 273 cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr; 274 WMITLV_SET_HDR(&cmd->tlv_header, 275 WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, 276 WMITLV_GET_STRUCT_TLVLEN 277 (wmi_peer_get_estimated_linkspeed_cmd_fixed_param)); 278 279 /* Copy the peer macaddress to the wma buffer */ 280 qdf_mem_copy(&cmd->peer_macaddr, 281 &peer_macaddr, 282 sizeof(peer_macaddr)); 283 284 wmi_mtrace(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID, cmd->vdev_id, 0); 285 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 286 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) { 287 WMI_LOGE("%s: failed to send link speed command", __func__); 288 wmi_buf_free(wmi_buf); 289 return QDF_STATUS_E_FAILURE; 290 } 291 return QDF_STATUS_SUCCESS; 292 } 293 294 /** 295 * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW 296 * @wmi_handl: wmi handle 297 * @cmd: Profiling command index 298 * @value1: parameter1 value 299 * @value2: parameter2 value 300 * 301 * Return: QDF_STATUS_SUCCESS for success else error code 302 */ 303 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle, 304 uint32_t cmd, uint32_t value1, uint32_t value2) 305 { 306 wmi_buf_t buf; 307 int32_t len = 0; 308 int ret; 309 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 310 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 311 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 312 wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd; 313 314 switch (cmd) { 315 case WMI_WLAN_PROFILE_TRIGGER_CMDID: 316 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 317 buf = wmi_buf_alloc(wmi_handle, len); 318 if (!buf) { 319 return QDF_STATUS_E_NOMEM; 320 } 321 prof_trig_cmd = 322 (wmi_wlan_profile_trigger_cmd_fixed_param *) 323 wmi_buf_data(buf); 324 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 325 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 326 WMITLV_GET_STRUCT_TLVLEN 327 (wmi_wlan_profile_trigger_cmd_fixed_param)); 328 prof_trig_cmd->enable = value1; 329 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 330 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 331 WMI_WLAN_PROFILE_TRIGGER_CMDID); 332 if (ret) { 333 WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d", 334 value1); 335 wmi_buf_free(buf); 336 return ret; 337 } 338 break; 339 340 case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID: 341 len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param); 342 buf = wmi_buf_alloc(wmi_handle, len); 343 if (!buf) { 344 return QDF_STATUS_E_NOMEM; 345 } 346 profile_getdata_cmd = 347 (wmi_wlan_profile_get_prof_data_cmd_fixed_param *) 348 wmi_buf_data(buf); 349 WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header, 350 WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param, 351 WMITLV_GET_STRUCT_TLVLEN 352 (wmi_wlan_profile_get_prof_data_cmd_fixed_param)); 353 wmi_mtrace(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, 354 NO_SESSION, 0); 355 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 356 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID); 357 if (ret) { 358 WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d", 359 value1, value2); 360 wmi_buf_free(buf); 361 return ret; 362 } 363 break; 364 365 case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID: 366 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 367 buf = wmi_buf_alloc(wmi_handle, len); 368 if (!buf) { 369 return QDF_STATUS_E_NOMEM; 370 } 371 hist_intvl_cmd = 372 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 373 wmi_buf_data(buf); 374 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 375 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 376 WMITLV_GET_STRUCT_TLVLEN 377 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 378 hist_intvl_cmd->profile_id = value1; 379 hist_intvl_cmd->value = value2; 380 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 381 NO_SESSION, 0); 382 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 383 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 384 if (ret) { 385 WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d", 386 value1, value2); 387 wmi_buf_free(buf); 388 return ret; 389 } 390 break; 391 392 case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID: 393 len = 394 sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 395 buf = wmi_buf_alloc(wmi_handle, len); 396 if (!buf) { 397 return QDF_STATUS_E_NOMEM; 398 } 399 profile_enable_cmd = 400 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 401 wmi_buf_data(buf); 402 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 403 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 404 WMITLV_GET_STRUCT_TLVLEN 405 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 406 profile_enable_cmd->profile_id = value1; 407 profile_enable_cmd->enable = value2; 408 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 409 NO_SESSION, 0); 410 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 411 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 412 if (ret) { 413 WMI_LOGE("enable cmd Failed for id %d value %d", 414 value1, value2); 415 wmi_buf_free(buf); 416 return ret; 417 } 418 break; 419 420 default: 421 WMI_LOGD("%s: invalid profiling command", __func__); 422 break; 423 } 424 425 return 0; 426 } 427 428 /** 429 * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter 430 * @wmi_handle: wmi handle 431 * @vdev_id: vdev id 432 * 433 * Return: QDF_STATUS_SUCCESS for success or error code 434 */ 435 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 436 { 437 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd; 438 wmi_buf_t buf; 439 int32_t len = sizeof(*cmd); 440 441 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 442 buf = wmi_buf_alloc(wmi_handle, len); 443 if (!buf) { 444 return QDF_STATUS_E_NOMEM; 445 } 446 cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *) 447 wmi_buf_data(buf); 448 WMITLV_SET_HDR(&cmd->tlv_header, 449 WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, 450 WMITLV_GET_STRUCT_TLVLEN 451 (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param)); 452 cmd->vdev_id = vdev_id; 453 cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE; 454 wmi_mtrace(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID, cmd->vdev_id, 0); 455 if (wmi_unified_cmd_send(wmi_handle, buf, len, 456 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) { 457 WMI_LOGP("%s: Failed to send NAT keepalive enable command", 458 __func__); 459 wmi_buf_free(buf); 460 return QDF_STATUS_E_FAILURE; 461 } 462 463 return 0; 464 } 465 466 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle, 467 struct wlm_latency_level_param *params) 468 { 469 wmi_wlm_config_cmd_fixed_param *cmd; 470 wmi_buf_t buf; 471 uint32_t len = sizeof(*cmd); 472 static uint32_t ll[4] = {100, 60, 40, 20}; 473 474 buf = wmi_buf_alloc(wmi_handle, len); 475 if (!buf) { 476 return QDF_STATUS_E_NOMEM; 477 } 478 cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf); 479 WMITLV_SET_HDR(&cmd->tlv_header, 480 WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param, 481 WMITLV_GET_STRUCT_TLVLEN 482 (wmi_wlm_config_cmd_fixed_param)); 483 cmd->vdev_id = params->vdev_id; 484 cmd->latency_level = params->wlm_latency_level; 485 cmd->ul_latency = ll[params->wlm_latency_level]; 486 cmd->dl_latency = ll[params->wlm_latency_level]; 487 cmd->flags = params->wlm_latency_flags; 488 wmi_mtrace(WMI_WLM_CONFIG_CMDID, cmd->vdev_id, 0); 489 if (wmi_unified_cmd_send(wmi_handle, buf, len, 490 WMI_WLM_CONFIG_CMDID)) { 491 WMI_LOGE("%s: Failed to send setting latency config command", 492 __func__); 493 wmi_buf_free(buf); 494 return QDF_STATUS_E_FAILURE; 495 } 496 497 return 0; 498 } 499 500 #ifdef FEATURE_WLAN_TDLS 501 /** 502 * tdls_get_wmi_offchannel_mode - Get WMI tdls off channel mode 503 * @tdls_sw_mode: tdls_sw_mode 504 * 505 * This function returns wmi tdls offchannel mode 506 * 507 * Return: enum value of wmi tdls offchannel mode 508 */ 509 static uint8_t tdls_get_wmi_offchannel_mode(uint8_t tdls_sw_mode) 510 { 511 uint8_t off_chan_mode; 512 513 switch (tdls_sw_mode) { 514 case ENABLE_CHANSWITCH: 515 off_chan_mode = WMI_TDLS_ENABLE_OFFCHANNEL; 516 break; 517 518 case DISABLE_CHANSWITCH: 519 off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL; 520 break; 521 522 default: 523 WMI_LOGD(FL("unknown tdls_sw_mode %d"), tdls_sw_mode); 524 off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL; 525 } 526 return off_chan_mode; 527 } 528 529 /** 530 * tdls_get_wmi_offchannel_bw - Get WMI tdls off channel Bandwidth 531 * @tdls_sw_mode: tdls_sw_mode 532 * 533 * This function returns wmi tdls offchannel bandwidth 534 * 535 * Return: TDLS offchannel bandwidth 536 */ 537 static uint8_t tdls_get_wmi_offchannel_bw(uint16_t tdls_off_ch_bw_offset) 538 { 539 uint8_t off_chan_bw; 540 541 switch (tdls_off_ch_bw_offset) { 542 case BW20: 543 off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ; 544 break; 545 case BW40_LOW_PRIMARY: 546 case BW40_HIGH_PRIMARY: 547 off_chan_bw = WMI_TDLS_OFFCHAN_40MHZ; 548 break; 549 case BW80: 550 off_chan_bw = WMI_TDLS_OFFCHAN_80MHZ; 551 break; 552 case BWALL: 553 off_chan_bw = WMI_TDLS_OFFCHAN_160MHZ; 554 break; 555 default: 556 WMI_LOGD(FL("unknown tdls offchannel bw offset %d"), 557 tdls_off_ch_bw_offset); 558 off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ; 559 } 560 return off_chan_bw; 561 } 562 563 /** 564 * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode 565 * @wmi_handle: wmi handle 566 * @chan_switch_params: Pointer to tdls channel switch parameter structure 567 * 568 * This function sets tdls off channel mode 569 * 570 * Return: 0 on success; Negative errno otherwise 571 */ 572 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle, 573 struct tdls_channel_switch_params *chan_switch_params) 574 { 575 wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd; 576 wmi_buf_t wmi_buf; 577 u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param); 578 579 wmi_buf = wmi_buf_alloc(wmi_handle, len); 580 if (!wmi_buf) { 581 return QDF_STATUS_E_FAILURE; 582 } 583 cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *) 584 wmi_buf_data(wmi_buf); 585 WMITLV_SET_HDR(&cmd->tlv_header, 586 WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, 587 WMITLV_GET_STRUCT_TLVLEN( 588 wmi_tdls_set_offchan_mode_cmd_fixed_param)); 589 590 WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr, 591 &cmd->peer_macaddr); 592 cmd->vdev_id = chan_switch_params->vdev_id; 593 cmd->offchan_mode = 594 tdls_get_wmi_offchannel_mode(chan_switch_params->tdls_sw_mode); 595 cmd->is_peer_responder = chan_switch_params->is_responder; 596 cmd->offchan_freq = chan_switch_params->tdls_off_chan_freq; 597 cmd->offchan_num = chan_switch_params->tdls_off_ch; 598 cmd->offchan_bw_bitmap = 599 tdls_get_wmi_offchannel_bw( 600 chan_switch_params->tdls_off_ch_bw_offset); 601 cmd->offchan_oper_class = chan_switch_params->oper_class; 602 603 WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"), 604 cmd->peer_macaddr.mac_addr31to0, 605 cmd->peer_macaddr.mac_addr47to32); 606 607 WMI_LOGD(FL( 608 "vdev_id: %d, off channel mode: %d, off channel Num: %d, " 609 "off channel frequency: %u off channel offset: 0x%x, " 610 " is_peer_responder: %d, operating class: %d"), 611 cmd->vdev_id, 612 cmd->offchan_mode, 613 cmd->offchan_num, 614 cmd->offchan_freq, 615 cmd->offchan_bw_bitmap, 616 cmd->is_peer_responder, 617 cmd->offchan_oper_class); 618 619 wmi_mtrace(WMI_TDLS_SET_OFFCHAN_MODE_CMDID, cmd->vdev_id, 0); 620 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 621 WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) { 622 WMI_LOGP(FL("failed to send tdls off chan command")); 623 wmi_buf_free(wmi_buf); 624 return QDF_STATUS_E_FAILURE; 625 } 626 627 return QDF_STATUS_SUCCESS; 628 } 629 630 /** 631 * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev 632 * @wmi_handle: wmi handle 633 * @pwmaTdlsparams: TDLS params 634 * 635 * Return: 0 for success or error code 636 */ 637 static QDF_STATUS 638 send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle, 639 struct tdls_info *tdls_param, 640 enum wmi_tdls_state tdls_state) 641 { 642 wmi_tdls_set_state_cmd_fixed_param *cmd; 643 wmi_buf_t wmi_buf; 644 645 uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param); 646 647 wmi_buf = wmi_buf_alloc(wmi_handle, len); 648 if (!wmi_buf) { 649 return QDF_STATUS_E_FAILURE; 650 } 651 cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf); 652 WMITLV_SET_HDR(&cmd->tlv_header, 653 WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param, 654 WMITLV_GET_STRUCT_TLVLEN 655 (wmi_tdls_set_state_cmd_fixed_param)); 656 cmd->vdev_id = tdls_param->vdev_id; 657 cmd->state = (A_UINT32)tdls_state; 658 cmd->notification_interval_ms = tdls_param->notification_interval_ms; 659 cmd->tx_discovery_threshold = tdls_param->tx_discovery_threshold; 660 cmd->tx_teardown_threshold = tdls_param->tx_teardown_threshold; 661 cmd->rssi_teardown_threshold = tdls_param->rssi_teardown_threshold; 662 cmd->rssi_delta = tdls_param->rssi_delta; 663 cmd->tdls_options = tdls_param->tdls_options; 664 cmd->tdls_peer_traffic_ind_window = tdls_param->peer_traffic_ind_window; 665 cmd->tdls_peer_traffic_response_timeout_ms = 666 tdls_param->peer_traffic_response_timeout; 667 cmd->tdls_puapsd_mask = tdls_param->puapsd_mask; 668 cmd->tdls_puapsd_inactivity_time_ms = 669 tdls_param->puapsd_inactivity_time; 670 cmd->tdls_puapsd_rx_frame_threshold = 671 tdls_param->puapsd_rx_frame_threshold; 672 cmd->teardown_notification_ms = 673 tdls_param->teardown_notification_ms; 674 cmd->tdls_peer_kickout_threshold = 675 tdls_param->tdls_peer_kickout_threshold; 676 cmd->tdls_discovery_wake_timeout = 677 tdls_param->tdls_discovery_wake_timeout; 678 679 WMI_LOGD("%s: tdls_state: %d, state: %d, " 680 "notification_interval_ms: %d, " 681 "tx_discovery_threshold: %d, " 682 "tx_teardown_threshold: %d, " 683 "rssi_teardown_threshold: %d, " 684 "rssi_delta: %d, " 685 "tdls_options: 0x%x, " 686 "tdls_peer_traffic_ind_window: %d, " 687 "tdls_peer_traffic_response_timeout: %d, " 688 "tdls_puapsd_mask: 0x%x, " 689 "tdls_puapsd_inactivity_time: %d, " 690 "tdls_puapsd_rx_frame_threshold: %d, " 691 "teardown_notification_ms: %d, " 692 "tdls_peer_kickout_threshold: %d, " 693 "tdls_discovery_wake_timeout: %d", 694 __func__, tdls_state, cmd->state, 695 cmd->notification_interval_ms, 696 cmd->tx_discovery_threshold, 697 cmd->tx_teardown_threshold, 698 cmd->rssi_teardown_threshold, 699 cmd->rssi_delta, 700 cmd->tdls_options, 701 cmd->tdls_peer_traffic_ind_window, 702 cmd->tdls_peer_traffic_response_timeout_ms, 703 cmd->tdls_puapsd_mask, 704 cmd->tdls_puapsd_inactivity_time_ms, 705 cmd->tdls_puapsd_rx_frame_threshold, 706 cmd->teardown_notification_ms, 707 cmd->tdls_peer_kickout_threshold, 708 cmd->tdls_discovery_wake_timeout); 709 710 wmi_mtrace(WMI_TDLS_SET_STATE_CMDID, cmd->vdev_id, 0); 711 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 712 WMI_TDLS_SET_STATE_CMDID)) { 713 WMI_LOGP("%s: failed to send tdls set state command", __func__); 714 wmi_buf_free(wmi_buf); 715 return QDF_STATUS_E_FAILURE; 716 } 717 WMI_LOGD("%s: vdev_id %d", __func__, tdls_param->vdev_id); 718 719 return QDF_STATUS_SUCCESS; 720 } 721 722 /** 723 * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state 724 * @wmi_handle: wmi handle 725 * @peer_state: TDLS peer state params 726 * 727 * Return: QDF_STATUS_SUCCESS for success or error code 728 */ 729 static QDF_STATUS 730 send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle, 731 struct tdls_peer_update_state *peer_state, 732 uint32_t *ch_mhz) 733 { 734 struct tdls_peer_params *in_peer_cap; 735 struct tdls_ch_params *in_chan_info; 736 wmi_tdls_peer_update_cmd_fixed_param *cmd; 737 wmi_tdls_peer_capabilities *peer_cap; 738 wmi_channel *chan_info; 739 wmi_buf_t wmi_buf; 740 uint8_t *buf_ptr; 741 uint32_t i; 742 int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) + 743 sizeof(wmi_tdls_peer_capabilities); 744 745 in_peer_cap = &peer_state->peer_cap; 746 len += WMI_TLV_HDR_SIZE + 747 sizeof(wmi_channel) * in_peer_cap->peer_chanlen; 748 749 wmi_buf = wmi_buf_alloc(wmi_handle, len); 750 if (!wmi_buf) { 751 return QDF_STATUS_E_FAILURE; 752 } 753 754 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 755 cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr; 756 WMITLV_SET_HDR(&cmd->tlv_header, 757 WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, 758 WMITLV_GET_STRUCT_TLVLEN 759 (wmi_tdls_peer_update_cmd_fixed_param)); 760 761 cmd->vdev_id = peer_state->vdev_id; 762 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_state->peer_macaddr, 763 &cmd->peer_macaddr); 764 765 cmd->peer_state = peer_state->peer_state; 766 767 WMI_LOGD("%s: vdev_id: %d, peermac: %pM, " 768 "peer_macaddr.mac_addr31to0: 0x%x, " 769 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d", 770 __func__, cmd->vdev_id, peer_state->peer_macaddr, 771 cmd->peer_macaddr.mac_addr31to0, 772 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state); 773 774 buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param); 775 peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr; 776 WMITLV_SET_HDR(&peer_cap->tlv_header, 777 WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, 778 WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities)); 779 780 if ((in_peer_cap->peer_uapsd_queue & 0x08) >> 3) 781 WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap); 782 if ((in_peer_cap->peer_uapsd_queue & 0x04) >> 2) 783 WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap); 784 if ((in_peer_cap->peer_uapsd_queue & 0x02) >> 1) 785 WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap); 786 if (in_peer_cap->peer_uapsd_queue & 0x01) 787 WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap); 788 789 /* Ack and More Data Ack are sent as 0, so no need to set 790 * but fill SP 791 */ 792 WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, in_peer_cap->peer_max_sp); 793 794 peer_cap->buff_sta_support = in_peer_cap->peer_buff_sta_support; 795 peer_cap->off_chan_support = in_peer_cap->peer_off_chan_support; 796 peer_cap->peer_curr_operclass = in_peer_cap->peer_curr_operclass; 797 /* self curr operclass is not being used and so pass op class for 798 * preferred off chan in it. 799 */ 800 peer_cap->self_curr_operclass = in_peer_cap->opclass_for_prefoffchan; 801 peer_cap->peer_chan_len = in_peer_cap->peer_chanlen; 802 peer_cap->peer_operclass_len = in_peer_cap->peer_oper_classlen; 803 804 WMI_LOGD("%s: peer_operclass_len: %d", 805 __func__, peer_cap->peer_operclass_len); 806 for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) { 807 peer_cap->peer_operclass[i] = in_peer_cap->peer_oper_class[i]; 808 WMI_LOGD("%s: peer_operclass[%d]: %d", 809 __func__, i, peer_cap->peer_operclass[i]); 810 } 811 812 peer_cap->is_peer_responder = in_peer_cap->is_peer_responder; 813 peer_cap->pref_offchan_freq = in_peer_cap->pref_offchan_freq; 814 peer_cap->pref_offchan_num = in_peer_cap->pref_off_channum; 815 peer_cap->pref_offchan_bw = in_peer_cap->pref_off_chan_bandwidth; 816 817 WMI_LOGD 818 ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, " 819 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: " 820 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:" 821 " %d, pref_offchan_bw: %d, pref_offchan_freq: %u", 822 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support, 823 peer_cap->off_chan_support, peer_cap->peer_curr_operclass, 824 peer_cap->self_curr_operclass, peer_cap->peer_chan_len, 825 peer_cap->peer_operclass_len, peer_cap->is_peer_responder, 826 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw, 827 peer_cap->pref_offchan_freq); 828 829 /* next fill variable size array of peer chan info */ 830 buf_ptr += sizeof(wmi_tdls_peer_capabilities); 831 WMITLV_SET_HDR(buf_ptr, 832 WMITLV_TAG_ARRAY_STRUC, 833 sizeof(wmi_channel) * 834 in_peer_cap->peer_chanlen); 835 836 chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE); 837 in_chan_info = in_peer_cap->peer_chan; 838 839 for (i = 0; i < in_peer_cap->peer_chanlen; ++i) { 840 WMITLV_SET_HDR(&chan_info->tlv_header, 841 WMITLV_TAG_STRUC_wmi_channel, 842 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 843 chan_info->mhz = ch_mhz[i]; 844 chan_info->band_center_freq1 = chan_info->mhz; 845 chan_info->band_center_freq2 = 0; 846 847 WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz); 848 849 if (in_chan_info->dfs_set) { 850 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE); 851 WMI_LOGI("chan[%d] DFS[%d]", 852 in_chan_info->chan_id, 853 in_chan_info->dfs_set); 854 } 855 856 if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ) 857 WMI_SET_CHANNEL_MODE(chan_info, MODE_11G); 858 else 859 WMI_SET_CHANNEL_MODE(chan_info, MODE_11A); 860 861 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, in_chan_info->pwr); 862 WMI_SET_CHANNEL_REG_POWER(chan_info, in_chan_info->pwr); 863 WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, 864 in_chan_info->pwr); 865 866 chan_info++; 867 in_chan_info++; 868 } 869 870 wmi_mtrace(WMI_TDLS_PEER_UPDATE_CMDID, cmd->vdev_id, 0); 871 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 872 WMI_TDLS_PEER_UPDATE_CMDID)) { 873 WMI_LOGE("%s: failed to send tdls peer update state command", 874 __func__); 875 wmi_buf_free(wmi_buf); 876 return QDF_STATUS_E_FAILURE; 877 } 878 879 return QDF_STATUS_SUCCESS; 880 } 881 882 /** 883 * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event 884 * @wmi_handle: wmi handle 885 * @param evt_buf: pointer to event buffer 886 * @param param: Pointer to hold vdev tdls param 887 * 888 * Return: QDF_STATUS_SUCCESS for success or error code 889 */ 890 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle, 891 void *evt_buf, struct tdls_event_info *param) 892 { 893 WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf; 894 wmi_tdls_peer_event_fixed_param *evt; 895 896 param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf; 897 if (!param_buf) { 898 WMI_LOGE("%s: NULL param_buf", __func__); 899 return QDF_STATUS_E_NULL_VALUE; 900 } 901 902 evt = param_buf->fixed_param; 903 904 qdf_mem_zero(param, sizeof(*param)); 905 906 param->vdev_id = evt->vdev_id; 907 WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr, 908 param->peermac.bytes); 909 switch (evt->peer_status) { 910 case WMI_TDLS_SHOULD_DISCOVER: 911 param->message_type = TDLS_SHOULD_DISCOVER; 912 break; 913 case WMI_TDLS_SHOULD_TEARDOWN: 914 param->message_type = TDLS_SHOULD_TEARDOWN; 915 break; 916 case WMI_TDLS_PEER_DISCONNECTED: 917 param->message_type = TDLS_PEER_DISCONNECTED; 918 break; 919 case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION: 920 param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY; 921 break; 922 default: 923 WMI_LOGE("%s: Discarding unknown tdls event %d from target", 924 __func__, evt->peer_status); 925 return QDF_STATUS_E_INVAL; 926 }; 927 928 switch (evt->peer_reason) { 929 case WMI_TDLS_TEARDOWN_REASON_TX: 930 param->peer_reason = TDLS_TEARDOWN_TX; 931 break; 932 case WMI_TDLS_TEARDOWN_REASON_RSSI: 933 param->peer_reason = TDLS_TEARDOWN_RSSI; 934 break; 935 case WMI_TDLS_TEARDOWN_REASON_SCAN: 936 param->peer_reason = TDLS_TEARDOWN_SCAN; 937 break; 938 case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE: 939 param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE; 940 break; 941 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: 942 param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT; 943 break; 944 case WMI_TDLS_TEARDOWN_REASON_BAD_PTR: 945 param->peer_reason = TDLS_TEARDOWN_BAD_PTR; 946 break; 947 case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: 948 param->peer_reason = TDLS_TEARDOWN_NO_RSP; 949 break; 950 case WMI_TDLS_ENTER_BUF_STA: 951 param->peer_reason = TDLS_PEER_ENTER_BUF_STA; 952 break; 953 case WMI_TDLS_EXIT_BUF_STA: 954 param->peer_reason = TDLS_PEER_EXIT_BUF_STA; 955 break; 956 case WMI_TDLS_ENTER_BT_BUSY_MODE: 957 param->peer_reason = TDLS_ENTER_BT_BUSY; 958 break; 959 case WMI_TDLS_EXIT_BT_BUSY_MODE: 960 param->peer_reason = TDLS_EXIT_BT_BUSY; 961 break; 962 case WMI_TDLS_SCAN_STARTED_EVENT: 963 param->peer_reason = TDLS_SCAN_STARTED; 964 break; 965 case WMI_TDLS_SCAN_COMPLETED_EVENT: 966 param->peer_reason = TDLS_SCAN_COMPLETED; 967 break; 968 969 default: 970 WMI_LOGE("%s: unknown reason %d in tdls event %d from target", 971 __func__, evt->peer_reason, evt->peer_status); 972 return QDF_STATUS_E_INVAL; 973 }; 974 975 WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d", 976 __func__, param->peermac.bytes, param->message_type, 977 param->peer_reason, param->vdev_id); 978 979 return QDF_STATUS_SUCCESS; 980 } 981 982 void wmi_tdls_attach_tlv(struct wmi_unified *wmi_handle) 983 { 984 struct wmi_ops *ops = wmi_handle->ops; 985 986 ops->send_set_tdls_offchan_mode_cmd = 987 send_set_tdls_offchan_mode_cmd_tlv; 988 ops->send_update_fw_tdls_state_cmd = 989 send_update_fw_tdls_state_cmd_tlv; 990 ops->send_update_tdls_peer_state_cmd = 991 send_update_tdls_peer_state_cmd_tlv; 992 ops->extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv; 993 } 994 #endif /* FEATURE_WLAN_TDLS */ 995 996 /* 997 * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware 998 * @wmi_handle: Pointer to WMi handle 999 * @ie_data: Pointer for ie data 1000 * 1001 * This function sends IE information to firmware 1002 * 1003 * Return: QDF_STATUS_SUCCESS for success otherwise failure 1004 * 1005 */ 1006 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle, 1007 struct vdev_ie_info_param *ie_info) 1008 { 1009 wmi_vdev_set_ie_cmd_fixed_param *cmd; 1010 wmi_buf_t buf; 1011 uint8_t *buf_ptr; 1012 uint32_t len, ie_len_aligned; 1013 QDF_STATUS ret; 1014 1015 ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t)); 1016 /* Allocate memory for the WMI command */ 1017 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned; 1018 1019 buf = wmi_buf_alloc(wmi_handle, len); 1020 if (!buf) { 1021 return QDF_STATUS_E_NOMEM; 1022 } 1023 1024 buf_ptr = wmi_buf_data(buf); 1025 qdf_mem_zero(buf_ptr, len); 1026 1027 /* Populate the WMI command */ 1028 cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr; 1029 1030 WMITLV_SET_HDR(&cmd->tlv_header, 1031 WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param, 1032 WMITLV_GET_STRUCT_TLVLEN( 1033 wmi_vdev_set_ie_cmd_fixed_param)); 1034 cmd->vdev_id = ie_info->vdev_id; 1035 cmd->ie_id = ie_info->ie_id; 1036 cmd->ie_len = ie_info->length; 1037 cmd->band = ie_info->band; 1038 1039 WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id, 1040 ie_info->length, ie_info->vdev_id); 1041 1042 buf_ptr += sizeof(*cmd); 1043 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 1044 buf_ptr += WMI_TLV_HDR_SIZE; 1045 1046 qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len); 1047 1048 wmi_mtrace(WMI_VDEV_SET_IE_CMDID, cmd->vdev_id, 0); 1049 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1050 WMI_VDEV_SET_IE_CMDID); 1051 if (QDF_IS_STATUS_ERROR(ret)) { 1052 WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret); 1053 wmi_buf_free(buf); 1054 } 1055 1056 return ret; 1057 } 1058 1059 /** 1060 * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw 1061 * @wmi_handle: wmi handle 1062 * @custom_addr: base mac address 1063 * 1064 * Return: QDF_STATUS_SUCCESS for success or error code 1065 */ 1066 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle, 1067 uint8_t *custom_addr) 1068 { 1069 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd; 1070 wmi_buf_t buf; 1071 int err; 1072 1073 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1074 if (!buf) { 1075 return QDF_STATUS_E_NOMEM; 1076 } 1077 1078 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf); 1079 qdf_mem_zero(cmd, sizeof(*cmd)); 1080 1081 WMITLV_SET_HDR(&cmd->tlv_header, 1082 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, 1083 WMITLV_GET_STRUCT_TLVLEN 1084 (wmi_pdev_set_base_macaddr_cmd_fixed_param)); 1085 WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr); 1086 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1087 wmi_handle, 1088 WMI_HOST_PDEV_ID_SOC); 1089 wmi_mtrace(WMI_PDEV_SET_BASE_MACADDR_CMDID, NO_SESSION, 0); 1090 err = wmi_unified_cmd_send(wmi_handle, buf, 1091 sizeof(*cmd), 1092 WMI_PDEV_SET_BASE_MACADDR_CMDID); 1093 if (err) { 1094 WMI_LOGE("Failed to send set_base_macaddr cmd"); 1095 wmi_buf_free(buf); 1096 return QDF_STATUS_E_FAILURE; 1097 } 1098 1099 return 0; 1100 } 1101 1102 #ifdef FEATURE_BLACKLIST_MGR 1103 1104 static WMI_BSSID_DISALLOW_LIST_TYPE 1105 wmi_get_wmi_reject_ap_type(enum blm_reject_ap_type reject_ap_type) 1106 { 1107 switch (reject_ap_type) { 1108 case USERSPACE_AVOID_TYPE: 1109 return WMI_BSSID_DISALLOW_USER_SPACE_AVOID_LIST; 1110 case DRIVER_AVOID_TYPE: 1111 return WMI_BSSID_DISALLOW_DRIVER_AVOID_LIST; 1112 case USERSPACE_BLACKLIST_TYPE: 1113 return WMI_BSSID_DISALLOW_USER_SPACE_BLACK_LIST; 1114 case DRIVER_BLACKLIST_TYPE: 1115 return WMI_BSSID_DISALLOW_DRIVER_BLACK_LIST; 1116 case DRIVER_RSSI_REJECT_TYPE: 1117 return WMI_BSSID_DISALLOW_RSSI_REJECT_LIST; 1118 default: 1119 return WMI_BSSID_DISALLOW_DRIVER_AVOID_LIST; 1120 } 1121 } 1122 1123 static QDF_STATUS 1124 send_reject_ap_list_cmd_tlv(wmi_unified_t wmi_handle, 1125 struct reject_ap_params *reject_params) 1126 { 1127 wmi_buf_t buf; 1128 QDF_STATUS status; 1129 uint32_t len, list_tlv_len; 1130 int i; 1131 uint8_t *buf_ptr; 1132 wmi_pdev_dsm_filter_fixed_param *chan_list_fp; 1133 wmi_pdev_bssid_disallow_list_config_param *chan_list; 1134 struct reject_ap_config_params *reject_list = reject_params->bssid_list; 1135 uint8_t num_of_reject_bssid = reject_params->num_of_reject_bssid; 1136 1137 if (!num_of_reject_bssid) { 1138 WMI_LOGD("%s : invalid number of channels %d", __func__, 1139 num_of_reject_bssid); 1140 return QDF_STATUS_E_EMPTY; 1141 } 1142 1143 list_tlv_len = sizeof(*chan_list) * num_of_reject_bssid; 1144 1145 len = sizeof(*chan_list_fp) + list_tlv_len + WMI_TLV_HDR_SIZE; 1146 buf = wmi_buf_alloc(wmi_handle, len); 1147 if (!buf) 1148 return QDF_STATUS_E_NOMEM; 1149 1150 WMI_LOGD("num of reject BSSIDs %d", num_of_reject_bssid); 1151 1152 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1153 chan_list_fp = (wmi_pdev_dsm_filter_fixed_param *)buf_ptr; 1154 WMITLV_SET_HDR(&chan_list_fp->tlv_header, 1155 WMITLV_TAG_STRUC_wmi_pdev_dsm_filter_fixed_param, 1156 WMITLV_GET_STRUCT_TLVLEN 1157 (wmi_pdev_dsm_filter_fixed_param)); 1158 1159 buf_ptr += sizeof(wmi_pdev_dsm_filter_fixed_param); 1160 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, list_tlv_len); 1161 1162 buf_ptr += WMI_TLV_HDR_SIZE; 1163 chan_list = (wmi_pdev_bssid_disallow_list_config_param *)buf_ptr; 1164 for (i = 0; i < num_of_reject_bssid; i++) { 1165 1166 WMITLV_SET_HDR(&chan_list->tlv_header, 1167 WMITLV_TAG_STRUC_wmi_pdev_bssid_disallow_list_config_param, 1168 WMITLV_GET_STRUCT_TLVLEN 1169 (wmi_pdev_bssid_disallow_list_config_param)); 1170 WMI_CHAR_ARRAY_TO_MAC_ADDR(reject_list[i].bssid.bytes, 1171 &chan_list->bssid); 1172 chan_list->bssid_type = 1173 wmi_get_wmi_reject_ap_type(reject_list[i].reject_ap_type); 1174 chan_list->expected_rssi = reject_list[i].expected_rssi; 1175 chan_list->remaining_disallow_duration = 1176 reject_list[i].reject_duration; 1177 chan_list++; 1178 } 1179 1180 wmi_mtrace(WMI_PDEV_DSM_FILTER_CMDID, NO_SESSION, 0); 1181 status = wmi_unified_cmd_send(wmi_handle, buf, 1182 len, WMI_PDEV_DSM_FILTER_CMDID); 1183 if (QDF_IS_STATUS_ERROR(status)) { 1184 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_DSM_FILTER_CMDID returned Error %d", 1185 status); 1186 goto error; 1187 } 1188 1189 return QDF_STATUS_SUCCESS; 1190 error: 1191 wmi_buf_free(buf); 1192 return status; 1193 } 1194 1195 void wmi_blacklist_mgr_attach_tlv(struct wmi_unified *wmi_handle) 1196 { 1197 struct wmi_ops *ops = wmi_handle->ops; 1198 1199 ops->send_reject_ap_list_cmd = send_reject_ap_list_cmd_tlv; 1200 } 1201 #endif 1202 1203 /** 1204 * send_sar_limit_cmd_tlv() - send sar limit cmd to fw 1205 * @wmi_handle: wmi handle 1206 * @params: sar limit params 1207 * 1208 * Return: QDF_STATUS_SUCCESS for success or error code 1209 */ 1210 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle, 1211 struct sar_limit_cmd_params *sar_limit_params) 1212 { 1213 wmi_buf_t buf; 1214 QDF_STATUS qdf_status; 1215 wmi_sar_limits_cmd_fixed_param *cmd; 1216 int i; 1217 uint8_t *buf_ptr; 1218 wmi_sar_limit_cmd_row *wmi_sar_rows_list; 1219 struct sar_limit_cmd_row *sar_rows_list; 1220 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 1221 1222 len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows; 1223 buf = wmi_buf_alloc(wmi_handle, len); 1224 if (!buf) { 1225 qdf_status = QDF_STATUS_E_NOMEM; 1226 goto end; 1227 } 1228 1229 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1230 cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr; 1231 WMITLV_SET_HDR(&cmd->tlv_header, 1232 WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param, 1233 WMITLV_GET_STRUCT_TLVLEN 1234 (wmi_sar_limits_cmd_fixed_param)); 1235 cmd->sar_enable = sar_limit_params->sar_enable; 1236 cmd->commit_limits = sar_limit_params->commit_limits; 1237 cmd->num_limit_rows = sar_limit_params->num_limit_rows; 1238 1239 WMI_LOGD("no of sar rows = %d, len = %d", 1240 sar_limit_params->num_limit_rows, len); 1241 buf_ptr += sizeof(*cmd); 1242 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1243 sizeof(wmi_sar_limit_cmd_row) * 1244 sar_limit_params->num_limit_rows); 1245 if (cmd->num_limit_rows == 0) 1246 goto send_sar_limits; 1247 1248 wmi_sar_rows_list = (wmi_sar_limit_cmd_row *) 1249 (buf_ptr + WMI_TLV_HDR_SIZE); 1250 sar_rows_list = sar_limit_params->sar_limit_row_list; 1251 1252 for (i = 0; i < sar_limit_params->num_limit_rows; i++) { 1253 WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header, 1254 WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row, 1255 WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row)); 1256 wmi_sar_rows_list->band_id = sar_rows_list->band_id; 1257 wmi_sar_rows_list->chain_id = sar_rows_list->chain_id; 1258 wmi_sar_rows_list->mod_id = sar_rows_list->mod_id; 1259 wmi_sar_rows_list->limit_value = sar_rows_list->limit_value; 1260 wmi_sar_rows_list->validity_bitmap = 1261 sar_rows_list->validity_bitmap; 1262 WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d", 1263 i, wmi_sar_rows_list->band_id, 1264 wmi_sar_rows_list->chain_id, 1265 wmi_sar_rows_list->mod_id, 1266 wmi_sar_rows_list->limit_value, 1267 wmi_sar_rows_list->validity_bitmap); 1268 sar_rows_list++; 1269 wmi_sar_rows_list++; 1270 } 1271 send_sar_limits: 1272 wmi_mtrace(WMI_SAR_LIMITS_CMDID, NO_SESSION, 0); 1273 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 1274 WMI_SAR_LIMITS_CMDID); 1275 1276 if (QDF_IS_STATUS_ERROR(qdf_status)) { 1277 WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID"); 1278 wmi_buf_free(buf); 1279 } 1280 1281 end: 1282 return qdf_status; 1283 } 1284 1285 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle) 1286 { 1287 wmi_sar_get_limits_cmd_fixed_param *cmd; 1288 wmi_buf_t wmi_buf; 1289 uint32_t len; 1290 QDF_STATUS status; 1291 1292 WMI_LOGD(FL("Enter")); 1293 1294 len = sizeof(*cmd); 1295 wmi_buf = wmi_buf_alloc(wmi_handle, len); 1296 if (!wmi_buf) { 1297 return QDF_STATUS_E_NOMEM; 1298 } 1299 1300 cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf); 1301 1302 WMITLV_SET_HDR(&cmd->tlv_header, 1303 WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param, 1304 WMITLV_GET_STRUCT_TLVLEN 1305 (wmi_sar_get_limits_cmd_fixed_param)); 1306 1307 cmd->reserved = 0; 1308 1309 wmi_mtrace(WMI_SAR_GET_LIMITS_CMDID, NO_SESSION, 0); 1310 status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 1311 WMI_SAR_GET_LIMITS_CMDID); 1312 if (QDF_IS_STATUS_ERROR(status)) { 1313 WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status); 1314 wmi_buf_free(wmi_buf); 1315 } 1316 1317 WMI_LOGD(FL("Exit")); 1318 1319 return status; 1320 } 1321 1322 /** 1323 * wmi_sar2_result_string() - return string conversion of sar2 result 1324 * @result: sar2 result value 1325 * 1326 * This utility function helps log string conversion of sar2 result. 1327 * 1328 * Return: string conversion of sar 2 result, if match found; 1329 * "Unknown response" otherwise. 1330 */ 1331 static const char *wmi_sar2_result_string(uint32_t result) 1332 { 1333 switch (result) { 1334 CASE_RETURN_STRING(WMI_SAR2_SUCCESS); 1335 CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX); 1336 CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX); 1337 CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR); 1338 CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE); 1339 default: 1340 return "Unknown response"; 1341 } 1342 } 1343 1344 /** 1345 * extract_sar2_result_event_tlv() - process sar response event from FW. 1346 * @handle: wma handle 1347 * @event: event buffer 1348 * @len: buffer length 1349 * 1350 * Return: 0 for success or error code 1351 */ 1352 static QDF_STATUS extract_sar2_result_event_tlv(void *handle, 1353 uint8_t *event, 1354 uint32_t len) 1355 { 1356 wmi_sar2_result_event_fixed_param *sar2_fixed_param; 1357 1358 WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf = 1359 (WMI_SAR2_RESULT_EVENTID_param_tlvs *)event; 1360 1361 if (!param_buf) { 1362 WMI_LOGI("Invalid sar2 result event buffer"); 1363 return QDF_STATUS_E_INVAL; 1364 } 1365 1366 sar2_fixed_param = param_buf->fixed_param; 1367 if (!sar2_fixed_param) { 1368 WMI_LOGI("Invalid sar2 result event fixed param buffer"); 1369 return QDF_STATUS_E_INVAL; 1370 } 1371 1372 WMI_LOGI("SAR2 result: %s", 1373 wmi_sar2_result_string(sar2_fixed_param->result)); 1374 1375 return QDF_STATUS_SUCCESS; 1376 } 1377 1378 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle, 1379 uint8_t *evt_buf, 1380 struct sar_limit_event *event) 1381 { 1382 wmi_sar_get_limits_event_fixed_param *fixed_param; 1383 WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf; 1384 wmi_sar_get_limit_event_row *row_in; 1385 struct sar_limit_event_row *row_out; 1386 uint32_t row; 1387 1388 if (!evt_buf) { 1389 WMI_LOGE(FL("input event is NULL")); 1390 return QDF_STATUS_E_INVAL; 1391 } 1392 if (!event) { 1393 WMI_LOGE(FL("output event is NULL")); 1394 return QDF_STATUS_E_INVAL; 1395 } 1396 1397 param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf; 1398 1399 fixed_param = param_buf->fixed_param; 1400 if (!fixed_param) { 1401 WMI_LOGE(FL("Invalid fixed param")); 1402 return QDF_STATUS_E_INVAL; 1403 } 1404 1405 event->sar_enable = fixed_param->sar_enable; 1406 event->num_limit_rows = fixed_param->num_limit_rows; 1407 1408 if (event->num_limit_rows > param_buf->num_sar_get_limits) { 1409 WMI_LOGE(FL("Num rows %d exceeds sar_get_limits rows len %d"), 1410 event->num_limit_rows, param_buf->num_sar_get_limits); 1411 return QDF_STATUS_E_INVAL; 1412 } 1413 1414 if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) { 1415 QDF_ASSERT(0); 1416 WMI_LOGE(FL("Num rows %d exceeds max of %d"), 1417 event->num_limit_rows, 1418 MAX_SAR_LIMIT_ROWS_SUPPORTED); 1419 event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED; 1420 } 1421 1422 row_in = param_buf->sar_get_limits; 1423 if (!row_in) { 1424 WMI_LOGD("sar_get_limits is NULL"); 1425 } else { 1426 row_out = &event->sar_limit_row[0]; 1427 for (row = 0; row < event->num_limit_rows; row++) { 1428 row_out->band_id = row_in->band_id; 1429 row_out->chain_id = row_in->chain_id; 1430 row_out->mod_id = row_in->mod_id; 1431 row_out->limit_value = row_in->limit_value; 1432 row_out++; 1433 row_in++; 1434 } 1435 } 1436 1437 return QDF_STATUS_SUCCESS; 1438 } 1439 1440 /** 1441 * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid 1442 * @wmi_handle: wmi handler 1443 * @pmk_info: pointer to PMK cache entry 1444 * @vdev_id: vdev id 1445 * 1446 * Return: 0 for success and non zero for failure 1447 */ 1448 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle, 1449 struct wmi_unified_pmk_cache *pmk_info) 1450 { 1451 wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd; 1452 wmi_buf_t buf; 1453 QDF_STATUS status; 1454 uint8_t *buf_ptr; 1455 wmi_pmk_cache *pmksa; 1456 uint32_t len = sizeof(*cmd); 1457 1458 if (!pmk_info) 1459 return QDF_STATUS_E_INVAL; 1460 1461 if (!pmk_info->is_flush_all) 1462 len += WMI_TLV_HDR_SIZE + sizeof(*pmksa); 1463 1464 buf = wmi_buf_alloc(wmi_handle, len); 1465 if (!buf) { 1466 return QDF_STATUS_E_NOMEM; 1467 } 1468 1469 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1470 cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr; 1471 1472 WMITLV_SET_HDR(&cmd->tlv_header, 1473 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param, 1474 WMITLV_GET_STRUCT_TLVLEN( 1475 wmi_pdev_update_pmk_cache_cmd_fixed_param)); 1476 1477 cmd->vdev_id = pmk_info->vdev_id; 1478 1479 /* If pmk_info->is_flush_all is true, this is a flush request */ 1480 if (pmk_info->is_flush_all) { 1481 cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL; 1482 cmd->num_cache = 0; 1483 goto send_cmd; 1484 } 1485 1486 cmd->num_cache = 1; 1487 buf_ptr += sizeof(*cmd); 1488 1489 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1490 sizeof(*pmksa)); 1491 buf_ptr += WMI_TLV_HDR_SIZE; 1492 1493 pmksa = (wmi_pmk_cache *)buf_ptr; 1494 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache, 1495 WMITLV_GET_STRUCT_TLVLEN 1496 (wmi_pmk_cache)); 1497 pmksa->pmk_len = pmk_info->pmk_len; 1498 qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len); 1499 pmksa->pmkid_len = pmk_info->pmkid_len; 1500 qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len); 1501 qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr)); 1502 pmksa->ssid.ssid_len = pmk_info->ssid.length; 1503 qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid), 1504 pmksa->ssid.ssid_len); 1505 pmksa->cache_id = pmk_info->cache_id; 1506 pmksa->cat_flag = pmk_info->cat_flag; 1507 pmksa->action_flag = pmk_info->action_flag; 1508 1509 send_cmd: 1510 wmi_mtrace(WMI_PDEV_UPDATE_PMK_CACHE_CMDID, cmd->vdev_id, 0); 1511 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1512 WMI_PDEV_UPDATE_PMK_CACHE_CMDID); 1513 if (status != QDF_STATUS_SUCCESS) { 1514 WMI_LOGE("%s: failed to send set del pmkid cache command %d", 1515 __func__, status); 1516 wmi_buf_free(buf); 1517 } 1518 1519 return status; 1520 } 1521 1522 /** 1523 * send_del_ts_cmd_tlv() - send DELTS request to fw 1524 * @wmi_handle: wmi handle 1525 * @msg: delts params 1526 * 1527 * Return: CDF status 1528 */ 1529 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 1530 uint8_t ac) 1531 { 1532 wmi_vdev_wmm_delts_cmd_fixed_param *cmd; 1533 wmi_buf_t buf; 1534 int32_t len = sizeof(*cmd); 1535 1536 buf = wmi_buf_alloc(wmi_handle, len); 1537 if (!buf) { 1538 return QDF_STATUS_E_NOMEM; 1539 } 1540 cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf); 1541 WMITLV_SET_HDR(&cmd->tlv_header, 1542 WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param, 1543 WMITLV_GET_STRUCT_TLVLEN 1544 (wmi_vdev_wmm_delts_cmd_fixed_param)); 1545 cmd->vdev_id = vdev_id; 1546 cmd->ac = ac; 1547 1548 WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d", 1549 cmd->vdev_id, cmd->ac, __func__, __LINE__); 1550 wmi_mtrace(WMI_VDEV_WMM_DELTS_CMDID, cmd->vdev_id, 0); 1551 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1552 WMI_VDEV_WMM_DELTS_CMDID)) { 1553 WMI_LOGP("%s: Failed to send vdev DELTS command", __func__); 1554 wmi_buf_free(buf); 1555 return QDF_STATUS_E_FAILURE; 1556 } 1557 1558 return QDF_STATUS_SUCCESS; 1559 } 1560 1561 /** 1562 * send_aggr_qos_cmd_tlv() - send aggr qos request to fw 1563 * @wmi_handle: handle to wmi 1564 * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests. 1565 * 1566 * A function to handle WMI_AGGR_QOS_REQ. This will send out 1567 * ADD_TS requests to firmware in loop for all the ACs with 1568 * active flow. 1569 * 1570 * Return: CDF status 1571 */ 1572 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle, 1573 struct aggr_add_ts_param *aggr_qos_rsp_msg) 1574 { 1575 int i = 0; 1576 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 1577 wmi_buf_t buf; 1578 int32_t len = sizeof(*cmd); 1579 1580 for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) { 1581 /* if flow in this AC is active */ 1582 if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) { 1583 /* 1584 * as per implementation of wma_add_ts_req() we 1585 * are not waiting any response from firmware so 1586 * apart from sending ADDTS to firmware just send 1587 * success to upper layers 1588 */ 1589 aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS; 1590 1591 buf = wmi_buf_alloc(wmi_handle, len); 1592 if (!buf) { 1593 return QDF_STATUS_E_NOMEM; 1594 } 1595 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) 1596 wmi_buf_data(buf); 1597 WMITLV_SET_HDR(&cmd->tlv_header, 1598 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 1599 WMITLV_GET_STRUCT_TLVLEN 1600 (wmi_vdev_wmm_addts_cmd_fixed_param)); 1601 cmd->vdev_id = aggr_qos_rsp_msg->vdev_id; 1602 cmd->ac = 1603 WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo. 1604 traffic.userPrio); 1605 cmd->medium_time_us = 1606 aggr_qos_rsp_msg->tspec[i].mediumTime * 32; 1607 cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO; 1608 WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d", 1609 __func__, __LINE__, cmd->vdev_id, cmd->ac, 1610 cmd->medium_time_us, cmd->downgrade_type); 1611 wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0); 1612 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1613 WMI_VDEV_WMM_ADDTS_CMDID)) { 1614 WMI_LOGP("%s: Failed to send vdev ADDTS command", 1615 __func__); 1616 aggr_qos_rsp_msg->status[i] = 1617 QDF_STATUS_E_FAILURE; 1618 wmi_buf_free(buf); 1619 return QDF_STATUS_E_FAILURE; 1620 } 1621 } 1622 } 1623 1624 return QDF_STATUS_SUCCESS; 1625 } 1626 1627 /** 1628 * send_add_ts_cmd_tlv() - send ADDTS request to fw 1629 * @wmi_handle: wmi handle 1630 * @msg: ADDTS params 1631 * 1632 * Return: CDF status 1633 */ 1634 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle, 1635 struct add_ts_param *msg) 1636 { 1637 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 1638 wmi_buf_t buf; 1639 int32_t len = sizeof(*cmd); 1640 1641 msg->status = QDF_STATUS_SUCCESS; 1642 1643 buf = wmi_buf_alloc(wmi_handle, len); 1644 if (!buf) { 1645 return QDF_STATUS_E_NOMEM; 1646 } 1647 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf); 1648 WMITLV_SET_HDR(&cmd->tlv_header, 1649 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 1650 WMITLV_GET_STRUCT_TLVLEN 1651 (wmi_vdev_wmm_addts_cmd_fixed_param)); 1652 cmd->vdev_id = msg->vdev_id; 1653 cmd->ac = msg->tspec.tsinfo.traffic.userPrio; 1654 cmd->medium_time_us = msg->tspec.mediumTime * 32; 1655 cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP; 1656 WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d", 1657 cmd->vdev_id, cmd->ac, cmd->medium_time_us, 1658 cmd->downgrade_type, __func__, __LINE__); 1659 wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0); 1660 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1661 WMI_VDEV_WMM_ADDTS_CMDID)) { 1662 WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__); 1663 msg->status = QDF_STATUS_E_FAILURE; 1664 wmi_buf_free(buf); 1665 return QDF_STATUS_E_FAILURE; 1666 } 1667 1668 return QDF_STATUS_SUCCESS; 1669 } 1670 1671 /** 1672 * send_process_add_periodic_tx_ptrn_cmd_tlv() - add periodic tx pattern 1673 * @wmi_handle: wmi handle 1674 * @pattern: tx pattern params 1675 * @vdev_id: vdev id 1676 * 1677 * Return: QDF status 1678 */ 1679 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv( 1680 wmi_unified_t wmi_handle, 1681 struct periodic_tx_pattern *pattern, 1682 uint8_t vdev_id) 1683 { 1684 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 1685 wmi_buf_t wmi_buf; 1686 uint32_t len; 1687 uint8_t *buf_ptr; 1688 uint32_t ptrn_len, ptrn_len_aligned; 1689 int j; 1690 1691 ptrn_len = pattern->ucPtrnSize; 1692 ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t)); 1693 len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) + 1694 WMI_TLV_HDR_SIZE + ptrn_len_aligned; 1695 1696 wmi_buf = wmi_buf_alloc(wmi_handle, len); 1697 if (!wmi_buf) { 1698 return QDF_STATUS_E_NOMEM; 1699 } 1700 1701 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 1702 1703 cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr; 1704 WMITLV_SET_HDR(&cmd->tlv_header, 1705 WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 1706 WMITLV_GET_STRUCT_TLVLEN 1707 (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 1708 1709 /* Pass the pattern id to delete for the corresponding vdev id */ 1710 cmd->vdev_id = vdev_id; 1711 cmd->pattern_id = pattern->ucPtrnId; 1712 cmd->timeout = pattern->usPtrnIntervalMs; 1713 cmd->length = pattern->ucPtrnSize; 1714 1715 /* Pattern info */ 1716 buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 1717 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned); 1718 buf_ptr += WMI_TLV_HDR_SIZE; 1719 qdf_mem_copy(buf_ptr, pattern->ucPattern, ptrn_len); 1720 for (j = 0; j < pattern->ucPtrnSize; j++) 1721 WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff); 1722 1723 WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d", 1724 __func__, cmd->pattern_id, cmd->vdev_id); 1725 1726 wmi_mtrace(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0); 1727 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 1728 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 1729 WMI_LOGE("%s: failed to add pattern set state command", 1730 __func__); 1731 wmi_buf_free(wmi_buf); 1732 return QDF_STATUS_E_FAILURE; 1733 } 1734 return QDF_STATUS_SUCCESS; 1735 } 1736 1737 /** 1738 * send_process_del_periodic_tx_ptrn_cmd_tlv() - del periodic tx pattern 1739 * @wmi_handle: wmi handle 1740 * @vdev_id: vdev id 1741 * @pattern_id: pattern id 1742 * 1743 * Return: QDF status 1744 */ 1745 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv( 1746 wmi_unified_t wmi_handle, 1747 uint8_t vdev_id, 1748 uint8_t pattern_id) 1749 { 1750 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 1751 wmi_buf_t wmi_buf; 1752 uint32_t len = 1753 sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 1754 1755 wmi_buf = wmi_buf_alloc(wmi_handle, len); 1756 if (!wmi_buf) { 1757 return QDF_STATUS_E_NOMEM; 1758 } 1759 1760 cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) 1761 wmi_buf_data(wmi_buf); 1762 WMITLV_SET_HDR(&cmd->tlv_header, 1763 WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 1764 WMITLV_GET_STRUCT_TLVLEN 1765 (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 1766 1767 /* Pass the pattern id to delete for the corresponding vdev id */ 1768 cmd->vdev_id = vdev_id; 1769 cmd->pattern_id = pattern_id; 1770 WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d", 1771 __func__, cmd->pattern_id, cmd->vdev_id); 1772 1773 wmi_mtrace(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0); 1774 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 1775 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 1776 WMI_LOGE("%s: failed to send del pattern command", __func__); 1777 wmi_buf_free(wmi_buf); 1778 return QDF_STATUS_E_FAILURE; 1779 } 1780 return QDF_STATUS_SUCCESS; 1781 } 1782 1783 /** 1784 * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware 1785 * @wmi_handle: wmi handle 1786 * @timer_val: auto shutdown timer value 1787 * 1788 * Return: CDF status 1789 */ 1790 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle, 1791 uint32_t timer_val) 1792 { 1793 QDF_STATUS status; 1794 wmi_buf_t buf = NULL; 1795 uint8_t *buf_ptr; 1796 wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd; 1797 int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param); 1798 1799 WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d", 1800 __func__, timer_val); 1801 1802 buf = wmi_buf_alloc(wmi_handle, len); 1803 if (!buf) { 1804 return QDF_STATUS_E_NOMEM; 1805 } 1806 1807 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1808 wmi_auto_sh_cmd = 1809 (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr; 1810 wmi_auto_sh_cmd->timer_value = timer_val; 1811 1812 WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header, 1813 WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param, 1814 WMITLV_GET_STRUCT_TLVLEN 1815 (wmi_host_auto_shutdown_cfg_cmd_fixed_param)); 1816 1817 wmi_mtrace(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID, NO_SESSION, 0); 1818 status = wmi_unified_cmd_send(wmi_handle, buf, 1819 len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID); 1820 if (QDF_IS_STATUS_ERROR(status)) { 1821 WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d", 1822 __func__, status); 1823 wmi_buf_free(buf); 1824 } 1825 1826 return status; 1827 } 1828 1829 /** 1830 * send_set_led_flashing_cmd_tlv() - set led flashing in fw 1831 * @wmi_handle: wmi handle 1832 * @flashing: flashing request 1833 * 1834 * Return: CDF status 1835 */ 1836 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle, 1837 struct flashing_req_params *flashing) 1838 { 1839 wmi_set_led_flashing_cmd_fixed_param *cmd; 1840 QDF_STATUS status; 1841 wmi_buf_t buf; 1842 uint8_t *buf_ptr; 1843 int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param); 1844 1845 buf = wmi_buf_alloc(wmi_handle, len); 1846 if (!buf) { 1847 return QDF_STATUS_E_NOMEM; 1848 } 1849 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1850 cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr; 1851 WMITLV_SET_HDR(&cmd->tlv_header, 1852 WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param, 1853 WMITLV_GET_STRUCT_TLVLEN 1854 (wmi_set_led_flashing_cmd_fixed_param)); 1855 cmd->pattern_id = flashing->pattern_id; 1856 cmd->led_x0 = flashing->led_x0; 1857 cmd->led_x1 = flashing->led_x1; 1858 1859 wmi_mtrace(WMI_PDEV_SET_LED_FLASHING_CMDID, NO_SESSION, 0); 1860 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1861 WMI_PDEV_SET_LED_FLASHING_CMDID); 1862 if (QDF_IS_STATUS_ERROR(status)) { 1863 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 1864 " returned Error %d", __func__, status); 1865 wmi_buf_free(buf); 1866 } 1867 1868 return status; 1869 } 1870 1871 /** 1872 * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request 1873 * @wmi_handle: wmi handle 1874 * @ch_avoid_update_req: channel avoid update params 1875 * 1876 * Return: CDF status 1877 */ 1878 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle) 1879 { 1880 QDF_STATUS status; 1881 wmi_buf_t buf = NULL; 1882 uint8_t *buf_ptr; 1883 wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp; 1884 int len = sizeof(wmi_chan_avoid_update_cmd_param); 1885 1886 buf = wmi_buf_alloc(wmi_handle, len); 1887 if (!buf) { 1888 return QDF_STATUS_E_NOMEM; 1889 } 1890 1891 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1892 ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr; 1893 WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header, 1894 WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param, 1895 WMITLV_GET_STRUCT_TLVLEN 1896 (wmi_chan_avoid_update_cmd_param)); 1897 1898 wmi_mtrace(WMI_CHAN_AVOID_UPDATE_CMDID, NO_SESSION, 0); 1899 status = wmi_unified_cmd_send(wmi_handle, buf, 1900 len, WMI_CHAN_AVOID_UPDATE_CMDID); 1901 if (QDF_IS_STATUS_ERROR(status)) { 1902 WMI_LOGE("wmi_unified_cmd_send" 1903 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE" 1904 " returned Error %d", status); 1905 wmi_buf_free(buf); 1906 } 1907 1908 return status; 1909 } 1910 1911 /** 1912 * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW 1913 * @wmi_handle: wmi handle 1914 * @msg: PCL structure containing the PCL and the number of channels 1915 * 1916 * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN 1917 * firmware. The DBS Manager is the consumer of this information in the WLAN 1918 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs 1919 * to migrate to a new channel without host driver involvement. An example of 1920 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will 1921 * manage the channel selection without firmware involvement. 1922 * 1923 * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual 1924 * channel list. The weights corresponds to the channels sent in 1925 * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher 1926 * weightage compared to the non PCL channels. 1927 * 1928 * Return: Success if the cmd is sent successfully to the firmware 1929 */ 1930 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle, 1931 struct wmi_pcl_chan_weights *msg) 1932 { 1933 wmi_pdev_set_pcl_cmd_fixed_param *cmd; 1934 wmi_buf_t buf; 1935 uint8_t *buf_ptr; 1936 uint32_t *cmd_args, i, len; 1937 uint32_t chan_len; 1938 1939 chan_len = msg->saved_num_chan; 1940 1941 len = sizeof(*cmd) + 1942 WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t)); 1943 1944 buf = wmi_buf_alloc(wmi_handle, len); 1945 if (!buf) { 1946 return QDF_STATUS_E_NOMEM; 1947 } 1948 1949 cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf); 1950 buf_ptr = (uint8_t *) cmd; 1951 WMITLV_SET_HDR(&cmd->tlv_header, 1952 WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param, 1953 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param)); 1954 1955 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1956 wmi_handle, 1957 WMI_HOST_PDEV_ID_SOC); 1958 cmd->num_chan = chan_len; 1959 WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan); 1960 1961 buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param); 1962 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1963 (chan_len * sizeof(uint32_t))); 1964 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 1965 for (i = 0; i < chan_len ; i++) { 1966 cmd_args[i] = msg->weighed_valid_list[i]; 1967 WMI_LOGD("%s: freq:%d weight:%d", __func__, 1968 msg->saved_chan_list[i], cmd_args[i]); 1969 } 1970 wmi_mtrace(WMI_PDEV_SET_PCL_CMDID, NO_SESSION, 0); 1971 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1972 WMI_PDEV_SET_PCL_CMDID)) { 1973 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__); 1974 wmi_buf_free(buf); 1975 return QDF_STATUS_E_FAILURE; 1976 } 1977 return QDF_STATUS_SUCCESS; 1978 } 1979 1980 #ifdef WLAN_POLICY_MGR_ENABLE 1981 /** 1982 * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW 1983 * @wmi_handle: wmi handle 1984 * @msg: Dual MAC config parameters 1985 * 1986 * Configures WLAN firmware with the dual MAC features 1987 * 1988 * Return: QDF_STATUS. 0 on success. 1989 */ 1990 static 1991 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle, 1992 struct policy_mgr_dual_mac_config *msg) 1993 { 1994 wmi_pdev_set_mac_config_cmd_fixed_param *cmd; 1995 wmi_buf_t buf; 1996 uint32_t len; 1997 1998 len = sizeof(*cmd); 1999 2000 buf = wmi_buf_alloc(wmi_handle, len); 2001 if (!buf) { 2002 return QDF_STATUS_E_FAILURE; 2003 } 2004 2005 cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf); 2006 WMITLV_SET_HDR(&cmd->tlv_header, 2007 WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param, 2008 WMITLV_GET_STRUCT_TLVLEN( 2009 wmi_pdev_set_mac_config_cmd_fixed_param)); 2010 2011 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2012 wmi_handle, 2013 WMI_HOST_PDEV_ID_SOC); 2014 cmd->concurrent_scan_config_bits = msg->scan_config; 2015 cmd->fw_mode_config_bits = msg->fw_mode_config; 2016 WMI_LOGD("%s: scan_config:%x fw_mode_config:%x", 2017 __func__, msg->scan_config, msg->fw_mode_config); 2018 2019 wmi_mtrace(WMI_PDEV_SET_MAC_CONFIG_CMDID, NO_SESSION, 0); 2020 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2021 WMI_PDEV_SET_MAC_CONFIG_CMDID)) { 2022 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID", 2023 __func__); 2024 wmi_buf_free(buf); 2025 return QDF_STATUS_E_FAILURE; 2026 } 2027 return QDF_STATUS_SUCCESS; 2028 } 2029 2030 void wmi_policy_mgr_attach_tlv(struct wmi_unified *wmi_handle) 2031 { 2032 struct wmi_ops *ops = wmi_handle->ops; 2033 2034 ops->send_pdev_set_dual_mac_config_cmd = 2035 send_pdev_set_dual_mac_config_cmd_tlv; 2036 } 2037 #endif /* WLAN_POLICY_MGR_ENABLE */ 2038 2039 /** 2040 * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime 2041 * configuration params 2042 * @wma_handle: wma handler 2043 * @dwelltime_params: pointer to dwelltime_params 2044 * 2045 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 2046 */ 2047 static 2048 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle, 2049 struct wmi_adaptive_dwelltime_params *dwelltime_params) 2050 { 2051 wmi_scan_adaptive_dwell_config_fixed_param *dwell_param; 2052 wmi_scan_adaptive_dwell_parameters_tlv *cmd; 2053 wmi_buf_t buf; 2054 uint8_t *buf_ptr; 2055 int32_t err; 2056 int len; 2057 2058 len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 2059 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 2060 len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv); 2061 buf = wmi_buf_alloc(wmi_handle, len); 2062 if (!buf) { 2063 return QDF_STATUS_E_NOMEM; 2064 } 2065 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2066 dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr; 2067 WMITLV_SET_HDR(&dwell_param->tlv_header, 2068 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param, 2069 WMITLV_GET_STRUCT_TLVLEN 2070 (wmi_scan_adaptive_dwell_config_fixed_param)); 2071 2072 dwell_param->enable = dwelltime_params->is_enabled; 2073 buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 2074 WMITLV_SET_HDR(buf_ptr, 2075 WMITLV_TAG_ARRAY_STRUC, 2076 sizeof(wmi_scan_adaptive_dwell_parameters_tlv)); 2077 buf_ptr += WMI_TLV_HDR_SIZE; 2078 2079 cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr; 2080 WMITLV_SET_HDR(&cmd->tlv_header, 2081 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv, 2082 WMITLV_GET_STRUCT_TLVLEN( 2083 wmi_scan_adaptive_dwell_parameters_tlv)); 2084 2085 cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode; 2086 cmd->adapative_lpf_weight = dwelltime_params->lpf_weight; 2087 cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval; 2088 cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold; 2089 wmi_mtrace(WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID, NO_SESSION, 0); 2090 err = wmi_unified_cmd_send(wmi_handle, buf, 2091 len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID); 2092 if (err) { 2093 WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err); 2094 wmi_buf_free(buf); 2095 return QDF_STATUS_E_FAILURE; 2096 } 2097 2098 return QDF_STATUS_SUCCESS; 2099 } 2100 2101 /** 2102 * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection 2103 * configuration params 2104 * @wmi_handle: wmi handler 2105 * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params 2106 * 2107 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 2108 */ 2109 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle, 2110 struct wmi_dbs_scan_sel_params *dbs_scan_params) 2111 { 2112 wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param; 2113 wmi_scan_dbs_duty_cycle_tlv_param *cmd; 2114 wmi_buf_t buf; 2115 uint8_t *buf_ptr; 2116 QDF_STATUS err; 2117 uint32_t i; 2118 int len; 2119 2120 len = sizeof(*dbs_scan_param); 2121 len += WMI_TLV_HDR_SIZE; 2122 len += dbs_scan_params->num_clients * sizeof(*cmd); 2123 2124 buf = wmi_buf_alloc(wmi_handle, len); 2125 if (!buf) { 2126 return QDF_STATUS_E_NOMEM; 2127 } 2128 2129 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2130 dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr; 2131 WMITLV_SET_HDR(&dbs_scan_param->tlv_header, 2132 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param, 2133 WMITLV_GET_STRUCT_TLVLEN 2134 (wmi_scan_dbs_duty_cycle_fixed_param)); 2135 2136 dbs_scan_param->num_clients = dbs_scan_params->num_clients; 2137 dbs_scan_param->pdev_id = dbs_scan_params->pdev_id; 2138 buf_ptr += sizeof(*dbs_scan_param); 2139 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2140 (sizeof(*cmd) * dbs_scan_params->num_clients)); 2141 buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE; 2142 2143 for (i = 0; i < dbs_scan_params->num_clients; i++) { 2144 cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr; 2145 WMITLV_SET_HDR(&cmd->tlv_header, 2146 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv, 2147 WMITLV_GET_STRUCT_TLVLEN( 2148 wmi_scan_dbs_duty_cycle_tlv_param)); 2149 cmd->module_id = dbs_scan_params->module_id[i]; 2150 cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i]; 2151 cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i]; 2152 buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd); 2153 } 2154 2155 wmi_mtrace(WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID, NO_SESSION, 0); 2156 err = wmi_unified_cmd_send(wmi_handle, buf, 2157 len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID); 2158 if (QDF_IS_STATUS_ERROR(err)) { 2159 WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err); 2160 wmi_buf_free(buf); 2161 return QDF_STATUS_E_FAILURE; 2162 } 2163 2164 return QDF_STATUS_SUCCESS; 2165 } 2166 2167 /** 2168 * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request 2169 * @wmi_handle: wmi handler 2170 * @req_buf: set arp stats request buffer 2171 * 2172 * Return: 0 for success and non zero for failure 2173 */ 2174 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 2175 struct set_arp_stats *req_buf) 2176 { 2177 wmi_buf_t buf = NULL; 2178 QDF_STATUS status; 2179 int len; 2180 uint8_t *buf_ptr; 2181 wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp; 2182 2183 len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 2184 if (req_buf->pkt_type_bitmap) { 2185 len += WMI_TLV_HDR_SIZE; 2186 len += sizeof(wmi_vdev_set_connectivity_check_stats); 2187 } 2188 buf = wmi_buf_alloc(wmi_handle, len); 2189 if (!buf) { 2190 return QDF_STATUS_E_NOMEM; 2191 } 2192 2193 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2194 wmi_set_arp = 2195 (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr; 2196 WMITLV_SET_HDR(&wmi_set_arp->tlv_header, 2197 WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param, 2198 WMITLV_GET_STRUCT_TLVLEN 2199 (wmi_vdev_set_arp_stats_cmd_fixed_param)); 2200 2201 /* fill in per roam config values */ 2202 wmi_set_arp->vdev_id = req_buf->vdev_id; 2203 2204 wmi_set_arp->set_clr = req_buf->flag; 2205 wmi_set_arp->pkt_type = req_buf->pkt_type; 2206 wmi_set_arp->ipv4 = req_buf->ip_addr; 2207 2208 WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u", 2209 wmi_set_arp->vdev_id, wmi_set_arp->set_clr, 2210 wmi_set_arp->pkt_type, wmi_set_arp->ipv4); 2211 2212 /* 2213 * pkt_type_bitmap should be non-zero to ensure 2214 * presence of additional stats. 2215 */ 2216 if (req_buf->pkt_type_bitmap) { 2217 wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats; 2218 2219 buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 2220 WMITLV_SET_HDR(buf_ptr, 2221 WMITLV_TAG_ARRAY_STRUC, 2222 sizeof(wmi_vdev_set_connectivity_check_stats)); 2223 buf_ptr += WMI_TLV_HDR_SIZE; 2224 wmi_set_connect_stats = 2225 (wmi_vdev_set_connectivity_check_stats *)buf_ptr; 2226 WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header, 2227 WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats, 2228 WMITLV_GET_STRUCT_TLVLEN( 2229 wmi_vdev_set_connectivity_check_stats)); 2230 wmi_set_connect_stats->pkt_type_bitmap = 2231 req_buf->pkt_type_bitmap; 2232 wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port; 2233 wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port; 2234 wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4; 2235 2236 WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u", 2237 wmi_set_connect_stats->pkt_type_bitmap, 2238 wmi_set_connect_stats->tcp_src_port, 2239 wmi_set_connect_stats->tcp_dst_port, 2240 wmi_set_connect_stats->icmp_ipv4); 2241 } 2242 2243 /* Send per roam config parameters */ 2244 wmi_mtrace(WMI_VDEV_SET_ARP_STAT_CMDID, NO_SESSION, 0); 2245 status = wmi_unified_cmd_send(wmi_handle, buf, 2246 len, WMI_VDEV_SET_ARP_STAT_CMDID); 2247 if (QDF_IS_STATUS_ERROR(status)) { 2248 WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d", 2249 status); 2250 goto error; 2251 } 2252 2253 WMI_LOGD(FL("set arp stats flag=%d, vdev=%d"), 2254 req_buf->flag, req_buf->vdev_id); 2255 return QDF_STATUS_SUCCESS; 2256 error: 2257 wmi_buf_free(buf); 2258 2259 return status; 2260 } 2261 2262 /** 2263 * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request 2264 * @wmi_handle: wmi handler 2265 * @req_buf: get arp stats request buffer 2266 * 2267 * Return: 0 for success and non zero for failure 2268 */ 2269 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 2270 struct get_arp_stats *req_buf) 2271 { 2272 wmi_buf_t buf = NULL; 2273 QDF_STATUS status; 2274 int len; 2275 uint8_t *buf_ptr; 2276 wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats; 2277 2278 len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param); 2279 buf = wmi_buf_alloc(wmi_handle, len); 2280 if (!buf) { 2281 return QDF_STATUS_E_NOMEM; 2282 } 2283 2284 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2285 get_arp_stats = 2286 (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr; 2287 WMITLV_SET_HDR(&get_arp_stats->tlv_header, 2288 WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param, 2289 WMITLV_GET_STRUCT_TLVLEN 2290 (wmi_vdev_get_arp_stats_cmd_fixed_param)); 2291 2292 /* fill in arp stats req cmd values */ 2293 get_arp_stats->vdev_id = req_buf->vdev_id; 2294 2295 WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id); 2296 /* Send per roam config parameters */ 2297 wmi_mtrace(WMI_VDEV_GET_ARP_STAT_CMDID, NO_SESSION, 0); 2298 status = wmi_unified_cmd_send(wmi_handle, buf, 2299 len, WMI_VDEV_GET_ARP_STAT_CMDID); 2300 if (QDF_IS_STATUS_ERROR(status)) { 2301 WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d", 2302 status); 2303 goto error; 2304 } 2305 2306 return QDF_STATUS_SUCCESS; 2307 error: 2308 wmi_buf_free(buf); 2309 2310 return status; 2311 } 2312 2313 /** 2314 * send_peer_unmap_conf_cmd_tlv() - send PEER UNMAP conf command to fw 2315 * @wmi: wmi handle 2316 * @vdev_id: vdev id 2317 * @peer_id_cnt: no. of peer ids 2318 * @peer_id_list: list of peer ids 2319 * 2320 * Return: QDF_STATUS_SUCCESS for success or error code 2321 */ 2322 static QDF_STATUS send_peer_unmap_conf_cmd_tlv(wmi_unified_t wmi, 2323 uint8_t vdev_id, 2324 uint32_t peer_id_cnt, 2325 uint16_t *peer_id_list) 2326 { 2327 int i; 2328 wmi_buf_t buf; 2329 uint8_t *buf_ptr; 2330 A_UINT32 *peer_ids; 2331 wmi_peer_unmap_response_cmd_fixed_param *cmd; 2332 uint32_t peer_id_list_len; 2333 uint32_t len = sizeof(*cmd); 2334 QDF_STATUS status; 2335 2336 if (!peer_id_cnt || !peer_id_list) 2337 return QDF_STATUS_E_FAILURE; 2338 2339 len += WMI_TLV_HDR_SIZE; 2340 2341 peer_id_list_len = peer_id_cnt * sizeof(A_UINT32); 2342 2343 len += peer_id_list_len; 2344 2345 buf = wmi_buf_alloc(wmi, len); 2346 2347 if (!buf) { 2348 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 2349 return QDF_STATUS_E_NOMEM; 2350 } 2351 2352 cmd = (wmi_peer_unmap_response_cmd_fixed_param *)wmi_buf_data(buf); 2353 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2354 2355 WMITLV_SET_HDR(&cmd->tlv_header, 2356 WMITLV_TAG_STRUC_wmi_peer_unmap_response_cmd_fixed_param, 2357 WMITLV_GET_STRUCT_TLVLEN 2358 (wmi_peer_unmap_response_cmd_fixed_param)); 2359 2360 buf_ptr += sizeof(wmi_peer_unmap_response_cmd_fixed_param); 2361 2362 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 2363 peer_id_list_len); 2364 2365 peer_ids = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 2366 2367 for (i = 0; i < peer_id_cnt; i++) 2368 peer_ids[i] = peer_id_list[i]; 2369 2370 WMI_LOGD("%s: vdev_id %d peer_id_cnt %d", __func__, 2371 vdev_id, peer_id_cnt); 2372 wmi_mtrace(WMI_PEER_UNMAP_RESPONSE_CMDID, vdev_id, 0); 2373 status = wmi_unified_cmd_send(wmi, buf, len, 2374 WMI_PEER_UNMAP_RESPONSE_CMDID); 2375 if (QDF_IS_STATUS_ERROR(status)) { 2376 WMI_LOGE("%s: Failed to send peer unmap conf command: Err[%d]", 2377 __func__, status); 2378 wmi_buf_free(buf); 2379 return status; 2380 } 2381 2382 return QDF_STATUS_SUCCESS; 2383 } 2384 2385 void wmi_sta_attach_tlv(wmi_unified_t wmi_handle) 2386 { 2387 struct wmi_ops *ops = wmi_handle->ops; 2388 2389 ops->send_set_sta_sa_query_param_cmd = 2390 send_set_sta_sa_query_param_cmd_tlv; 2391 ops->send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv; 2392 ops->send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv; 2393 ops->send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv; 2394 ops->send_get_link_speed_cmd = send_get_link_speed_cmd_tlv; 2395 ops->send_fw_profiling_cmd = send_fw_profiling_cmd_tlv; 2396 ops->send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv; 2397 ops->send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv; 2398 ops->send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv; 2399 ops->send_set_base_macaddr_indicate_cmd = 2400 send_set_base_macaddr_indicate_cmd_tlv; 2401 ops->send_sar_limit_cmd = send_sar_limit_cmd_tlv; 2402 ops->get_sar_limit_cmd = get_sar_limit_cmd_tlv; 2403 ops->extract_sar_limit_event = extract_sar_limit_event_tlv; 2404 ops->extract_sar2_result_event = extract_sar2_result_event_tlv; 2405 ops->send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv; 2406 ops->send_del_ts_cmd = send_del_ts_cmd_tlv; 2407 ops->send_aggr_qos_cmd = send_aggr_qos_cmd_tlv; 2408 ops->send_add_ts_cmd = send_add_ts_cmd_tlv; 2409 ops->send_process_add_periodic_tx_ptrn_cmd = 2410 send_process_add_periodic_tx_ptrn_cmd_tlv; 2411 ops->send_process_del_periodic_tx_ptrn_cmd = 2412 send_process_del_periodic_tx_ptrn_cmd_tlv; 2413 ops->send_set_auto_shutdown_timer_cmd = 2414 send_set_auto_shutdown_timer_cmd_tlv; 2415 ops->send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv; 2416 ops->send_process_ch_avoid_update_cmd = 2417 send_process_ch_avoid_update_cmd_tlv; 2418 ops->send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv; 2419 ops->send_adapt_dwelltime_params_cmd = 2420 send_adapt_dwelltime_params_cmd_tlv; 2421 ops->send_dbs_scan_sel_params_cmd = 2422 send_dbs_scan_sel_params_cmd_tlv; 2423 ops->send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv; 2424 ops->send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv; 2425 ops->send_peer_unmap_conf_cmd = send_peer_unmap_conf_cmd_tlv; 2426 2427 wmi_tdls_attach_tlv(wmi_handle); 2428 wmi_policy_mgr_attach_tlv(wmi_handle); 2429 wmi_blacklist_mgr_attach_tlv(wmi_handle); 2430 } 2431 2432