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