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