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