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