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