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