1 /* 2 * Copyright (c) 2016-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 "wmi_unified_api.h" 20 #include "wmi.h" 21 #include "wmi_version.h" 22 #include "wmi_unified_priv.h" 23 #include "wmi_version_whitelist.h" 24 #include <qdf_module.h> 25 #include <wlan_defs.h> 26 #include <wlan_cmn.h> 27 #include <htc_services.h> 28 #ifdef FEATURE_WLAN_APF 29 #include "wmi_unified_apf_tlv.h" 30 #endif 31 #ifdef WLAN_FEATURE_ACTION_OUI 32 #include "wmi_unified_action_oui_tlv.h" 33 #endif 34 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 35 #include "wlan_pmo_hw_filter_public_struct.h" 36 #endif 37 #include <wlan_utility.h> 38 #ifdef WLAN_SUPPORT_GREEN_AP 39 #include "wlan_green_ap_api.h" 40 #endif 41 42 #include "wmi_unified_twt_api.h" 43 44 #ifdef WLAN_POLICY_MGR_ENABLE 45 #include "wlan_policy_mgr_public_struct.h" 46 #endif 47 48 #ifdef WMI_SMART_ANT_SUPPORT 49 #include "wmi_unified_smart_ant_api.h" 50 #endif 51 52 #ifdef WMI_DBR_SUPPORT 53 #include "wmi_unified_dbr_api.h" 54 #endif 55 56 #ifdef WMI_ATF_SUPPORT 57 #include "wmi_unified_atf_api.h" 58 #endif 59 60 #ifdef WMI_AP_SUPPORT 61 #include "wmi_unified_ap_api.h" 62 #endif 63 64 /* HTC service ids for WMI for multi-radio */ 65 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 66 WMI_CONTROL_SVC_WMAC1, 67 WMI_CONTROL_SVC_WMAC2}; 68 69 /** 70 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 71 * host to target defines. 72 * @param pdev_id: host pdev_id to be converted. 73 * Return: target pdev_id after conversion. 74 */ 75 static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id) 76 { 77 switch (pdev_id) { 78 case WMI_HOST_PDEV_ID_SOC: 79 return WMI_PDEV_ID_SOC; 80 case WMI_HOST_PDEV_ID_0: 81 return WMI_PDEV_ID_1ST; 82 case WMI_HOST_PDEV_ID_1: 83 return WMI_PDEV_ID_2ND; 84 case WMI_HOST_PDEV_ID_2: 85 return WMI_PDEV_ID_3RD; 86 } 87 88 QDF_ASSERT(0); 89 90 return WMI_PDEV_ID_SOC; 91 } 92 93 /** 94 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 95 * target to host defines. 96 * @param pdev_id: target pdev_id to be converted. 97 * Return: host pdev_id after conversion. 98 */ 99 static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id) 100 { 101 switch (pdev_id) { 102 case WMI_PDEV_ID_SOC: 103 return WMI_HOST_PDEV_ID_SOC; 104 case WMI_PDEV_ID_1ST: 105 return WMI_HOST_PDEV_ID_0; 106 case WMI_PDEV_ID_2ND: 107 return WMI_HOST_PDEV_ID_1; 108 case WMI_PDEV_ID_3RD: 109 return WMI_HOST_PDEV_ID_2; 110 } 111 112 QDF_ASSERT(0); 113 114 return WMI_HOST_PDEV_ID_SOC; 115 } 116 117 /** 118 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 119 * 120 * Return None. 121 */ 122 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle) 123 { 124 wmi_handle->ops->convert_pdev_id_host_to_target = 125 convert_host_pdev_id_to_target_pdev_id; 126 wmi_handle->ops->convert_pdev_id_target_to_host = 127 convert_target_pdev_id_to_host_pdev_id; 128 } 129 130 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 131 * buffer. 132 * @wmi_handle: pointer to wmi_handle 133 * @cmd: pointer target vdev create command buffer 134 * @param: pointer host params for vdev create 135 * 136 * Return: None 137 */ 138 #ifdef CONFIG_MCL 139 static inline void copy_vdev_create_pdev_id( 140 struct wmi_unified *wmi_handle, 141 wmi_vdev_create_cmd_fixed_param * cmd, 142 struct vdev_create_params *param) 143 { 144 cmd->pdev_id = WMI_PDEV_ID_SOC; 145 } 146 #else 147 static inline void copy_vdev_create_pdev_id( 148 struct wmi_unified *wmi_handle, 149 wmi_vdev_create_cmd_fixed_param * cmd, 150 struct vdev_create_params *param) 151 { 152 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 153 param->pdev_id); 154 } 155 #endif 156 157 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 158 { 159 uint16_t mtrace_message_id; 160 161 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 162 (QDF_WMI_MTRACE_GRP_ID(message_id) << 163 QDF_WMI_MTRACE_CMD_NUM_BITS); 164 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 165 mtrace_message_id, vdev_id, data); 166 } 167 168 qdf_export_symbol(wmi_mtrace); 169 170 /** 171 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 172 * @wmi_handle: wmi handle 173 * @param: pointer to hold vdev create parameter 174 * @macaddr: vdev mac address 175 * 176 * Return: QDF_STATUS_SUCCESS for success or error code 177 */ 178 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 179 uint8_t macaddr[IEEE80211_ADDR_LEN], 180 struct vdev_create_params *param) 181 { 182 wmi_vdev_create_cmd_fixed_param *cmd; 183 wmi_buf_t buf; 184 int32_t len = sizeof(*cmd); 185 QDF_STATUS ret; 186 int num_bands = 2; 187 uint8_t *buf_ptr; 188 wmi_vdev_txrx_streams *txrx_streams; 189 190 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 191 buf = wmi_buf_alloc(wmi_handle, len); 192 if (!buf) 193 return QDF_STATUS_E_NOMEM; 194 195 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 196 WMITLV_SET_HDR(&cmd->tlv_header, 197 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 198 WMITLV_GET_STRUCT_TLVLEN 199 (wmi_vdev_create_cmd_fixed_param)); 200 #ifdef CMN_VDEV_MGR_TGT_IF_ENABLE 201 cmd->vdev_id = param->vdev_id; 202 #else 203 cmd->vdev_id = param->if_id; 204 #endif 205 cmd->vdev_type = param->type; 206 cmd->vdev_subtype = param->subtype; 207 cmd->flags = param->mbssid_flags; 208 cmd->vdevid_trans = param->vdevid_trans; 209 cmd->num_cfg_txrx_streams = num_bands; 210 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 211 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 212 WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x", 213 #ifdef CMN_VDEV_MGR_TGT_IF_ENABLE 214 __func__, param->vdev_id, cmd->pdev_id, 215 #else 216 __func__, param->if_id, cmd->pdev_id, 217 #endif 218 macaddr[0], macaddr[1], macaddr[2], 219 macaddr[3], macaddr[4], macaddr[5]); 220 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 221 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 222 (num_bands * sizeof(wmi_vdev_txrx_streams))); 223 buf_ptr += WMI_TLV_HDR_SIZE; 224 225 WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__, 226 param->type, param->subtype, 227 param->nss_2g, param->nss_5g); 228 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 229 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 230 txrx_streams->supported_tx_streams = param->nss_2g; 231 txrx_streams->supported_rx_streams = param->nss_2g; 232 WMITLV_SET_HDR(&txrx_streams->tlv_header, 233 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 234 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 235 236 txrx_streams++; 237 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 238 txrx_streams->supported_tx_streams = param->nss_5g; 239 txrx_streams->supported_rx_streams = param->nss_5g; 240 WMITLV_SET_HDR(&txrx_streams->tlv_header, 241 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 242 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 243 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 244 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 245 if (QDF_IS_STATUS_ERROR(ret)) { 246 WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID"); 247 wmi_buf_free(buf); 248 } 249 250 return ret; 251 } 252 253 /** 254 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 255 * @wmi_handle: wmi handle 256 * @if_id: vdev id 257 * 258 * Return: QDF_STATUS_SUCCESS for success or error code 259 */ 260 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 261 uint8_t if_id) 262 { 263 wmi_vdev_delete_cmd_fixed_param *cmd; 264 wmi_buf_t buf; 265 QDF_STATUS ret; 266 267 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 268 if (!buf) 269 return QDF_STATUS_E_NOMEM; 270 271 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 272 WMITLV_SET_HDR(&cmd->tlv_header, 273 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 274 WMITLV_GET_STRUCT_TLVLEN 275 (wmi_vdev_delete_cmd_fixed_param)); 276 cmd->vdev_id = if_id; 277 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 278 ret = wmi_unified_cmd_send(wmi_handle, buf, 279 sizeof(wmi_vdev_delete_cmd_fixed_param), 280 WMI_VDEV_DELETE_CMDID); 281 if (QDF_IS_STATUS_ERROR(ret)) { 282 WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID"); 283 wmi_buf_free(buf); 284 } 285 WMI_LOGD("%s:vdev id = %d", __func__, if_id); 286 287 return ret; 288 } 289 290 /** 291 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 292 * @wmi_handle: wmi handle 293 * @vdev_id: vdev id 294 * @nss_chains_user_cfg: user configured nss chain params 295 * 296 * Return: QDF_STATUS_SUCCESS for success or error code 297 */ 298 static QDF_STATUS 299 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 300 uint8_t vdev_id, 301 struct vdev_nss_chains *user_cfg) 302 { 303 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 304 wmi_buf_t buf; 305 QDF_STATUS ret; 306 307 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 308 if (!buf) 309 return QDF_STATUS_E_NOMEM; 310 311 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 312 WMITLV_SET_HDR(&cmd->tlv_header, 313 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 314 WMITLV_GET_STRUCT_TLVLEN 315 (wmi_vdev_chainmask_config_cmd_fixed_param)); 316 cmd->vdev_id = vdev_id; 317 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 318 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 319 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 320 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 321 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 322 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 323 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 324 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 325 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 326 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 327 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 328 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 329 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 330 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 331 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 332 333 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 334 ret = wmi_unified_cmd_send(wmi_handle, buf, 335 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 336 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 337 if (QDF_IS_STATUS_ERROR(ret)) { 338 WMI_LOGE("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 339 wmi_buf_free(buf); 340 } 341 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 342 343 return ret; 344 } 345 346 /** 347 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 348 * @wmi: wmi handle 349 * @vdev_id: vdev id 350 * 351 * Return: QDF_STATUS_SUCCESS for success or erro code 352 */ 353 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 354 uint8_t vdev_id) 355 { 356 wmi_vdev_stop_cmd_fixed_param *cmd; 357 wmi_buf_t buf; 358 int32_t len = sizeof(*cmd); 359 360 buf = wmi_buf_alloc(wmi, len); 361 if (!buf) 362 return QDF_STATUS_E_NOMEM; 363 364 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 365 WMITLV_SET_HDR(&cmd->tlv_header, 366 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 367 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 368 cmd->vdev_id = vdev_id; 369 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 370 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 371 WMI_LOGP("%s: Failed to send vdev stop command", __func__); 372 wmi_buf_free(buf); 373 return QDF_STATUS_E_FAILURE; 374 } 375 WMI_LOGD("%s:vdev id = %d", __func__, vdev_id); 376 377 return 0; 378 } 379 380 /** 381 * send_vdev_down_cmd_tlv() - send vdev down command to fw 382 * @wmi: wmi handle 383 * @vdev_id: vdev id 384 * 385 * Return: QDF_STATUS_SUCCESS for success or error code 386 */ 387 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 388 { 389 wmi_vdev_down_cmd_fixed_param *cmd; 390 wmi_buf_t buf; 391 int32_t len = sizeof(*cmd); 392 393 buf = wmi_buf_alloc(wmi, len); 394 if (!buf) 395 return QDF_STATUS_E_NOMEM; 396 397 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 398 WMITLV_SET_HDR(&cmd->tlv_header, 399 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 400 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 401 cmd->vdev_id = vdev_id; 402 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 403 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 404 WMI_LOGP("%s: Failed to send vdev down", __func__); 405 wmi_buf_free(buf); 406 return QDF_STATUS_E_FAILURE; 407 } 408 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 409 410 return 0; 411 } 412 413 static inline void copy_channel_info( 414 wmi_vdev_start_request_cmd_fixed_param * cmd, 415 wmi_channel *chan, 416 struct vdev_start_params *req) 417 { 418 chan->mhz = req->channel.mhz; 419 420 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 421 422 chan->band_center_freq1 = req->channel.cfreq1; 423 chan->band_center_freq2 = req->channel.cfreq2; 424 425 if (req->channel.half_rate) 426 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 427 else if (req->channel.quarter_rate) 428 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 429 430 if (req->channel.dfs_set) { 431 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 432 cmd->disable_hw_ack = req->disable_hw_ack; 433 } 434 435 if (req->channel.dfs_set_cfreq2) 436 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 437 438 /* According to firmware both reg power and max tx power 439 * on set channel power is used and set it to max reg 440 * power from regulatory. 441 */ 442 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 443 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 444 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 445 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 446 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 447 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 448 449 } 450 451 /** 452 * send_vdev_start_cmd_tlv() - send vdev start request to fw 453 * @wmi_handle: wmi handle 454 * @req: vdev start params 455 * 456 * Return: QDF status 457 */ 458 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 459 struct vdev_start_params *req) 460 { 461 wmi_vdev_start_request_cmd_fixed_param *cmd; 462 wmi_buf_t buf; 463 wmi_channel *chan; 464 int32_t len, ret; 465 uint8_t *buf_ptr; 466 467 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 468 buf = wmi_buf_alloc(wmi_handle, len); 469 if (!buf) 470 return QDF_STATUS_E_NOMEM; 471 472 buf_ptr = (uint8_t *) wmi_buf_data(buf); 473 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 474 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 475 WMITLV_SET_HDR(&cmd->tlv_header, 476 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 477 WMITLV_GET_STRUCT_TLVLEN 478 (wmi_vdev_start_request_cmd_fixed_param)); 479 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 480 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 481 cmd->vdev_id = req->vdev_id; 482 483 /* Fill channel info */ 484 copy_channel_info(cmd, chan, req); 485 #ifdef CMN_VDEV_MGR_TGT_IF_ENABLE 486 cmd->beacon_interval = req->beacon_interval; 487 #else 488 cmd->beacon_interval = req->beacon_intval; 489 #endif 490 cmd->dtim_period = req->dtim_period; 491 492 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 493 if (req->bcn_tx_rate_code) 494 cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT; 495 496 if (!req->is_restart) { 497 #ifdef CMN_VDEV_MGR_TGT_IF_ENABLE 498 cmd->beacon_interval = req->beacon_interval; 499 #else 500 cmd->beacon_interval = req->beacon_intval; 501 #endif 502 cmd->dtim_period = req->dtim_period; 503 504 /* Copy the SSID */ 505 if (req->ssid.length) { 506 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 507 cmd->ssid.ssid_len = req->ssid.length; 508 else 509 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 510 qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid, 511 cmd->ssid.ssid_len); 512 } 513 514 if (req->hidden_ssid) 515 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 516 517 if (req->pmf_enabled) 518 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 519 } 520 521 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 522 cmd->num_noa_descriptors = req->num_noa_descriptors; 523 cmd->preferred_rx_streams = req->preferred_rx_streams; 524 cmd->preferred_tx_streams = req->preferred_tx_streams; 525 cmd->cac_duration_ms = req->cac_duration_ms; 526 cmd->regdomain = req->regdomain; 527 cmd->he_ops = req->he_ops; 528 529 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 530 sizeof(wmi_channel)); 531 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 532 cmd->num_noa_descriptors * 533 sizeof(wmi_p2p_noa_descriptor)); 534 WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 535 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 536 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 537 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 538 "req->dis_hw_ack: %d ", __func__, req->vdev_id, 539 chan->mhz, req->channel.phy_mode, chan->info, 540 #ifdef CMN_VDEV_MGR_TGT_IF_ENABLE 541 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 542 #else 543 req->channel.dfs_set, req->beacon_intval, cmd->dtim_period, 544 #endif 545 chan->band_center_freq1, chan->band_center_freq2, 546 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 547 req->preferred_tx_streams, req->preferred_rx_streams, 548 req->ldpc_rx_enabled, req->cac_duration_ms, 549 req->regdomain, req->he_ops, 550 req->disable_hw_ack); 551 552 if (req->is_restart) { 553 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 554 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 555 WMI_VDEV_RESTART_REQUEST_CMDID); 556 } else { 557 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 558 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 559 WMI_VDEV_START_REQUEST_CMDID); 560 } 561 if (ret) { 562 WMI_LOGP("%s: Failed to send vdev start command", __func__); 563 wmi_buf_free(buf); 564 return QDF_STATUS_E_FAILURE; 565 } 566 567 return QDF_STATUS_SUCCESS; 568 } 569 570 /** 571 * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid 572 * @wmi_handle: wmi handle 573 * @restart_params: vdev restart params 574 * 575 * Return: QDF_STATUS_SUCCESS for success or error code 576 */ 577 static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle, 578 struct hidden_ssid_vdev_restart_params *restart_params) 579 { 580 wmi_vdev_start_request_cmd_fixed_param *cmd; 581 wmi_buf_t buf; 582 wmi_channel *chan; 583 int32_t len; 584 uint8_t *buf_ptr; 585 QDF_STATUS ret = 0; 586 587 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 588 buf = wmi_buf_alloc(wmi_handle, len); 589 if (!buf) 590 return QDF_STATUS_E_NOMEM; 591 592 buf_ptr = (uint8_t *) wmi_buf_data(buf); 593 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 594 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 595 596 WMITLV_SET_HDR(&cmd->tlv_header, 597 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 598 WMITLV_GET_STRUCT_TLVLEN 599 (wmi_vdev_start_request_cmd_fixed_param)); 600 601 WMITLV_SET_HDR(&chan->tlv_header, 602 WMITLV_TAG_STRUC_wmi_channel, 603 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 604 605 cmd->vdev_id = restart_params->session_id; 606 cmd->ssid.ssid_len = restart_params->ssid_len; 607 qdf_mem_copy(cmd->ssid.ssid, 608 restart_params->ssid, 609 cmd->ssid.ssid_len); 610 cmd->flags = restart_params->flags; 611 cmd->requestor_id = restart_params->requestor_id; 612 cmd->disable_hw_ack = restart_params->disable_hw_ack; 613 614 chan->mhz = restart_params->mhz; 615 chan->band_center_freq1 = 616 restart_params->band_center_freq1; 617 chan->band_center_freq2 = 618 restart_params->band_center_freq2; 619 chan->info = restart_params->info; 620 chan->reg_info_1 = restart_params->reg_info_1; 621 chan->reg_info_2 = restart_params->reg_info_2; 622 623 cmd->num_noa_descriptors = 0; 624 buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) + 625 sizeof(wmi_channel)); 626 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 627 cmd->num_noa_descriptors * 628 sizeof(wmi_p2p_noa_descriptor)); 629 630 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 631 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 632 WMI_VDEV_RESTART_REQUEST_CMDID); 633 if (QDF_IS_STATUS_ERROR(ret)) { 634 wmi_buf_free(buf); 635 return QDF_STATUS_E_FAILURE; 636 } 637 return QDF_STATUS_SUCCESS; 638 } 639 640 641 /** 642 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 643 * @wmi: wmi handle 644 * @peer_addr: peer mac address 645 * @param: pointer to hold peer flush tid parameter 646 * 647 * Return: 0 for success or error code 648 */ 649 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 650 uint8_t peer_addr[IEEE80211_ADDR_LEN], 651 struct peer_flush_params *param) 652 { 653 wmi_peer_flush_tids_cmd_fixed_param *cmd; 654 wmi_buf_t buf; 655 int32_t len = sizeof(*cmd); 656 657 buf = wmi_buf_alloc(wmi, len); 658 if (!buf) 659 return QDF_STATUS_E_NOMEM; 660 661 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 662 WMITLV_SET_HDR(&cmd->tlv_header, 663 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 664 WMITLV_GET_STRUCT_TLVLEN 665 (wmi_peer_flush_tids_cmd_fixed_param)); 666 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 667 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 668 cmd->vdev_id = param->vdev_id; 669 WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__, 670 peer_addr, param->vdev_id, 671 param->peer_tid_bitmap); 672 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 673 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 674 WMI_LOGP("%s: Failed to send flush tid command", __func__); 675 wmi_buf_free(buf); 676 return QDF_STATUS_E_FAILURE; 677 } 678 679 return 0; 680 } 681 682 /** 683 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 684 * @wmi: wmi handle 685 * @peer_addr: peer mac addr 686 * @vdev_id: vdev id 687 * 688 * Return: QDF_STATUS_SUCCESS for success or error code 689 */ 690 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 691 uint8_t peer_addr[IEEE80211_ADDR_LEN], 692 uint8_t vdev_id) 693 { 694 wmi_peer_delete_cmd_fixed_param *cmd; 695 wmi_buf_t buf; 696 int32_t len = sizeof(*cmd); 697 buf = wmi_buf_alloc(wmi, len); 698 if (!buf) 699 return QDF_STATUS_E_NOMEM; 700 701 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 702 WMITLV_SET_HDR(&cmd->tlv_header, 703 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 704 WMITLV_GET_STRUCT_TLVLEN 705 (wmi_peer_delete_cmd_fixed_param)); 706 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 707 cmd->vdev_id = vdev_id; 708 709 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); 710 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 711 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 712 WMI_LOGP("%s: Failed to send peer delete command", __func__); 713 wmi_buf_free(buf); 714 return QDF_STATUS_E_FAILURE; 715 } 716 717 return 0; 718 } 719 720 /** 721 * convert_host_peer_id_to_target_id_tlv - convert host peer param_id 722 * to target id. 723 * @targ_paramid: Target parameter id to hold the result. 724 * @peer_param_id: host param id. 725 * 726 * Return: QDF_STATUS_SUCCESS for success 727 * QDF_STATUS_E_NOSUPPORT when the param_id in not supported in tareget 728 */ 729 #ifdef CONFIG_MCL 730 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 731 uint32_t *targ_paramid, 732 uint32_t peer_param_id) 733 { 734 *targ_paramid = peer_param_id; 735 return QDF_STATUS_SUCCESS; 736 } 737 738 /** 739 * crash_on_send_peer_rx_reorder_queue_remove_cmd() - crash on reorder queue cmd 740 * 741 * On MCL side, we are suspecting this cmd to trigger drop of ARP 742 * response frames from REO by the FW. This function causes a crash if this 743 * command is sent out by the host, so we can track this issue. Ideally no one 744 * should be calling this API from the MCL side 745 * 746 * Return: None 747 */ 748 static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void) 749 { 750 QDF_BUG(0); 751 } 752 #else 753 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 754 uint32_t *targ_paramid, 755 uint32_t peer_param_id) 756 { 757 switch (peer_param_id) { 758 case WMI_HOST_PEER_MIMO_PS_STATE: 759 *targ_paramid = WMI_PEER_MIMO_PS_STATE; 760 break; 761 case WMI_HOST_PEER_AMPDU: 762 *targ_paramid = WMI_PEER_AMPDU; 763 break; 764 case WMI_HOST_PEER_AUTHORIZE: 765 *targ_paramid = WMI_PEER_AUTHORIZE; 766 break; 767 case WMI_HOST_PEER_CHWIDTH: 768 *targ_paramid = WMI_PEER_CHWIDTH; 769 break; 770 case WMI_HOST_PEER_NSS: 771 *targ_paramid = WMI_PEER_NSS; 772 break; 773 case WMI_HOST_PEER_USE_4ADDR: 774 *targ_paramid = WMI_PEER_USE_4ADDR; 775 break; 776 case WMI_HOST_PEER_MEMBERSHIP: 777 *targ_paramid = WMI_PEER_MEMBERSHIP; 778 break; 779 case WMI_HOST_PEER_USERPOS: 780 *targ_paramid = WMI_PEER_USERPOS; 781 break; 782 case WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED: 783 *targ_paramid = WMI_PEER_CRIT_PROTO_HINT_ENABLED; 784 break; 785 case WMI_HOST_PEER_TX_FAIL_CNT_THR: 786 *targ_paramid = WMI_PEER_TX_FAIL_CNT_THR; 787 break; 788 case WMI_HOST_PEER_SET_HW_RETRY_CTS2S: 789 *targ_paramid = WMI_PEER_SET_HW_RETRY_CTS2S; 790 break; 791 case WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH: 792 *targ_paramid = WMI_PEER_IBSS_ATIM_WINDOW_LENGTH; 793 break; 794 case WMI_HOST_PEER_PHYMODE: 795 *targ_paramid = WMI_PEER_PHYMODE; 796 break; 797 case WMI_HOST_PEER_USE_FIXED_PWR: 798 *targ_paramid = WMI_PEER_USE_FIXED_PWR; 799 break; 800 case WMI_HOST_PEER_PARAM_FIXED_RATE: 801 *targ_paramid = WMI_PEER_PARAM_FIXED_RATE; 802 break; 803 case WMI_HOST_PEER_SET_MU_WHITELIST: 804 *targ_paramid = WMI_PEER_SET_MU_WHITELIST; 805 break; 806 case WMI_HOST_PEER_SET_MAC_TX_RATE: 807 *targ_paramid = WMI_PEER_SET_MAX_TX_RATE; 808 break; 809 case WMI_HOST_PEER_SET_MIN_TX_RATE: 810 *targ_paramid = WMI_PEER_SET_MIN_TX_RATE; 811 break; 812 case WMI_HOST_PEER_SET_DEFAULT_ROUTING: 813 *targ_paramid = WMI_PEER_SET_DEFAULT_ROUTING; 814 break; 815 case WMI_HOST_PEER_NSS_VHT160: 816 *targ_paramid = WMI_PEER_NSS_VHT160; 817 break; 818 case WMI_HOST_PEER_NSS_VHT80_80: 819 *targ_paramid = WMI_PEER_NSS_VHT80_80; 820 break; 821 case WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL: 822 *targ_paramid = WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL; 823 break; 824 case WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL: 825 *targ_paramid = WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL; 826 break; 827 case WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE: 828 *targ_paramid = WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE; 829 break; 830 case WMI_HOST_PEER_PARAM_MU_ENABLE: 831 *targ_paramid = WMI_PEER_PARAM_MU_ENABLE; 832 break; 833 case WMI_HOST_PEER_PARAM_OFDMA_ENABLE: 834 *targ_paramid = WMI_PEER_PARAM_OFDMA_ENABLE; 835 break; 836 case WMI_HOST_PEER_PARAM_ENABLE_FT: 837 *targ_paramid = WMI_PEER_PARAM_ENABLE_FT; 838 break; 839 default: 840 return QDF_STATUS_E_NOSUPPORT; 841 } 842 843 return QDF_STATUS_SUCCESS; 844 } 845 846 static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void) 847 { 848 /* No-OP */ 849 } 850 851 #endif 852 /** 853 * send_peer_param_cmd_tlv() - set peer parameter in fw 854 * @wmi: wmi handle 855 * @peer_addr: peer mac address 856 * @param : pointer to hold peer set parameter 857 * 858 * Return: QDF_STATUS_SUCCESS for success or error code 859 */ 860 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 861 uint8_t peer_addr[IEEE80211_ADDR_LEN], 862 struct peer_set_params *param) 863 { 864 wmi_peer_set_param_cmd_fixed_param *cmd; 865 wmi_buf_t buf; 866 int32_t err; 867 uint32_t param_id; 868 869 if (convert_host_peer_id_to_target_id_tlv(¶m_id, 870 param->param_id) != QDF_STATUS_SUCCESS) 871 return QDF_STATUS_E_NOSUPPORT; 872 873 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 874 if (!buf) 875 return QDF_STATUS_E_NOMEM; 876 877 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 878 WMITLV_SET_HDR(&cmd->tlv_header, 879 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 880 WMITLV_GET_STRUCT_TLVLEN 881 (wmi_peer_set_param_cmd_fixed_param)); 882 cmd->vdev_id = param->vdev_id; 883 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 884 cmd->param_id = param_id; 885 cmd->param_value = param->param_value; 886 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 887 err = wmi_unified_cmd_send(wmi, buf, 888 sizeof(wmi_peer_set_param_cmd_fixed_param), 889 WMI_PEER_SET_PARAM_CMDID); 890 if (err) { 891 WMI_LOGE("Failed to send set_param cmd"); 892 wmi_buf_free(buf); 893 return QDF_STATUS_E_FAILURE; 894 } 895 896 return 0; 897 } 898 899 /** 900 * send_vdev_up_cmd_tlv() - send vdev up command in fw 901 * @wmi: wmi handle 902 * @bssid: bssid 903 * @vdev_up_params: pointer to hold vdev up parameter 904 * 905 * Return: QDF_STATUS_SUCCESS for success or error code 906 */ 907 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 908 uint8_t bssid[IEEE80211_ADDR_LEN], 909 struct vdev_up_params *params) 910 { 911 wmi_vdev_up_cmd_fixed_param *cmd; 912 wmi_buf_t buf; 913 int32_t len = sizeof(*cmd); 914 915 WMI_LOGD("%s: VDEV_UP", __func__); 916 WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__, 917 params->vdev_id, params->assoc_id, bssid); 918 buf = wmi_buf_alloc(wmi, len); 919 if (!buf) 920 return QDF_STATUS_E_NOMEM; 921 922 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 923 WMITLV_SET_HDR(&cmd->tlv_header, 924 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 925 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 926 cmd->vdev_id = params->vdev_id; 927 cmd->vdev_assoc_id = params->assoc_id; 928 cmd->profile_idx = params->profile_idx; 929 cmd->profile_num = params->profile_num; 930 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 931 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 932 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 933 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 934 WMI_LOGP("%s: Failed to send vdev up command", __func__); 935 wmi_buf_free(buf); 936 return QDF_STATUS_E_FAILURE; 937 } 938 939 return 0; 940 } 941 942 /** 943 * send_peer_create_cmd_tlv() - send peer create command to fw 944 * @wmi: wmi handle 945 * @peer_addr: peer mac address 946 * @peer_type: peer type 947 * @vdev_id: vdev id 948 * 949 * Return: QDF_STATUS_SUCCESS for success or error code 950 */ 951 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 952 struct peer_create_params *param) 953 { 954 wmi_peer_create_cmd_fixed_param *cmd; 955 wmi_buf_t buf; 956 int32_t len = sizeof(*cmd); 957 958 buf = wmi_buf_alloc(wmi, len); 959 if (!buf) 960 return QDF_STATUS_E_NOMEM; 961 962 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 963 WMITLV_SET_HDR(&cmd->tlv_header, 964 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 965 WMITLV_GET_STRUCT_TLVLEN 966 (wmi_peer_create_cmd_fixed_param)); 967 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 968 cmd->peer_type = param->peer_type; 969 cmd->vdev_id = param->vdev_id; 970 971 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 972 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 973 WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__); 974 wmi_buf_free(buf); 975 return QDF_STATUS_E_FAILURE; 976 } 977 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr, 978 param->vdev_id); 979 980 return 0; 981 } 982 983 /** 984 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 985 * command to fw 986 * @wmi: wmi handle 987 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 988 * 989 * Return: 0 for success or error code 990 */ 991 static 992 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 993 struct rx_reorder_queue_setup_params *param) 994 { 995 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 996 wmi_buf_t buf; 997 int32_t len = sizeof(*cmd); 998 999 buf = wmi_buf_alloc(wmi, len); 1000 if (!buf) 1001 return QDF_STATUS_E_NOMEM; 1002 1003 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1004 WMITLV_SET_HDR(&cmd->tlv_header, 1005 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1006 WMITLV_GET_STRUCT_TLVLEN 1007 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1008 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1009 cmd->vdev_id = param->vdev_id; 1010 cmd->tid = param->tid; 1011 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1012 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1013 cmd->queue_no = param->queue_no; 1014 cmd->ba_window_size_valid = param->ba_window_size_valid; 1015 cmd->ba_window_size = param->ba_window_size; 1016 1017 1018 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1019 if (wmi_unified_cmd_send(wmi, buf, len, 1020 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1021 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID", 1022 __func__); 1023 wmi_buf_free(buf); 1024 return QDF_STATUS_E_FAILURE; 1025 } 1026 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d", __func__, 1027 param->peer_macaddr, param->vdev_id, param->tid); 1028 1029 return QDF_STATUS_SUCCESS; 1030 } 1031 1032 /** 1033 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1034 * command to fw 1035 * @wmi: wmi handle 1036 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 1037 * 1038 * Return: 0 for success or error code 1039 */ 1040 static 1041 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1042 struct rx_reorder_queue_remove_params *param) 1043 { 1044 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1045 wmi_buf_t buf; 1046 int32_t len = sizeof(*cmd); 1047 1048 crash_on_send_peer_rx_reorder_queue_remove_cmd(); 1049 1050 buf = wmi_buf_alloc(wmi, len); 1051 if (!buf) 1052 return QDF_STATUS_E_NOMEM; 1053 1054 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1055 wmi_buf_data(buf); 1056 WMITLV_SET_HDR(&cmd->tlv_header, 1057 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 1058 WMITLV_GET_STRUCT_TLVLEN 1059 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 1060 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1061 cmd->vdev_id = param->vdev_id; 1062 cmd->tid_mask = param->peer_tid_bitmap; 1063 1064 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 1065 if (wmi_unified_cmd_send(wmi, buf, len, 1066 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 1067 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID", 1068 __func__); 1069 wmi_buf_free(buf); 1070 return QDF_STATUS_E_FAILURE; 1071 } 1072 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__, 1073 param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap); 1074 1075 return QDF_STATUS_SUCCESS; 1076 } 1077 1078 #ifdef WLAN_SUPPORT_GREEN_AP 1079 /** 1080 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1081 * @wmi_handle: wmi handle 1082 * @value: value 1083 * @pdev_id: pdev id to have radio context 1084 * 1085 * Return: QDF_STATUS_SUCCESS for success or error code 1086 */ 1087 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1088 uint32_t value, uint8_t pdev_id) 1089 { 1090 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1091 wmi_buf_t buf; 1092 int32_t len = sizeof(*cmd); 1093 1094 WMI_LOGD("Set Green AP PS val %d", value); 1095 1096 buf = wmi_buf_alloc(wmi_handle, len); 1097 if (!buf) 1098 return QDF_STATUS_E_NOMEM; 1099 1100 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1101 WMITLV_SET_HDR(&cmd->tlv_header, 1102 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1103 WMITLV_GET_STRUCT_TLVLEN 1104 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1105 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 1106 cmd->enable = value; 1107 1108 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 1109 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1110 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1111 WMI_LOGE("Set Green AP PS param Failed val %d", value); 1112 wmi_buf_free(buf); 1113 return QDF_STATUS_E_FAILURE; 1114 } 1115 1116 return 0; 1117 } 1118 #endif 1119 1120 /** 1121 * send_pdev_utf_cmd_tlv() - send utf command to fw 1122 * @wmi_handle: wmi handle 1123 * @param: pointer to pdev_utf_params 1124 * @mac_id: mac id to have radio context 1125 * 1126 * Return: QDF_STATUS_SUCCESS for success or error code 1127 */ 1128 static QDF_STATUS 1129 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1130 struct pdev_utf_params *param, 1131 uint8_t mac_id) 1132 { 1133 wmi_buf_t buf; 1134 uint8_t *cmd; 1135 /* if param->len is 0 no data is sent, return error */ 1136 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1137 static uint8_t msgref = 1; 1138 uint8_t segNumber = 0, segInfo, numSegments; 1139 uint16_t chunk_len, total_bytes; 1140 uint8_t *bufpos; 1141 struct seg_hdr_info segHdrInfo; 1142 1143 bufpos = param->utf_payload; 1144 total_bytes = param->len; 1145 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1146 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1147 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1148 1149 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1150 numSegments++; 1151 1152 while (param->len) { 1153 if (param->len > MAX_WMI_UTF_LEN) 1154 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1155 else 1156 chunk_len = param->len; 1157 1158 buf = wmi_buf_alloc(wmi_handle, 1159 (chunk_len + sizeof(segHdrInfo) + 1160 WMI_TLV_HDR_SIZE)); 1161 if (!buf) 1162 return QDF_STATUS_E_NOMEM; 1163 1164 cmd = (uint8_t *) wmi_buf_data(buf); 1165 1166 segHdrInfo.len = total_bytes; 1167 segHdrInfo.msgref = msgref; 1168 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1169 segHdrInfo.segmentInfo = segInfo; 1170 segHdrInfo.pad = 0; 1171 1172 WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1173 " segHdrInfo.segmentInfo = %d", 1174 __func__, segHdrInfo.len, segHdrInfo.msgref, 1175 segHdrInfo.segmentInfo); 1176 1177 WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d" 1178 "chunk len %d", __func__, total_bytes, segNumber, 1179 numSegments, chunk_len); 1180 1181 segNumber++; 1182 1183 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1184 (chunk_len + sizeof(segHdrInfo))); 1185 cmd += WMI_TLV_HDR_SIZE; 1186 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1187 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); 1188 1189 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 1190 ret = wmi_unified_cmd_send(wmi_handle, buf, 1191 (chunk_len + sizeof(segHdrInfo) + 1192 WMI_TLV_HDR_SIZE), 1193 WMI_PDEV_UTF_CMDID); 1194 1195 if (QDF_IS_STATUS_ERROR(ret)) { 1196 WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command"); 1197 wmi_buf_free(buf); 1198 break; 1199 } 1200 1201 param->len -= chunk_len; 1202 bufpos += chunk_len; 1203 } 1204 1205 msgref++; 1206 1207 return ret; 1208 } 1209 #ifdef CONFIG_MCL 1210 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1211 uint32_t host_param) 1212 { 1213 return host_param; 1214 } 1215 #else 1216 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1217 uint32_t host_param) 1218 { 1219 if (host_param < wmi_pdev_param_max) 1220 return wmi_handle->pdev_param[host_param]; 1221 1222 return WMI_UNAVAILABLE_PARAM; 1223 } 1224 #endif 1225 /** 1226 * send_pdev_param_cmd_tlv() - set pdev parameters 1227 * @wmi_handle: wmi handle 1228 * @param: pointer to pdev parameter 1229 * @mac_id: radio context 1230 * 1231 * Return: 0 on success, errno on failure 1232 */ 1233 static QDF_STATUS 1234 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1235 struct pdev_params *param, 1236 uint8_t mac_id) 1237 { 1238 QDF_STATUS ret; 1239 wmi_pdev_set_param_cmd_fixed_param *cmd; 1240 wmi_buf_t buf; 1241 uint16_t len = sizeof(*cmd); 1242 uint32_t pdev_param; 1243 1244 pdev_param = convert_host_pdev_param_tlv(wmi_handle, param->param_id); 1245 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1246 WMI_LOGW("%s: Unavailable param %d", 1247 __func__, param->param_id); 1248 return QDF_STATUS_E_INVAL; 1249 } 1250 1251 buf = wmi_buf_alloc(wmi_handle, len); 1252 if (!buf) 1253 return QDF_STATUS_E_NOMEM; 1254 1255 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1256 WMITLV_SET_HDR(&cmd->tlv_header, 1257 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1258 WMITLV_GET_STRUCT_TLVLEN 1259 (wmi_pdev_set_param_cmd_fixed_param)); 1260 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1261 cmd->param_id = pdev_param; 1262 cmd->param_value = param->param_value; 1263 WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id, 1264 param->param_value); 1265 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 1266 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1267 WMI_PDEV_SET_PARAM_CMDID); 1268 if (QDF_IS_STATUS_ERROR(ret)) { 1269 WMI_LOGE("Failed to send set param command ret = %d", ret); 1270 wmi_buf_free(buf); 1271 } 1272 return ret; 1273 } 1274 1275 /** 1276 * send_suspend_cmd_tlv() - WMI suspend function 1277 * @param wmi_handle : handle to WMI. 1278 * @param param : pointer to hold suspend parameter 1279 * @mac_id: radio context 1280 * 1281 * Return 0 on success and -ve on failure. 1282 */ 1283 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1284 struct suspend_params *param, 1285 uint8_t mac_id) 1286 { 1287 wmi_pdev_suspend_cmd_fixed_param *cmd; 1288 wmi_buf_t wmibuf; 1289 uint32_t len = sizeof(*cmd); 1290 int32_t ret; 1291 1292 /* 1293 * send the command to Target to ignore the 1294 * PCIE reset so as to ensure that Host and target 1295 * states are in sync 1296 */ 1297 wmibuf = wmi_buf_alloc(wmi_handle, len); 1298 if (wmibuf == NULL) 1299 return QDF_STATUS_E_NOMEM; 1300 1301 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1302 WMITLV_SET_HDR(&cmd->tlv_header, 1303 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1304 WMITLV_GET_STRUCT_TLVLEN 1305 (wmi_pdev_suspend_cmd_fixed_param)); 1306 if (param->disable_target_intr) 1307 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1308 else 1309 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1310 1311 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1312 1313 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 1314 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1315 WMI_PDEV_SUSPEND_CMDID); 1316 if (ret) { 1317 wmi_buf_free(wmibuf); 1318 WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1319 } 1320 1321 return ret; 1322 } 1323 1324 /** 1325 * send_resume_cmd_tlv() - WMI resume function 1326 * @param wmi_handle : handle to WMI. 1327 * @mac_id: radio context 1328 * 1329 * Return: 0 on success and -ve on failure. 1330 */ 1331 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1332 uint8_t mac_id) 1333 { 1334 wmi_buf_t wmibuf; 1335 wmi_pdev_resume_cmd_fixed_param *cmd; 1336 QDF_STATUS ret; 1337 1338 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1339 if (wmibuf == NULL) 1340 return QDF_STATUS_E_NOMEM; 1341 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1342 WMITLV_SET_HDR(&cmd->tlv_header, 1343 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1344 WMITLV_GET_STRUCT_TLVLEN 1345 (wmi_pdev_resume_cmd_fixed_param)); 1346 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1347 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 1348 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1349 WMI_PDEV_RESUME_CMDID); 1350 if (QDF_IS_STATUS_ERROR(ret)) { 1351 WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); 1352 wmi_buf_free(wmibuf); 1353 } 1354 1355 return ret; 1356 } 1357 1358 /** 1359 * send_wow_enable_cmd_tlv() - WMI wow enable function 1360 * @param wmi_handle : handle to WMI. 1361 * @param param : pointer to hold wow enable parameter 1362 * @mac_id: radio context 1363 * 1364 * Return: 0 on success and -ve on failure. 1365 */ 1366 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1367 struct wow_cmd_params *param, 1368 uint8_t mac_id) 1369 { 1370 wmi_wow_enable_cmd_fixed_param *cmd; 1371 wmi_buf_t buf; 1372 int32_t len; 1373 int32_t ret; 1374 1375 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1376 1377 buf = wmi_buf_alloc(wmi_handle, len); 1378 if (!buf) 1379 return QDF_STATUS_E_NOMEM; 1380 1381 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1382 WMITLV_SET_HDR(&cmd->tlv_header, 1383 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1384 WMITLV_GET_STRUCT_TLVLEN 1385 (wmi_wow_enable_cmd_fixed_param)); 1386 cmd->enable = param->enable; 1387 if (param->can_suspend_link) 1388 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1389 else 1390 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1391 cmd->flags = param->flags; 1392 1393 WMI_LOGI("suspend type: %s", 1394 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1395 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED"); 1396 1397 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 1398 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1399 WMI_WOW_ENABLE_CMDID); 1400 if (ret) 1401 wmi_buf_free(buf); 1402 1403 return ret; 1404 } 1405 1406 /** 1407 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1408 * @wmi_handle: wmi handle 1409 * @peer_addr: peer mac address 1410 * @param: pointer to ap_ps parameter structure 1411 * 1412 * Return: QDF_STATUS_SUCCESS for success or error code 1413 */ 1414 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1415 uint8_t *peer_addr, 1416 struct ap_ps_params *param) 1417 { 1418 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1419 wmi_buf_t buf; 1420 int32_t err; 1421 1422 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1423 if (!buf) 1424 return QDF_STATUS_E_NOMEM; 1425 1426 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1427 WMITLV_SET_HDR(&cmd->tlv_header, 1428 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1429 WMITLV_GET_STRUCT_TLVLEN 1430 (wmi_ap_ps_peer_cmd_fixed_param)); 1431 cmd->vdev_id = param->vdev_id; 1432 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1433 cmd->param = param->param; 1434 cmd->value = param->value; 1435 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 1436 err = wmi_unified_cmd_send(wmi_handle, buf, 1437 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1438 if (err) { 1439 WMI_LOGE("Failed to send set_ap_ps_param cmd"); 1440 wmi_buf_free(buf); 1441 return QDF_STATUS_E_FAILURE; 1442 } 1443 1444 return 0; 1445 } 1446 1447 /** 1448 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1449 * @wmi_handle: wmi handle 1450 * @peer_addr: peer mac address 1451 * @param: pointer to sta_ps parameter structure 1452 * 1453 * Return: QDF_STATUS_SUCCESS for success or error code 1454 */ 1455 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1456 struct sta_ps_params *param) 1457 { 1458 wmi_sta_powersave_param_cmd_fixed_param *cmd; 1459 wmi_buf_t buf; 1460 int32_t len = sizeof(*cmd); 1461 1462 buf = wmi_buf_alloc(wmi_handle, len); 1463 if (!buf) 1464 return QDF_STATUS_E_NOMEM; 1465 1466 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 1467 WMITLV_SET_HDR(&cmd->tlv_header, 1468 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 1469 WMITLV_GET_STRUCT_TLVLEN 1470 (wmi_sta_powersave_param_cmd_fixed_param)); 1471 cmd->vdev_id = param->vdev_id; 1472 cmd->param = param->param; 1473 cmd->value = param->value; 1474 1475 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 1476 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1477 WMI_STA_POWERSAVE_PARAM_CMDID)) { 1478 WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d", 1479 param->vdev_id, param->param, param->value); 1480 wmi_buf_free(buf); 1481 return QDF_STATUS_E_FAILURE; 1482 } 1483 1484 return 0; 1485 } 1486 1487 /** 1488 * send_crash_inject_cmd_tlv() - inject fw crash 1489 * @wmi_handle: wmi handle 1490 * @param: ponirt to crash inject parameter structure 1491 * 1492 * Return: QDF_STATUS_SUCCESS for success or return error 1493 */ 1494 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 1495 struct crash_inject *param) 1496 { 1497 int32_t ret = 0; 1498 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 1499 uint16_t len = sizeof(*cmd); 1500 wmi_buf_t buf; 1501 1502 buf = wmi_buf_alloc(wmi_handle, len); 1503 if (!buf) 1504 return QDF_STATUS_E_NOMEM; 1505 1506 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 1507 WMITLV_SET_HDR(&cmd->tlv_header, 1508 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 1509 WMITLV_GET_STRUCT_TLVLEN 1510 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 1511 cmd->type = param->type; 1512 cmd->delay_time_ms = param->delay_time_ms; 1513 1514 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 1515 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1516 WMI_FORCE_FW_HANG_CMDID); 1517 if (ret) { 1518 WMI_LOGE("%s: Failed to send set param command, ret = %d", 1519 __func__, ret); 1520 wmi_buf_free(buf); 1521 } 1522 1523 return ret; 1524 } 1525 1526 #ifdef FEATURE_FW_LOG_PARSING 1527 /** 1528 * send_dbglog_cmd_tlv() - set debug log level 1529 * @param wmi_handle : handle to WMI. 1530 * @param param : pointer to hold dbglog level parameter 1531 * 1532 * Return: 0 on success and -ve on failure. 1533 */ 1534 static QDF_STATUS 1535 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 1536 struct dbglog_params *dbglog_param) 1537 { 1538 wmi_buf_t buf; 1539 wmi_debug_log_config_cmd_fixed_param *configmsg; 1540 QDF_STATUS status; 1541 int32_t i; 1542 int32_t len; 1543 int8_t *buf_ptr; 1544 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 1545 1546 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 1547 1548 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 1549 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 1550 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1551 buf = wmi_buf_alloc(wmi_handle, len); 1552 if (!buf) 1553 return QDF_STATUS_E_NOMEM; 1554 1555 configmsg = 1556 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 1557 buf_ptr = (int8_t *) configmsg; 1558 WMITLV_SET_HDR(&configmsg->tlv_header, 1559 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 1560 WMITLV_GET_STRUCT_TLVLEN 1561 (wmi_debug_log_config_cmd_fixed_param)); 1562 configmsg->dbg_log_param = dbglog_param->param; 1563 configmsg->value = dbglog_param->val; 1564 /* Filling in the data part of second tlv -- should 1565 * follow first tlv _ WMI_TLV_HDR_SIZE */ 1566 module_id_bitmap_array = (uint32_t *) (buf_ptr + 1567 sizeof 1568 (wmi_debug_log_config_cmd_fixed_param) 1569 + WMI_TLV_HDR_SIZE); 1570 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 1571 WMITLV_TAG_ARRAY_UINT32, 1572 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1573 if (dbglog_param->module_id_bitmap) { 1574 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 1575 module_id_bitmap_array[i] = 1576 dbglog_param->module_id_bitmap[i]; 1577 } 1578 } 1579 1580 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 1581 status = wmi_unified_cmd_send(wmi_handle, buf, 1582 len, WMI_DBGLOG_CFG_CMDID); 1583 1584 if (status != QDF_STATUS_SUCCESS) 1585 wmi_buf_free(buf); 1586 1587 return status; 1588 } 1589 #endif 1590 1591 #ifdef CONFIG_MCL 1592 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1593 uint32_t host_param) 1594 { 1595 return host_param; 1596 } 1597 #else 1598 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1599 uint32_t host_param) 1600 { 1601 if (host_param < wmi_vdev_param_max) 1602 return wmi_handle->vdev_param[host_param]; 1603 1604 return WMI_UNAVAILABLE_PARAM; 1605 } 1606 #endif 1607 /** 1608 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 1609 * @param wmi_handle : handle to WMI. 1610 * @param macaddr : MAC address 1611 * @param param : pointer to hold vdev set parameter 1612 * 1613 * Return: 0 on success and -ve on failure. 1614 */ 1615 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 1616 struct vdev_set_params *param) 1617 { 1618 QDF_STATUS ret; 1619 wmi_vdev_set_param_cmd_fixed_param *cmd; 1620 wmi_buf_t buf; 1621 uint16_t len = sizeof(*cmd); 1622 uint32_t vdev_param; 1623 1624 vdev_param = convert_host_vdev_param_tlv(wmi_handle, param->param_id); 1625 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 1626 WMI_LOGW("%s:Vdev param %d not available", __func__, 1627 param->param_id); 1628 return QDF_STATUS_E_INVAL; 1629 1630 } 1631 1632 buf = wmi_buf_alloc(wmi_handle, len); 1633 if (!buf) 1634 return QDF_STATUS_E_NOMEM; 1635 1636 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1637 WMITLV_SET_HDR(&cmd->tlv_header, 1638 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 1639 WMITLV_GET_STRUCT_TLVLEN 1640 (wmi_vdev_set_param_cmd_fixed_param)); 1641 #ifdef CMN_VDEV_MGR_TGT_IF_ENABLE 1642 cmd->vdev_id = param->vdev_id; 1643 #else 1644 cmd->vdev_id = param->if_id; 1645 #endif 1646 cmd->param_id = vdev_param; 1647 cmd->param_value = param->param_value; 1648 WMI_LOGD("Setting vdev %d param = %x, value = %u", 1649 cmd->vdev_id, cmd->param_id, cmd->param_value); 1650 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 1651 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1652 WMI_VDEV_SET_PARAM_CMDID); 1653 if (QDF_IS_STATUS_ERROR(ret)) { 1654 WMI_LOGE("Failed to send set param command ret = %d", ret); 1655 wmi_buf_free(buf); 1656 } 1657 1658 return ret; 1659 } 1660 1661 /** 1662 * send_stats_request_cmd_tlv() - WMI request stats function 1663 * @param wmi_handle : handle to WMI. 1664 * @param macaddr : MAC address 1665 * @param param : pointer to hold stats request parameter 1666 * 1667 * Return: 0 on success and -ve on failure. 1668 */ 1669 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 1670 uint8_t macaddr[IEEE80211_ADDR_LEN], 1671 struct stats_request_params *param) 1672 { 1673 int32_t ret; 1674 wmi_request_stats_cmd_fixed_param *cmd; 1675 wmi_buf_t buf; 1676 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param); 1677 1678 buf = wmi_buf_alloc(wmi_handle, len); 1679 if (!buf) 1680 return -QDF_STATUS_E_NOMEM; 1681 1682 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 1683 WMITLV_SET_HDR(&cmd->tlv_header, 1684 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 1685 WMITLV_GET_STRUCT_TLVLEN 1686 (wmi_request_stats_cmd_fixed_param)); 1687 cmd->stats_id = param->stats_id; 1688 cmd->vdev_id = param->vdev_id; 1689 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1690 param->pdev_id); 1691 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 1692 1693 WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->", 1694 cmd->stats_id, cmd->vdev_id, cmd->pdev_id); 1695 1696 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 1697 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1698 WMI_REQUEST_STATS_CMDID); 1699 1700 if (ret) { 1701 WMI_LOGE("Failed to send status request to fw =%d", ret); 1702 wmi_buf_free(buf); 1703 } 1704 1705 return ret; 1706 } 1707 1708 #ifdef CONFIG_WIN 1709 1710 /** 1711 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 1712 * @wmi_handle: handle to WMI. 1713 * @macaddr: Peer mac address to be filter 1714 * @mac_id: mac id to have radio context 1715 * @enb_dsb: Enable MAC based filtering or Disable 1716 * 1717 * Return: QDF_STATUS 1718 */ 1719 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 1720 uint8_t *macaddr, 1721 uint8_t mac_id, 1722 uint8_t enb_dsb) 1723 { 1724 int32_t ret; 1725 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 1726 wmi_pdev_pktlog_filter_info *mac_info; 1727 wmi_buf_t buf; 1728 uint8_t *buf_ptr; 1729 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 1730 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 1731 1732 buf = wmi_buf_alloc(wmi_handle, len); 1733 if (!buf) 1734 return QDF_STATUS_E_NOMEM; 1735 1736 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1737 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 1738 WMITLV_SET_HDR(&cmd->tlv_header, 1739 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 1740 WMITLV_GET_STRUCT_TLVLEN 1741 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 1742 cmd->pdev_id = mac_id; 1743 cmd->enable = enb_dsb; 1744 cmd->num_of_mac_addresses = 1; 1745 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 1746 1747 buf_ptr += sizeof(*cmd); 1748 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1749 sizeof(wmi_pdev_pktlog_filter_info)); 1750 buf_ptr += WMI_TLV_HDR_SIZE; 1751 1752 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 1753 1754 WMITLV_SET_HDR(&mac_info->tlv_header, 1755 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 1756 WMITLV_GET_STRUCT_TLVLEN 1757 (wmi_pdev_pktlog_filter_info)); 1758 1759 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 1760 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1761 WMI_PDEV_PKTLOG_FILTER_CMDID); 1762 if (ret) { 1763 WMI_LOGE("Failed to send peer based pktlog command to FW =%d" 1764 , ret); 1765 wmi_buf_free(buf); 1766 } 1767 1768 return ret; 1769 } 1770 1771 /** 1772 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 1773 * @param wmi_handle : handle to WMI. 1774 * @param PKTLOG_EVENT : packet log event 1775 * @mac_id: mac id to have radio context 1776 * 1777 * Return: 0 on success and -ve on failure. 1778 */ 1779 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1780 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 1781 { 1782 int32_t ret; 1783 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 1784 wmi_buf_t buf; 1785 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 1786 1787 buf = wmi_buf_alloc(wmi_handle, len); 1788 if (!buf) 1789 return -QDF_STATUS_E_NOMEM; 1790 1791 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 1792 WMITLV_SET_HDR(&cmd->tlv_header, 1793 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 1794 WMITLV_GET_STRUCT_TLVLEN 1795 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 1796 cmd->evlist = PKTLOG_EVENT; 1797 cmd->pdev_id = mac_id; 1798 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 1799 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1800 WMI_PDEV_PKTLOG_ENABLE_CMDID); 1801 if (ret) { 1802 WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret); 1803 wmi_buf_free(buf); 1804 } 1805 1806 return ret; 1807 } 1808 1809 /** 1810 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 1811 * @param wmi_handle : handle to WMI. 1812 * @mac_id: mac id to have radio context 1813 * 1814 * Return: 0 on success and -ve on failure. 1815 */ 1816 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1817 uint8_t mac_id) 1818 { 1819 int32_t ret; 1820 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 1821 wmi_buf_t buf; 1822 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 1823 1824 buf = wmi_buf_alloc(wmi_handle, len); 1825 if (!buf) 1826 return -QDF_STATUS_E_NOMEM; 1827 1828 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 1829 WMITLV_SET_HDR(&cmd->tlv_header, 1830 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 1831 WMITLV_GET_STRUCT_TLVLEN 1832 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 1833 cmd->pdev_id = mac_id; 1834 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 1835 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1836 WMI_PDEV_PKTLOG_DISABLE_CMDID); 1837 if (ret) { 1838 WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret); 1839 wmi_buf_free(buf); 1840 } 1841 1842 return ret; 1843 } 1844 #else 1845 /** 1846 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable 1847 * packet-log 1848 * @param wmi_handle : handle to WMI. 1849 * @param macaddr : MAC address 1850 * @param param : pointer to hold stats request parameter 1851 * 1852 * Return: QDF_STATUS. 1853 */ 1854 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1855 uint8_t macaddr[IEEE80211_ADDR_LEN], 1856 struct packet_enable_params *param) 1857 { 1858 return QDF_STATUS_SUCCESS; 1859 } 1860 1861 /** 1862 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 1863 * @wmi_handle: handle to WMI. 1864 * @macaddr: Peer mac address to be filter 1865 * @mac_id: mac id to have radio context 1866 * @enb_dsb: Enable MAC based filtering or Disable 1867 * 1868 * Return: QDF_STATUS 1869 */ 1870 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 1871 uint8_t *macaddr, 1872 uint8_t mac_id, 1873 uint8_t enb_dsb) 1874 { 1875 return QDF_STATUS_SUCCESS; 1876 } 1877 /** 1878 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable 1879 * packet-log 1880 * @param wmi_handle : handle to WMI. 1881 * @mac_id: mac id to have radio context 1882 * 1883 * Return: QDF_STATUS. 1884 */ 1885 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1886 uint8_t mac_id) 1887 { 1888 return QDF_STATUS_SUCCESS; 1889 } 1890 #endif 1891 1892 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 1893 /** 1894 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 1895 * sync time between bwtween host and firmware 1896 * @param wmi_handle : handle to WMI. 1897 * 1898 * Return: None 1899 */ 1900 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 1901 { 1902 wmi_buf_t buf; 1903 QDF_STATUS status = QDF_STATUS_SUCCESS; 1904 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 1905 int32_t len; 1906 qdf_time_t time_ms; 1907 1908 len = sizeof(*time_stamp); 1909 buf = wmi_buf_alloc(wmi_handle, len); 1910 1911 if (!buf) 1912 return; 1913 1914 time_stamp = 1915 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 1916 (wmi_buf_data(buf)); 1917 WMITLV_SET_HDR(&time_stamp->tlv_header, 1918 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 1919 WMITLV_GET_STRUCT_TLVLEN( 1920 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 1921 1922 time_ms = qdf_get_time_of_the_day_ms(); 1923 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 1924 time_stamp->time_stamp_low = time_ms & 1925 WMI_FW_TIME_STAMP_LOW_MASK; 1926 /* 1927 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 1928 * wont exceed 27 bit 1929 */ 1930 time_stamp->time_stamp_high = 0; 1931 WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), 1932 time_stamp->mode, time_stamp->time_stamp_low, 1933 time_stamp->time_stamp_high); 1934 1935 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 1936 status = wmi_unified_cmd_send(wmi_handle, buf, 1937 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 1938 if (status) { 1939 WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 1940 wmi_buf_free(buf); 1941 } 1942 1943 } 1944 1945 /** 1946 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 1947 * @param wmi_handle : handle to WMI. 1948 * @param param : pointer to hold beacon send cmd parameter 1949 * 1950 * Return: 0 on success and -ve on failure. 1951 */ 1952 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 1953 struct beacon_tmpl_params *param) 1954 { 1955 int32_t ret; 1956 wmi_bcn_tmpl_cmd_fixed_param *cmd; 1957 wmi_bcn_prb_info *bcn_prb_info; 1958 wmi_buf_t wmi_buf; 1959 uint8_t *buf_ptr; 1960 uint32_t wmi_buf_len; 1961 1962 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 1963 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 1964 param->tmpl_len_aligned; 1965 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 1966 if (!wmi_buf) 1967 return QDF_STATUS_E_NOMEM; 1968 1969 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 1970 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 1971 WMITLV_SET_HDR(&cmd->tlv_header, 1972 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 1973 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 1974 cmd->vdev_id = param->vdev_id; 1975 cmd->tim_ie_offset = param->tim_ie_offset; 1976 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 1977 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 1978 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 1979 cmd->esp_ie_offset = param->esp_ie_offset; 1980 cmd->buf_len = param->tmpl_len; 1981 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 1982 1983 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 1984 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 1985 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 1986 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 1987 bcn_prb_info->caps = 0; 1988 bcn_prb_info->erp = 0; 1989 buf_ptr += sizeof(wmi_bcn_prb_info); 1990 1991 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 1992 buf_ptr += WMI_TLV_HDR_SIZE; 1993 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 1994 1995 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 1996 ret = wmi_unified_cmd_send(wmi_handle, 1997 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 1998 if (ret) { 1999 WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret); 2000 wmi_buf_free(wmi_buf); 2001 } 2002 2003 return 0; 2004 } 2005 2006 #ifdef CONFIG_MCL 2007 static inline void copy_peer_flags_tlv( 2008 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2009 struct peer_assoc_params *param) 2010 { 2011 cmd->peer_flags = param->peer_flags; 2012 } 2013 #else 2014 static inline void copy_peer_flags_tlv( 2015 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2016 struct peer_assoc_params *param) 2017 { 2018 /* 2019 * The target only needs a subset of the flags maintained in the host. 2020 * Just populate those flags and send it down 2021 */ 2022 cmd->peer_flags = 0; 2023 2024 /* 2025 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2026 */ 2027 if (param->is_wme_set) { 2028 2029 if (param->qos_flag) 2030 cmd->peer_flags |= WMI_PEER_QOS; 2031 if (param->apsd_flag) 2032 cmd->peer_flags |= WMI_PEER_APSD; 2033 if (param->ht_flag) 2034 cmd->peer_flags |= WMI_PEER_HT; 2035 if (param->bw_40) 2036 cmd->peer_flags |= WMI_PEER_40MHZ; 2037 if (param->bw_80) 2038 cmd->peer_flags |= WMI_PEER_80MHZ; 2039 if (param->bw_160) 2040 cmd->peer_flags |= WMI_PEER_160MHZ; 2041 2042 /* Typically if STBC is enabled for VHT it should be enabled 2043 * for HT as well 2044 **/ 2045 if (param->stbc_flag) 2046 cmd->peer_flags |= WMI_PEER_STBC; 2047 2048 /* Typically if LDPC is enabled for VHT it should be enabled 2049 * for HT as well 2050 **/ 2051 if (param->ldpc_flag) 2052 cmd->peer_flags |= WMI_PEER_LDPC; 2053 2054 if (param->static_mimops_flag) 2055 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2056 if (param->dynamic_mimops_flag) 2057 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2058 if (param->spatial_mux_flag) 2059 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2060 if (param->vht_flag) 2061 cmd->peer_flags |= WMI_PEER_VHT; 2062 if (param->he_flag) 2063 cmd->peer_flags |= WMI_PEER_HE; 2064 } 2065 2066 if (param->is_pmf_enabled) 2067 cmd->peer_flags |= WMI_PEER_PMF; 2068 /* 2069 * Suppress authorization for all AUTH modes that need 4-way handshake 2070 * (during re-association). 2071 * Authorization will be done for these modes on key installation. 2072 */ 2073 if (param->auth_flag) 2074 cmd->peer_flags |= WMI_PEER_AUTH; 2075 if (param->need_ptk_4_way) 2076 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2077 else 2078 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2079 if (param->need_gtk_2_way) 2080 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2081 /* safe mode bypass the 4-way handshake */ 2082 if (param->safe_mode_enabled) 2083 cmd->peer_flags &= 2084 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2085 /* Disable AMSDU for station transmit, if user configures it */ 2086 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2087 * it 2088 * if (param->amsdu_disable) Add after FW support 2089 **/ 2090 2091 /* Target asserts if node is marked HT and all MCS is set to 0. 2092 * Mark the node as non-HT if all the mcs rates are disabled through 2093 * iwpriv 2094 **/ 2095 if (param->peer_ht_rates.num_rates == 0) 2096 cmd->peer_flags &= ~WMI_PEER_HT; 2097 2098 if (param->twt_requester) 2099 cmd->peer_flags |= WMI_PEER_TWT_REQ; 2100 2101 if (param->twt_responder) 2102 cmd->peer_flags |= WMI_PEER_TWT_RESP; 2103 } 2104 #endif 2105 2106 static inline void copy_peer_mac_addr_tlv( 2107 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2108 struct peer_assoc_params *param) 2109 { 2110 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2111 } 2112 2113 /** 2114 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2115 * @param wmi_handle : handle to WMI. 2116 * @param param : pointer to peer assoc parameter 2117 * 2118 * Return: 0 on success and -ve on failure. 2119 */ 2120 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2121 struct peer_assoc_params *param) 2122 { 2123 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2124 wmi_vht_rate_set *mcs; 2125 wmi_he_rate_set *he_mcs; 2126 wmi_buf_t buf; 2127 int32_t len; 2128 uint8_t *buf_ptr; 2129 QDF_STATUS ret; 2130 uint32_t peer_legacy_rates_align; 2131 uint32_t peer_ht_rates_align; 2132 int32_t i; 2133 2134 2135 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2136 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2137 2138 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2139 (peer_legacy_rates_align * sizeof(uint8_t)) + 2140 WMI_TLV_HDR_SIZE + 2141 (peer_ht_rates_align * sizeof(uint8_t)) + 2142 sizeof(wmi_vht_rate_set) + 2143 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2144 + WMI_TLV_HDR_SIZE); 2145 2146 buf = wmi_buf_alloc(wmi_handle, len); 2147 if (!buf) 2148 return QDF_STATUS_E_NOMEM; 2149 2150 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2151 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2152 WMITLV_SET_HDR(&cmd->tlv_header, 2153 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2154 WMITLV_GET_STRUCT_TLVLEN 2155 (wmi_peer_assoc_complete_cmd_fixed_param)); 2156 2157 cmd->vdev_id = param->vdev_id; 2158 2159 cmd->peer_new_assoc = param->peer_new_assoc; 2160 cmd->peer_associd = param->peer_associd; 2161 2162 copy_peer_flags_tlv(cmd, param); 2163 copy_peer_mac_addr_tlv(cmd, param); 2164 2165 cmd->peer_rate_caps = param->peer_rate_caps; 2166 cmd->peer_caps = param->peer_caps; 2167 cmd->peer_listen_intval = param->peer_listen_intval; 2168 cmd->peer_ht_caps = param->peer_ht_caps; 2169 cmd->peer_max_mpdu = param->peer_max_mpdu; 2170 cmd->peer_mpdu_density = param->peer_mpdu_density; 2171 cmd->peer_vht_caps = param->peer_vht_caps; 2172 cmd->peer_phymode = param->peer_phymode; 2173 2174 /* Update 11ax capabilities */ 2175 cmd->peer_he_cap_info = 2176 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 2177 cmd->peer_he_cap_info_ext = 2178 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 2179 cmd->peer_he_ops = param->peer_he_ops; 2180 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2181 sizeof(param->peer_he_cap_phyinfo)); 2182 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2183 sizeof(param->peer_ppet)); 2184 2185 /* Update peer legacy rate information */ 2186 buf_ptr += sizeof(*cmd); 2187 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2188 peer_legacy_rates_align); 2189 buf_ptr += WMI_TLV_HDR_SIZE; 2190 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2191 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2192 param->peer_legacy_rates.num_rates); 2193 2194 /* Update peer HT rate information */ 2195 buf_ptr += peer_legacy_rates_align; 2196 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2197 peer_ht_rates_align); 2198 buf_ptr += WMI_TLV_HDR_SIZE; 2199 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2200 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2201 param->peer_ht_rates.num_rates); 2202 2203 /* VHT Rates */ 2204 buf_ptr += peer_ht_rates_align; 2205 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2206 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2207 2208 cmd->peer_nss = param->peer_nss; 2209 2210 /* Update bandwidth-NSS mapping */ 2211 cmd->peer_bw_rxnss_override = 0; 2212 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2213 2214 mcs = (wmi_vht_rate_set *) buf_ptr; 2215 if (param->vht_capable) { 2216 mcs->rx_max_rate = param->rx_max_rate; 2217 mcs->rx_mcs_set = param->rx_mcs_set; 2218 mcs->tx_max_rate = param->tx_max_rate; 2219 mcs->tx_mcs_set = param->tx_mcs_set; 2220 } 2221 2222 /* HE Rates */ 2223 cmd->peer_he_mcs = param->peer_he_mcs_count; 2224 buf_ptr += sizeof(wmi_vht_rate_set); 2225 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2226 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2227 buf_ptr += WMI_TLV_HDR_SIZE; 2228 2229 /* Loop through the HE rate set */ 2230 for (i = 0; i < param->peer_he_mcs_count; i++) { 2231 he_mcs = (wmi_he_rate_set *) buf_ptr; 2232 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2233 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2234 2235 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2236 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2237 WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__, 2238 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2239 buf_ptr += sizeof(wmi_he_rate_set); 2240 } 2241 2242 2243 WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x " 2244 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2245 "nss %d phymode %d peer_mpdu_density %d " 2246 "cmd->peer_vht_caps %x " 2247 "HE cap_info %x ops %x " 2248 "HE cap_info_ext %x " 2249 "HE phy %x %x %x " 2250 "peer_bw_rxnss_override %x", __func__, 2251 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2252 cmd->peer_rate_caps, cmd->peer_caps, 2253 cmd->peer_listen_intval, cmd->peer_ht_caps, 2254 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2255 cmd->peer_mpdu_density, 2256 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2257 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 2258 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 2259 cmd->peer_he_cap_phy[2], 2260 cmd->peer_bw_rxnss_override); 2261 2262 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 2263 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2264 WMI_PEER_ASSOC_CMDID); 2265 if (QDF_IS_STATUS_ERROR(ret)) { 2266 WMI_LOGP("%s: Failed to send peer assoc command ret = %d", 2267 __func__, ret); 2268 wmi_buf_free(buf); 2269 } 2270 2271 return ret; 2272 } 2273 2274 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2275 */ 2276 static inline void copy_scan_event_cntrl_flags( 2277 wmi_start_scan_cmd_fixed_param * cmd, 2278 struct scan_req_params *param) 2279 { 2280 2281 /* Scan events subscription */ 2282 if (param->scan_ev_started) 2283 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2284 if (param->scan_ev_completed) 2285 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2286 if (param->scan_ev_bss_chan) 2287 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2288 if (param->scan_ev_foreign_chan) 2289 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2290 if (param->scan_ev_dequeued) 2291 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2292 if (param->scan_ev_preempted) 2293 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2294 if (param->scan_ev_start_failed) 2295 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2296 if (param->scan_ev_restarted) 2297 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2298 if (param->scan_ev_foreign_chn_exit) 2299 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2300 if (param->scan_ev_suspended) 2301 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2302 if (param->scan_ev_resumed) 2303 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2304 2305 /** Set scan control flags */ 2306 cmd->scan_ctrl_flags = 0; 2307 if (param->scan_f_passive) 2308 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2309 if (param->scan_f_strict_passive_pch) 2310 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2311 if (param->scan_f_promisc_mode) 2312 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2313 if (param->scan_f_capture_phy_err) 2314 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2315 if (param->scan_f_half_rate) 2316 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2317 if (param->scan_f_quarter_rate) 2318 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2319 if (param->scan_f_cck_rates) 2320 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2321 if (param->scan_f_ofdm_rates) 2322 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2323 if (param->scan_f_chan_stat_evnt) 2324 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2325 if (param->scan_f_filter_prb_req) 2326 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2327 if (param->scan_f_bcast_probe) 2328 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2329 if (param->scan_f_offchan_mgmt_tx) 2330 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2331 if (param->scan_f_offchan_data_tx) 2332 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2333 if (param->scan_f_force_active_dfs_chn) 2334 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2335 if (param->scan_f_add_tpc_ie_in_probe) 2336 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2337 if (param->scan_f_add_ds_ie_in_probe) 2338 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2339 if (param->scan_f_add_spoofed_mac_in_probe) 2340 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2341 if (param->scan_f_add_rand_seq_in_probe) 2342 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2343 if (param->scan_f_en_ie_whitelist_in_probe) 2344 cmd->scan_ctrl_flags |= 2345 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2346 2347 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2348 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2349 param->adaptive_dwell_time_mode); 2350 } 2351 2352 /* scan_copy_ie_buffer() - Copy scan ie_data */ 2353 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 2354 struct scan_req_params *params) 2355 { 2356 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 2357 } 2358 2359 /** 2360 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 2361 * @mac: random mac addr 2362 * @mask: random mac mask 2363 * @mac_addr: wmi random mac 2364 * @mac_mask: wmi random mac mask 2365 * 2366 * Return None. 2367 */ 2368 static inline 2369 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 2370 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 2371 { 2372 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 2373 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 2374 } 2375 2376 /* 2377 * wmi_fill_vendor_oui() - fill vendor OUIs 2378 * @buf_ptr: pointer to wmi tlv buffer 2379 * @num_vendor_oui: number of vendor OUIs to be filled 2380 * @param_voui: pointer to OUI buffer 2381 * 2382 * This function populates the wmi tlv buffer when vendor specific OUIs are 2383 * present. 2384 * 2385 * Return: None 2386 */ 2387 static inline 2388 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 2389 uint32_t *pvoui) 2390 { 2391 wmi_vendor_oui *voui = NULL; 2392 uint32_t i; 2393 2394 voui = (wmi_vendor_oui *)buf_ptr; 2395 2396 for (i = 0; i < num_vendor_oui; i++) { 2397 WMITLV_SET_HDR(&voui[i].tlv_header, 2398 WMITLV_TAG_STRUC_wmi_vendor_oui, 2399 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 2400 voui[i].oui_type_subtype = pvoui[i]; 2401 } 2402 } 2403 2404 /* 2405 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 2406 * @ie_bitmap: output pointer to ie bit map in cmd 2407 * @num_vendor_oui: output pointer to num vendor OUIs 2408 * @ie_whitelist: input parameter 2409 * 2410 * This function populates the IE whitelist attrs of scan, pno and 2411 * scan oui commands for ie_whitelist parameter. 2412 * 2413 * Return: None 2414 */ 2415 static inline 2416 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 2417 uint32_t *num_vendor_oui, 2418 struct probe_req_whitelist_attr *ie_whitelist) 2419 { 2420 uint32_t i = 0; 2421 2422 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 2423 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 2424 2425 *num_vendor_oui = ie_whitelist->num_vendor_oui; 2426 } 2427 2428 /** 2429 * send_scan_start_cmd_tlv() - WMI scan start function 2430 * @param wmi_handle : handle to WMI. 2431 * @param param : pointer to hold scan start cmd parameter 2432 * 2433 * Return: 0 on success and -ve on failure. 2434 */ 2435 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 2436 struct scan_req_params *params) 2437 { 2438 int32_t ret = 0; 2439 int32_t i; 2440 wmi_buf_t wmi_buf; 2441 wmi_start_scan_cmd_fixed_param *cmd; 2442 uint8_t *buf_ptr; 2443 uint32_t *tmp_ptr; 2444 wmi_ssid *ssid = NULL; 2445 wmi_mac_addr *bssid; 2446 int len = sizeof(*cmd); 2447 uint8_t extraie_len_with_pad = 0; 2448 uint8_t phymode_roundup = 0; 2449 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 2450 2451 /* Length TLV placeholder for array of uint32_t */ 2452 len += WMI_TLV_HDR_SIZE; 2453 /* calculate the length of buffer required */ 2454 if (params->chan_list.num_chan) 2455 len += params->chan_list.num_chan * sizeof(uint32_t); 2456 2457 /* Length TLV placeholder for array of wmi_ssid structures */ 2458 len += WMI_TLV_HDR_SIZE; 2459 if (params->num_ssids) 2460 len += params->num_ssids * sizeof(wmi_ssid); 2461 2462 /* Length TLV placeholder for array of wmi_mac_addr structures */ 2463 len += WMI_TLV_HDR_SIZE; 2464 if (params->num_bssid) 2465 len += sizeof(wmi_mac_addr) * params->num_bssid; 2466 2467 /* Length TLV placeholder for array of bytes */ 2468 len += WMI_TLV_HDR_SIZE; 2469 if (params->extraie.len) 2470 extraie_len_with_pad = 2471 roundup(params->extraie.len, sizeof(uint32_t)); 2472 len += extraie_len_with_pad; 2473 2474 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 2475 if (ie_whitelist->num_vendor_oui) 2476 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 2477 2478 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 2479 if (params->scan_f_wide_band) 2480 phymode_roundup = 2481 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 2482 sizeof(uint32_t)); 2483 len += phymode_roundup; 2484 2485 /* Allocate the memory */ 2486 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2487 if (!wmi_buf) 2488 return QDF_STATUS_E_FAILURE; 2489 2490 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2491 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 2492 WMITLV_SET_HDR(&cmd->tlv_header, 2493 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 2494 WMITLV_GET_STRUCT_TLVLEN 2495 (wmi_start_scan_cmd_fixed_param)); 2496 2497 cmd->scan_id = params->scan_id; 2498 cmd->scan_req_id = params->scan_req_id; 2499 cmd->vdev_id = params->vdev_id; 2500 cmd->scan_priority = params->scan_priority; 2501 2502 copy_scan_event_cntrl_flags(cmd, params); 2503 2504 cmd->dwell_time_active = params->dwell_time_active; 2505 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 2506 cmd->dwell_time_passive = params->dwell_time_passive; 2507 cmd->min_rest_time = params->min_rest_time; 2508 cmd->max_rest_time = params->max_rest_time; 2509 cmd->repeat_probe_time = params->repeat_probe_time; 2510 cmd->probe_spacing_time = params->probe_spacing_time; 2511 cmd->idle_time = params->idle_time; 2512 cmd->max_scan_time = params->max_scan_time; 2513 cmd->probe_delay = params->probe_delay; 2514 cmd->burst_duration = params->burst_duration; 2515 cmd->num_chan = params->chan_list.num_chan; 2516 cmd->num_bssid = params->num_bssid; 2517 cmd->num_ssids = params->num_ssids; 2518 cmd->ie_len = params->extraie.len; 2519 cmd->n_probes = params->n_probes; 2520 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 2521 2522 WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext); 2523 2524 if (params->scan_random.randomize) 2525 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 2526 params->scan_random.mac_mask, 2527 &cmd->mac_addr, 2528 &cmd->mac_mask); 2529 2530 if (ie_whitelist->white_list) 2531 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 2532 &cmd->num_vendor_oui, 2533 ie_whitelist); 2534 2535 buf_ptr += sizeof(*cmd); 2536 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2537 for (i = 0; i < params->chan_list.num_chan; ++i) 2538 tmp_ptr[i] = params->chan_list.chan[i].freq; 2539 2540 WMITLV_SET_HDR(buf_ptr, 2541 WMITLV_TAG_ARRAY_UINT32, 2542 (params->chan_list.num_chan * sizeof(uint32_t))); 2543 buf_ptr += WMI_TLV_HDR_SIZE + 2544 (params->chan_list.num_chan * sizeof(uint32_t)); 2545 2546 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 2547 WMI_LOGE("Invalid value for num_ssids %d", params->num_ssids); 2548 goto error; 2549 } 2550 2551 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2552 (params->num_ssids * sizeof(wmi_ssid))); 2553 2554 if (params->num_ssids) { 2555 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 2556 for (i = 0; i < params->num_ssids; ++i) { 2557 ssid->ssid_len = params->ssid[i].length; 2558 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 2559 params->ssid[i].length); 2560 ssid++; 2561 } 2562 } 2563 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 2564 2565 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2566 (params->num_bssid * sizeof(wmi_mac_addr))); 2567 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 2568 2569 if (params->num_bssid) { 2570 for (i = 0; i < params->num_bssid; ++i) { 2571 WMI_CHAR_ARRAY_TO_MAC_ADDR( 2572 ¶ms->bssid_list[i].bytes[0], bssid); 2573 bssid++; 2574 } 2575 } 2576 2577 buf_ptr += WMI_TLV_HDR_SIZE + 2578 (params->num_bssid * sizeof(wmi_mac_addr)); 2579 2580 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 2581 if (params->extraie.len) 2582 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 2583 params); 2584 2585 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 2586 2587 /* probe req ie whitelisting */ 2588 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2589 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 2590 2591 buf_ptr += WMI_TLV_HDR_SIZE; 2592 2593 if (cmd->num_vendor_oui) { 2594 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 2595 ie_whitelist->voui); 2596 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 2597 } 2598 2599 /* Add phy mode TLV if it's a wide band scan */ 2600 if (params->scan_f_wide_band) { 2601 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 2602 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2603 for (i = 0; i < params->chan_list.num_chan; ++i) 2604 buf_ptr[i] = 2605 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 2606 buf_ptr += phymode_roundup; 2607 } else { 2608 /* Add ZERO legth phy mode TLV */ 2609 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 2610 } 2611 2612 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 2613 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2614 len, WMI_START_SCAN_CMDID); 2615 if (ret) { 2616 WMI_LOGE("%s: Failed to start scan: %d", __func__, ret); 2617 wmi_buf_free(wmi_buf); 2618 } 2619 return ret; 2620 error: 2621 wmi_buf_free(wmi_buf); 2622 return QDF_STATUS_E_FAILURE; 2623 } 2624 2625 /** 2626 * send_scan_stop_cmd_tlv() - WMI scan start function 2627 * @param wmi_handle : handle to WMI. 2628 * @param param : pointer to hold scan cancel cmd parameter 2629 * 2630 * Return: 0 on success and -ve on failure. 2631 */ 2632 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 2633 struct scan_cancel_param *param) 2634 { 2635 wmi_stop_scan_cmd_fixed_param *cmd; 2636 int ret; 2637 int len = sizeof(*cmd); 2638 wmi_buf_t wmi_buf; 2639 2640 /* Allocate the memory */ 2641 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2642 if (!wmi_buf) { 2643 ret = QDF_STATUS_E_NOMEM; 2644 goto error; 2645 } 2646 2647 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2648 WMITLV_SET_HDR(&cmd->tlv_header, 2649 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 2650 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 2651 cmd->vdev_id = param->vdev_id; 2652 cmd->requestor = param->requester; 2653 cmd->scan_id = param->scan_id; 2654 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2655 param->pdev_id); 2656 /* stop the scan with the corresponding scan_id */ 2657 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 2658 /* Cancelling all scans */ 2659 cmd->req_type = WMI_SCAN_STOP_ALL; 2660 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 2661 /* Cancelling VAP scans */ 2662 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 2663 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 2664 /* Cancelling specific scan */ 2665 cmd->req_type = WMI_SCAN_STOP_ONE; 2666 } else { 2667 WMI_LOGE("%s: Invalid Command : ", __func__); 2668 wmi_buf_free(wmi_buf); 2669 return QDF_STATUS_E_INVAL; 2670 } 2671 2672 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 2673 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2674 len, WMI_STOP_SCAN_CMDID); 2675 if (ret) { 2676 WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret); 2677 wmi_buf_free(wmi_buf); 2678 } 2679 2680 error: 2681 return ret; 2682 } 2683 2684 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2685 struct scan_chan_list_params *chan_list) 2686 { 2687 wmi_buf_t buf; 2688 QDF_STATUS qdf_status; 2689 wmi_scan_chan_list_cmd_fixed_param *cmd; 2690 int i; 2691 uint8_t *buf_ptr; 2692 wmi_channel *chan_info; 2693 struct channel_param *tchan_info; 2694 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2695 2696 len += sizeof(wmi_channel) * chan_list->nallchans; 2697 buf = wmi_buf_alloc(wmi_handle, len); 2698 if (!buf) { 2699 qdf_status = QDF_STATUS_E_NOMEM; 2700 goto end; 2701 } 2702 2703 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2704 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2705 WMITLV_SET_HDR(&cmd->tlv_header, 2706 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2707 WMITLV_GET_STRUCT_TLVLEN 2708 (wmi_scan_chan_list_cmd_fixed_param)); 2709 2710 WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len); 2711 2712 if (chan_list->append) 2713 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 2714 2715 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2716 chan_list->pdev_id); 2717 cmd->num_scan_chans = chan_list->nallchans; 2718 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2719 WMITLV_TAG_ARRAY_STRUC, 2720 sizeof(wmi_channel) * chan_list->nallchans); 2721 chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2722 tchan_info = &(chan_list->ch_param[0]); 2723 2724 for (i = 0; i < chan_list->nallchans; ++i) { 2725 WMITLV_SET_HDR(&chan_info->tlv_header, 2726 WMITLV_TAG_STRUC_wmi_channel, 2727 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2728 chan_info->mhz = tchan_info->mhz; 2729 chan_info->band_center_freq1 = 2730 tchan_info->cfreq1; 2731 chan_info->band_center_freq2 = 2732 tchan_info->cfreq2; 2733 2734 if (tchan_info->is_chan_passive) 2735 WMI_SET_CHANNEL_FLAG(chan_info, 2736 WMI_CHAN_FLAG_PASSIVE); 2737 if (tchan_info->dfs_set) 2738 WMI_SET_CHANNEL_FLAG(chan_info, 2739 WMI_CHAN_FLAG_DFS); 2740 2741 if (tchan_info->allow_vht) 2742 WMI_SET_CHANNEL_FLAG(chan_info, 2743 WMI_CHAN_FLAG_ALLOW_VHT); 2744 if (tchan_info->allow_ht) 2745 WMI_SET_CHANNEL_FLAG(chan_info, 2746 WMI_CHAN_FLAG_ALLOW_HT); 2747 WMI_SET_CHANNEL_MODE(chan_info, 2748 tchan_info->phy_mode); 2749 2750 if (tchan_info->half_rate) 2751 WMI_SET_CHANNEL_FLAG(chan_info, 2752 WMI_CHAN_FLAG_HALF_RATE); 2753 2754 if (tchan_info->quarter_rate) 2755 WMI_SET_CHANNEL_FLAG(chan_info, 2756 WMI_CHAN_FLAG_QUARTER_RATE); 2757 2758 /* also fill in power information */ 2759 WMI_SET_CHANNEL_MIN_POWER(chan_info, 2760 tchan_info->minpower); 2761 WMI_SET_CHANNEL_MAX_POWER(chan_info, 2762 tchan_info->maxpower); 2763 WMI_SET_CHANNEL_REG_POWER(chan_info, 2764 tchan_info->maxregpower); 2765 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 2766 tchan_info->antennamax); 2767 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 2768 tchan_info->reg_class_id); 2769 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 2770 tchan_info->maxregpower); 2771 2772 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 2773 2774 tchan_info++; 2775 chan_info++; 2776 } 2777 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2778 chan_list->pdev_id); 2779 2780 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 2781 qdf_status = wmi_unified_cmd_send( 2782 wmi_handle, 2783 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 2784 2785 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2786 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 2787 wmi_buf_free(buf); 2788 } 2789 2790 end: 2791 return qdf_status; 2792 } 2793 2794 /** 2795 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 2796 * 2797 * @bufp: Pointer to buffer 2798 * @param: Pointer to tx param 2799 * 2800 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 2801 */ 2802 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 2803 struct tx_send_params param) 2804 { 2805 wmi_tx_send_params *tx_param; 2806 QDF_STATUS status = QDF_STATUS_SUCCESS; 2807 2808 if (!bufp) { 2809 status = QDF_STATUS_E_FAILURE; 2810 return status; 2811 } 2812 tx_param = (wmi_tx_send_params *)bufp; 2813 WMITLV_SET_HDR(&tx_param->tlv_header, 2814 WMITLV_TAG_STRUC_wmi_tx_send_params, 2815 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 2816 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 2817 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 2818 param.mcs_mask); 2819 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 2820 param.nss_mask); 2821 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 2822 param.retry_limit); 2823 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 2824 param.chain_mask); 2825 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 2826 param.bw_mask); 2827 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 2828 param.preamble_type); 2829 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 2830 param.frame_type); 2831 2832 return status; 2833 } 2834 2835 #ifdef CONFIG_HL_SUPPORT 2836 /** 2837 * send_mgmt_cmd_tlv() - WMI scan start function 2838 * @wmi_handle : handle to WMI. 2839 * @param : pointer to hold mgmt cmd parameter 2840 * 2841 * Return: 0 on success and -ve on failure. 2842 */ 2843 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 2844 struct wmi_mgmt_params *param) 2845 { 2846 wmi_buf_t buf; 2847 uint8_t *bufp; 2848 int32_t cmd_len; 2849 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 2850 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 2851 mgmt_tx_dl_frm_len; 2852 2853 if (param->frm_len > mgmt_tx_dl_frm_len) { 2854 WMI_LOGE("%s:mgmt frame len %u exceeds %u", 2855 __func__, param->frm_len, mgmt_tx_dl_frm_len); 2856 return QDF_STATUS_E_INVAL; 2857 } 2858 2859 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 2860 WMI_TLV_HDR_SIZE + 2861 roundup(bufp_len, sizeof(uint32_t)); 2862 2863 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 2864 if (!buf) 2865 return QDF_STATUS_E_NOMEM; 2866 2867 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 2868 bufp = (uint8_t *) cmd; 2869 WMITLV_SET_HDR(&cmd->tlv_header, 2870 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 2871 WMITLV_GET_STRUCT_TLVLEN 2872 (wmi_mgmt_tx_send_cmd_fixed_param)); 2873 2874 cmd->vdev_id = param->vdev_id; 2875 2876 cmd->desc_id = param->desc_id; 2877 cmd->chanfreq = param->chanfreq; 2878 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 2879 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 2880 sizeof(uint32_t))); 2881 bufp += WMI_TLV_HDR_SIZE; 2882 qdf_mem_copy(bufp, param->pdata, bufp_len); 2883 2884 cmd->frame_len = param->frm_len; 2885 cmd->buf_len = bufp_len; 2886 cmd->tx_params_valid = param->tx_params_valid; 2887 2888 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 2889 bufp, cmd->vdev_id, cmd->chanfreq); 2890 2891 bufp += roundup(bufp_len, sizeof(uint32_t)); 2892 if (param->tx_params_valid) { 2893 if (populate_tx_send_params(bufp, param->tx_param) != 2894 QDF_STATUS_SUCCESS) { 2895 WMI_LOGE("%s: Populate TX send params failed", 2896 __func__); 2897 goto free_buf; 2898 } 2899 cmd_len += sizeof(wmi_tx_send_params); 2900 } 2901 2902 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 2903 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 2904 WMI_MGMT_TX_SEND_CMDID)) { 2905 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 2906 goto free_buf; 2907 } 2908 return QDF_STATUS_SUCCESS; 2909 2910 free_buf: 2911 wmi_buf_free(buf); 2912 return QDF_STATUS_E_FAILURE; 2913 } 2914 #else 2915 /** 2916 * send_mgmt_cmd_tlv() - WMI scan start function 2917 * @wmi_handle : handle to WMI. 2918 * @param : pointer to hold mgmt cmd parameter 2919 * 2920 * Return: 0 on success and -ve on failure. 2921 */ 2922 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 2923 struct wmi_mgmt_params *param) 2924 { 2925 wmi_buf_t buf; 2926 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 2927 int32_t cmd_len; 2928 uint64_t dma_addr; 2929 void *qdf_ctx = param->qdf_ctx; 2930 uint8_t *bufp; 2931 QDF_STATUS status = QDF_STATUS_SUCCESS; 2932 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 2933 mgmt_tx_dl_frm_len; 2934 2935 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 2936 WMI_TLV_HDR_SIZE + 2937 roundup(bufp_len, sizeof(uint32_t)); 2938 2939 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 2940 if (!buf) 2941 return QDF_STATUS_E_NOMEM; 2942 2943 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 2944 bufp = (uint8_t *) cmd; 2945 WMITLV_SET_HDR(&cmd->tlv_header, 2946 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 2947 WMITLV_GET_STRUCT_TLVLEN 2948 (wmi_mgmt_tx_send_cmd_fixed_param)); 2949 2950 cmd->vdev_id = param->vdev_id; 2951 2952 cmd->desc_id = param->desc_id; 2953 cmd->chanfreq = param->chanfreq; 2954 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 2955 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 2956 sizeof(uint32_t))); 2957 bufp += WMI_TLV_HDR_SIZE; 2958 qdf_mem_copy(bufp, param->pdata, bufp_len); 2959 2960 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 2961 QDF_DMA_TO_DEVICE); 2962 if (status != QDF_STATUS_SUCCESS) { 2963 WMI_LOGE("%s: wmi buf map failed", __func__); 2964 goto free_buf; 2965 } 2966 2967 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 2968 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 2969 #if defined(HTT_PADDR64) 2970 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 2971 #endif 2972 cmd->frame_len = param->frm_len; 2973 cmd->buf_len = bufp_len; 2974 cmd->tx_params_valid = param->tx_params_valid; 2975 2976 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 2977 bufp, cmd->vdev_id, cmd->chanfreq); 2978 2979 bufp += roundup(bufp_len, sizeof(uint32_t)); 2980 if (param->tx_params_valid) { 2981 status = populate_tx_send_params(bufp, param->tx_param); 2982 if (status != QDF_STATUS_SUCCESS) { 2983 WMI_LOGE("%s: Populate TX send params failed", 2984 __func__); 2985 goto unmap_tx_frame; 2986 } 2987 cmd_len += sizeof(wmi_tx_send_params); 2988 } 2989 2990 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 2991 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 2992 WMI_MGMT_TX_SEND_CMDID)) { 2993 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 2994 goto unmap_tx_frame; 2995 } 2996 return QDF_STATUS_SUCCESS; 2997 2998 unmap_tx_frame: 2999 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3000 QDF_DMA_TO_DEVICE); 3001 free_buf: 3002 wmi_buf_free(buf); 3003 return QDF_STATUS_E_FAILURE; 3004 } 3005 #endif /* CONFIG_HL_SUPPORT */ 3006 3007 /** 3008 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3009 * @wmi_handle : handle to WMI. 3010 * @param : pointer to offchan data tx cmd parameter 3011 * 3012 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3013 */ 3014 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3015 struct wmi_offchan_data_tx_params *param) 3016 { 3017 wmi_buf_t buf; 3018 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3019 int32_t cmd_len; 3020 uint64_t dma_addr; 3021 void *qdf_ctx = param->qdf_ctx; 3022 uint8_t *bufp; 3023 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3024 param->frm_len : mgmt_tx_dl_frm_len; 3025 QDF_STATUS status = QDF_STATUS_SUCCESS; 3026 3027 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3028 WMI_TLV_HDR_SIZE + 3029 roundup(bufp_len, sizeof(uint32_t)); 3030 3031 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3032 if (!buf) 3033 return QDF_STATUS_E_NOMEM; 3034 3035 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3036 bufp = (uint8_t *) cmd; 3037 WMITLV_SET_HDR(&cmd->tlv_header, 3038 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3039 WMITLV_GET_STRUCT_TLVLEN 3040 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3041 3042 cmd->vdev_id = param->vdev_id; 3043 3044 cmd->desc_id = param->desc_id; 3045 cmd->chanfreq = param->chanfreq; 3046 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3047 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3048 sizeof(uint32_t))); 3049 bufp += WMI_TLV_HDR_SIZE; 3050 qdf_mem_copy(bufp, param->pdata, bufp_len); 3051 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3052 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3053 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3054 #if defined(HTT_PADDR64) 3055 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3056 #endif 3057 cmd->frame_len = param->frm_len; 3058 cmd->buf_len = bufp_len; 3059 cmd->tx_params_valid = param->tx_params_valid; 3060 3061 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3062 bufp, cmd->vdev_id, cmd->chanfreq); 3063 3064 bufp += roundup(bufp_len, sizeof(uint32_t)); 3065 if (param->tx_params_valid) { 3066 status = populate_tx_send_params(bufp, param->tx_param); 3067 if (status != QDF_STATUS_SUCCESS) { 3068 WMI_LOGE("%s: Populate TX send params failed", 3069 __func__); 3070 goto err1; 3071 } 3072 cmd_len += sizeof(wmi_tx_send_params); 3073 } 3074 3075 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 3076 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3077 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3078 WMI_LOGE("%s: Failed to offchan data Tx", __func__); 3079 goto err1; 3080 } 3081 3082 return QDF_STATUS_SUCCESS; 3083 3084 err1: 3085 wmi_buf_free(buf); 3086 return QDF_STATUS_E_FAILURE; 3087 } 3088 3089 /** 3090 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3091 * @wmi_handle: wmi handle 3092 * @param_value: parameter value 3093 * 3094 * Return: QDF_STATUS_SUCCESS for success or error code 3095 */ 3096 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3097 uint32_t param_value) 3098 { 3099 QDF_STATUS ret; 3100 wmi_modem_power_state_cmd_param *cmd; 3101 wmi_buf_t buf; 3102 uint16_t len = sizeof(*cmd); 3103 3104 buf = wmi_buf_alloc(wmi_handle, len); 3105 if (!buf) 3106 return QDF_STATUS_E_NOMEM; 3107 3108 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3109 WMITLV_SET_HDR(&cmd->tlv_header, 3110 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3111 WMITLV_GET_STRUCT_TLVLEN 3112 (wmi_modem_power_state_cmd_param)); 3113 cmd->modem_power_state = param_value; 3114 WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__, 3115 param_value); 3116 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 3117 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3118 WMI_MODEM_POWER_STATE_CMDID); 3119 if (QDF_IS_STATUS_ERROR(ret)) { 3120 WMI_LOGE("Failed to send notify cmd ret = %d", ret); 3121 wmi_buf_free(buf); 3122 } 3123 3124 return ret; 3125 } 3126 3127 /** 3128 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3129 * @wmi_handle: wmi handle 3130 * @vdev_id: vdev id 3131 * @val: value 3132 * 3133 * Return: QDF_STATUS_SUCCESS for success or error code. 3134 */ 3135 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3136 uint32_t vdev_id, uint8_t val) 3137 { 3138 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3139 wmi_buf_t buf; 3140 int32_t len = sizeof(*cmd); 3141 3142 WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3143 3144 buf = wmi_buf_alloc(wmi_handle, len); 3145 if (!buf) 3146 return QDF_STATUS_E_NOMEM; 3147 3148 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3149 WMITLV_SET_HDR(&cmd->tlv_header, 3150 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3151 WMITLV_GET_STRUCT_TLVLEN 3152 (wmi_sta_powersave_mode_cmd_fixed_param)); 3153 cmd->vdev_id = vdev_id; 3154 if (val) 3155 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3156 else 3157 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3158 3159 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 3160 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3161 WMI_STA_POWERSAVE_MODE_CMDID)) { 3162 WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d", 3163 vdev_id, val); 3164 wmi_buf_free(buf); 3165 return QDF_STATUS_E_FAILURE; 3166 } 3167 return 0; 3168 } 3169 3170 /** 3171 * send_set_mimops_cmd_tlv() - set MIMO powersave 3172 * @wmi_handle: wmi handle 3173 * @vdev_id: vdev id 3174 * @value: value 3175 * 3176 * Return: QDF_STATUS_SUCCESS for success or error code. 3177 */ 3178 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3179 uint8_t vdev_id, int value) 3180 { 3181 QDF_STATUS ret; 3182 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3183 wmi_buf_t buf; 3184 uint16_t len = sizeof(*cmd); 3185 3186 buf = wmi_buf_alloc(wmi_handle, len); 3187 if (!buf) 3188 return QDF_STATUS_E_NOMEM; 3189 3190 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 3191 WMITLV_SET_HDR(&cmd->tlv_header, 3192 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 3193 WMITLV_GET_STRUCT_TLVLEN 3194 (wmi_sta_smps_force_mode_cmd_fixed_param)); 3195 3196 cmd->vdev_id = vdev_id; 3197 3198 /* WMI_SMPS_FORCED_MODE values do not directly map 3199 * to SM power save values defined in the specification. 3200 * Make sure to send the right mapping. 3201 */ 3202 switch (value) { 3203 case 0: 3204 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 3205 break; 3206 case 1: 3207 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 3208 break; 3209 case 2: 3210 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 3211 break; 3212 case 3: 3213 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 3214 break; 3215 default: 3216 WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__); 3217 wmi_buf_free(buf); 3218 return QDF_STATUS_E_FAILURE; 3219 } 3220 3221 WMI_LOGD("Setting vdev %d value = %u", vdev_id, value); 3222 3223 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 3224 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3225 WMI_STA_SMPS_FORCE_MODE_CMDID); 3226 if (QDF_IS_STATUS_ERROR(ret)) { 3227 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3228 wmi_buf_free(buf); 3229 } 3230 3231 return ret; 3232 } 3233 3234 /** 3235 * send_set_smps_params_cmd_tlv() - set smps params 3236 * @wmi_handle: wmi handle 3237 * @vdev_id: vdev id 3238 * @value: value 3239 * 3240 * Return: QDF_STATUS_SUCCESS for success or error code. 3241 */ 3242 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 3243 int value) 3244 { 3245 QDF_STATUS ret; 3246 wmi_sta_smps_param_cmd_fixed_param *cmd; 3247 wmi_buf_t buf; 3248 uint16_t len = sizeof(*cmd); 3249 3250 buf = wmi_buf_alloc(wmi_handle, len); 3251 if (!buf) 3252 return QDF_STATUS_E_NOMEM; 3253 3254 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 3255 WMITLV_SET_HDR(&cmd->tlv_header, 3256 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 3257 WMITLV_GET_STRUCT_TLVLEN 3258 (wmi_sta_smps_param_cmd_fixed_param)); 3259 3260 cmd->vdev_id = vdev_id; 3261 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 3262 cmd->param = 3263 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 3264 3265 WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 3266 cmd->param); 3267 3268 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 3269 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3270 WMI_STA_SMPS_PARAM_CMDID); 3271 if (QDF_IS_STATUS_ERROR(ret)) { 3272 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3273 wmi_buf_free(buf); 3274 } 3275 3276 return ret; 3277 } 3278 3279 /** 3280 * send_get_temperature_cmd_tlv() - get pdev temperature req 3281 * @wmi_handle: wmi handle 3282 * 3283 * Return: QDF_STATUS_SUCCESS for success or error code. 3284 */ 3285 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 3286 { 3287 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 3288 wmi_buf_t wmi_buf; 3289 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 3290 uint8_t *buf_ptr; 3291 3292 if (!wmi_handle) { 3293 WMI_LOGE(FL("WMI is closed, can not issue cmd")); 3294 return QDF_STATUS_E_INVAL; 3295 } 3296 3297 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3298 if (!wmi_buf) 3299 return QDF_STATUS_E_NOMEM; 3300 3301 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3302 3303 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 3304 WMITLV_SET_HDR(&cmd->tlv_header, 3305 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 3306 WMITLV_GET_STRUCT_TLVLEN 3307 (wmi_pdev_get_temperature_cmd_fixed_param)); 3308 3309 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 3310 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 3311 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 3312 WMI_LOGE(FL("failed to send get temperature command")); 3313 wmi_buf_free(wmi_buf); 3314 return QDF_STATUS_E_FAILURE; 3315 } 3316 3317 return QDF_STATUS_SUCCESS; 3318 } 3319 3320 /** 3321 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 3322 * @wmi_handle: wmi handle 3323 * @vdevid: vdev id 3324 * @peer_addr: peer mac address 3325 * @auto_triggerparam: auto trigger parameters 3326 * @num_ac: number of access category 3327 * 3328 * This function sets the trigger 3329 * uapsd params such as service interval, delay interval 3330 * and suspend interval which will be used by the firmware 3331 * to send trigger frames periodically when there is no 3332 * traffic on the transmit side. 3333 * 3334 * Return: QDF_STATUS_SUCCESS for success or error code. 3335 */ 3336 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 3337 struct sta_uapsd_trig_params *param) 3338 { 3339 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 3340 QDF_STATUS ret; 3341 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 3342 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 3343 uint32_t i; 3344 wmi_buf_t buf; 3345 uint8_t *buf_ptr; 3346 struct sta_uapsd_params *uapsd_param; 3347 wmi_sta_uapsd_auto_trig_param *trig_param; 3348 3349 buf = wmi_buf_alloc(wmi_handle, cmd_len); 3350 if (!buf) 3351 return QDF_STATUS_E_NOMEM; 3352 3353 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3354 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 3355 WMITLV_SET_HDR(&cmd->tlv_header, 3356 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 3357 WMITLV_GET_STRUCT_TLVLEN 3358 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 3359 cmd->vdev_id = param->vdevid; 3360 cmd->num_ac = param->num_ac; 3361 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 3362 3363 /* TLV indicating array of structures to follow */ 3364 buf_ptr += sizeof(*cmd); 3365 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 3366 3367 buf_ptr += WMI_TLV_HDR_SIZE; 3368 3369 /* 3370 * Update tag and length for uapsd auto trigger params (this will take 3371 * care of updating tag and length if it is not pre-filled by caller). 3372 */ 3373 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 3374 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 3375 for (i = 0; i < param->num_ac; i++) { 3376 WMITLV_SET_HDR((buf_ptr + 3377 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 3378 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 3379 WMITLV_GET_STRUCT_TLVLEN 3380 (wmi_sta_uapsd_auto_trig_param)); 3381 trig_param->wmm_ac = uapsd_param->wmm_ac; 3382 trig_param->user_priority = uapsd_param->user_priority; 3383 trig_param->service_interval = uapsd_param->service_interval; 3384 trig_param->suspend_interval = uapsd_param->suspend_interval; 3385 trig_param->delay_interval = uapsd_param->delay_interval; 3386 trig_param++; 3387 uapsd_param++; 3388 } 3389 3390 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 3391 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3392 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 3393 if (QDF_IS_STATUS_ERROR(ret)) { 3394 WMI_LOGE("Failed to send set uapsd param ret = %d", ret); 3395 wmi_buf_free(buf); 3396 } 3397 3398 return ret; 3399 } 3400 3401 /** 3402 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 3403 * @wmi_handle: Pointer to wmi handle 3404 * @thermal_info: Thermal command information 3405 * 3406 * This function sends the thermal management command 3407 * to the firmware 3408 * 3409 * Return: QDF_STATUS_SUCCESS for success otherwise failure 3410 */ 3411 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3412 struct thermal_cmd_params *thermal_info) 3413 { 3414 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 3415 wmi_buf_t buf = NULL; 3416 QDF_STATUS status; 3417 uint32_t len = 0; 3418 3419 len = sizeof(*cmd); 3420 3421 buf = wmi_buf_alloc(wmi_handle, len); 3422 if (!buf) 3423 return QDF_STATUS_E_FAILURE; 3424 3425 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 3426 3427 WMITLV_SET_HDR(&cmd->tlv_header, 3428 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 3429 WMITLV_GET_STRUCT_TLVLEN 3430 (wmi_thermal_mgmt_cmd_fixed_param)); 3431 3432 cmd->lower_thresh_degreeC = thermal_info->min_temp; 3433 cmd->upper_thresh_degreeC = thermal_info->max_temp; 3434 cmd->enable = thermal_info->thermal_enable; 3435 3436 WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d", 3437 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable); 3438 3439 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 3440 status = wmi_unified_cmd_send(wmi_handle, buf, len, 3441 WMI_THERMAL_MGMT_CMDID); 3442 if (QDF_IS_STATUS_ERROR(status)) { 3443 wmi_buf_free(buf); 3444 WMI_LOGE("%s:Failed to send thermal mgmt command", __func__); 3445 } 3446 3447 return status; 3448 } 3449 3450 /** 3451 * send_lro_config_cmd_tlv() - process the LRO config command 3452 * @wmi_handle: Pointer to WMI handle 3453 * @wmi_lro_cmd: Pointer to LRO configuration parameters 3454 * 3455 * This function sends down the LRO configuration parameters to 3456 * the firmware to enable LRO, sets the TCP flags and sets the 3457 * seed values for the toeplitz hash generation 3458 * 3459 * Return: QDF_STATUS_SUCCESS for success otherwise failure 3460 */ 3461 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 3462 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 3463 { 3464 wmi_lro_info_cmd_fixed_param *cmd; 3465 wmi_buf_t buf; 3466 QDF_STATUS status; 3467 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 3468 3469 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 3470 if (!buf) 3471 return QDF_STATUS_E_FAILURE; 3472 3473 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 3474 3475 WMITLV_SET_HDR(&cmd->tlv_header, 3476 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 3477 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 3478 3479 cmd->lro_enable = wmi_lro_cmd->lro_enable; 3480 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 3481 wmi_lro_cmd->tcp_flag); 3482 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 3483 wmi_lro_cmd->tcp_flag_mask); 3484 cmd->toeplitz_hash_ipv4_0_3 = 3485 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 3486 cmd->toeplitz_hash_ipv4_4_7 = 3487 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 3488 cmd->toeplitz_hash_ipv4_8_11 = 3489 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 3490 cmd->toeplitz_hash_ipv4_12_15 = 3491 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 3492 cmd->toeplitz_hash_ipv4_16 = 3493 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 3494 3495 cmd->toeplitz_hash_ipv6_0_3 = 3496 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 3497 cmd->toeplitz_hash_ipv6_4_7 = 3498 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 3499 cmd->toeplitz_hash_ipv6_8_11 = 3500 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 3501 cmd->toeplitz_hash_ipv6_12_15 = 3502 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 3503 cmd->toeplitz_hash_ipv6_16_19 = 3504 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 3505 cmd->toeplitz_hash_ipv6_20_23 = 3506 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 3507 cmd->toeplitz_hash_ipv6_24_27 = 3508 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 3509 cmd->toeplitz_hash_ipv6_28_31 = 3510 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 3511 cmd->toeplitz_hash_ipv6_32_35 = 3512 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 3513 cmd->toeplitz_hash_ipv6_36_39 = 3514 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 3515 cmd->toeplitz_hash_ipv6_40 = 3516 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 3517 3518 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 3519 WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 3520 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 3521 3522 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 3523 status = wmi_unified_cmd_send(wmi_handle, buf, 3524 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 3525 if (QDF_IS_STATUS_ERROR(status)) { 3526 wmi_buf_free(buf); 3527 WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__); 3528 } 3529 3530 return status; 3531 } 3532 3533 /** 3534 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 3535 * @wmi_handle: Pointer to wmi handle 3536 * @rate_report_params: Pointer to peer rate report parameters 3537 * 3538 * 3539 * Return: QDF_STATUS_SUCCESS for success otherwise failure 3540 */ 3541 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 3542 struct wmi_peer_rate_report_params *rate_report_params) 3543 { 3544 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 3545 wmi_buf_t buf = NULL; 3546 QDF_STATUS status = 0; 3547 uint32_t len = 0; 3548 uint32_t i, j; 3549 3550 len = sizeof(*cmd); 3551 3552 buf = wmi_buf_alloc(wmi_handle, len); 3553 if (!buf) 3554 return QDF_STATUS_E_FAILURE; 3555 3556 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 3557 wmi_buf_data(buf); 3558 3559 WMITLV_SET_HDR( 3560 &cmd->tlv_header, 3561 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 3562 WMITLV_GET_STRUCT_TLVLEN( 3563 wmi_peer_set_rate_report_condition_fixed_param)); 3564 3565 cmd->enable_rate_report = rate_report_params->rate_report_enable; 3566 cmd->report_backoff_time = rate_report_params->backoff_time; 3567 cmd->report_timer_period = rate_report_params->timer_period; 3568 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 3569 cmd->cond_per_phy[i].val_cond_flags = 3570 rate_report_params->report_per_phy[i].cond_flags; 3571 cmd->cond_per_phy[i].rate_delta.min_delta = 3572 rate_report_params->report_per_phy[i].delta.delta_min; 3573 cmd->cond_per_phy[i].rate_delta.percentage = 3574 rate_report_params->report_per_phy[i].delta.percent; 3575 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 3576 cmd->cond_per_phy[i].rate_threshold[j] = 3577 rate_report_params->report_per_phy[i]. 3578 report_rate_threshold[j]; 3579 } 3580 } 3581 3582 WMI_LOGE("%s enable %d backoff_time %d period %d", __func__, 3583 cmd->enable_rate_report, 3584 cmd->report_backoff_time, cmd->report_timer_period); 3585 3586 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 3587 status = wmi_unified_cmd_send(wmi_handle, buf, len, 3588 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 3589 if (QDF_IS_STATUS_ERROR(status)) { 3590 wmi_buf_free(buf); 3591 WMI_LOGE("%s:Failed to send peer_set_report_cond command", 3592 __func__); 3593 } 3594 return status; 3595 } 3596 3597 #ifdef CONFIG_MCL 3598 /** 3599 * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL 3600 * @wmi_handle: wmi handle 3601 * @param: bcn ll cmd parameter 3602 * 3603 * Return: QDF_STATUS_SUCCESS for success otherwise failure 3604 */ 3605 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle, 3606 wmi_bcn_send_from_host_cmd_fixed_param *param) 3607 { 3608 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 3609 wmi_buf_t wmi_buf; 3610 QDF_STATUS ret; 3611 3612 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 3613 if (!wmi_buf) 3614 return QDF_STATUS_E_FAILURE; 3615 3616 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 3617 WMITLV_SET_HDR(&cmd->tlv_header, 3618 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 3619 WMITLV_GET_STRUCT_TLVLEN 3620 (wmi_bcn_send_from_host_cmd_fixed_param)); 3621 cmd->vdev_id = param->vdev_id; 3622 cmd->data_len = param->data_len; 3623 cmd->frame_ctrl = param->frame_ctrl; 3624 cmd->frag_ptr = param->frag_ptr; 3625 cmd->dtim_flag = param->dtim_flag; 3626 3627 wmi_mtrace(WMI_PDEV_SEND_BCN_CMDID, cmd->vdev_id, 0); 3628 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 3629 WMI_PDEV_SEND_BCN_CMDID); 3630 3631 if (QDF_IS_STATUS_ERROR(ret)) { 3632 WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command"); 3633 wmi_buf_free(wmi_buf); 3634 } 3635 3636 return ret; 3637 } 3638 #endif /* CONFIG_MCL */ 3639 3640 /** 3641 * send_process_update_edca_param_cmd_tlv() - update EDCA params 3642 * @wmi_handle: wmi handle 3643 * @vdev_id: vdev id. 3644 * @wmm_vparams: edca parameters 3645 * 3646 * This function updates EDCA parameters to the target 3647 * 3648 * Return: CDF Status 3649 */ 3650 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 3651 uint8_t vdev_id, bool mu_edca_param, 3652 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 3653 { 3654 uint8_t *buf_ptr; 3655 wmi_buf_t buf; 3656 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 3657 wmi_wmm_vparams *wmm_param; 3658 struct wmi_host_wme_vparams *twmm_param; 3659 int len = sizeof(*cmd); 3660 int ac; 3661 3662 buf = wmi_buf_alloc(wmi_handle, len); 3663 3664 if (!buf) 3665 return QDF_STATUS_E_NOMEM; 3666 3667 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3668 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 3669 WMITLV_SET_HDR(&cmd->tlv_header, 3670 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 3671 WMITLV_GET_STRUCT_TLVLEN 3672 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 3673 cmd->vdev_id = vdev_id; 3674 cmd->wmm_param_type = mu_edca_param; 3675 3676 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 3677 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 3678 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 3679 WMITLV_SET_HDR(&wmm_param->tlv_header, 3680 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 3681 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 3682 wmm_param->cwmin = twmm_param->cwmin; 3683 wmm_param->cwmax = twmm_param->cwmax; 3684 wmm_param->aifs = twmm_param->aifs; 3685 if (mu_edca_param) 3686 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 3687 else 3688 wmm_param->txoplimit = twmm_param->txoplimit; 3689 wmm_param->acm = twmm_param->acm; 3690 wmm_param->no_ack = twmm_param->noackpolicy; 3691 } 3692 3693 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 3694 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3695 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 3696 goto fail; 3697 3698 return QDF_STATUS_SUCCESS; 3699 3700 fail: 3701 wmi_buf_free(buf); 3702 WMI_LOGE("%s: Failed to set WMM Paremeters", __func__); 3703 return QDF_STATUS_E_FAILURE; 3704 } 3705 3706 /** 3707 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 3708 * @wmi_handle: wmi handle 3709 * @vdev_id: vdev id 3710 * @probe_rsp_info: probe response info 3711 * 3712 * Return: QDF_STATUS_SUCCESS for success or error code 3713 */ 3714 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 3715 uint8_t vdev_id, 3716 struct wmi_probe_resp_params *probe_rsp_info) 3717 { 3718 wmi_prb_tmpl_cmd_fixed_param *cmd; 3719 wmi_bcn_prb_info *bcn_prb_info; 3720 wmi_buf_t wmi_buf; 3721 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 3722 uint8_t *buf_ptr; 3723 QDF_STATUS ret; 3724 3725 WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id); 3726 3727 tmpl_len = probe_rsp_info->prb_rsp_template_len; 3728 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 3729 3730 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 3731 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 3732 tmpl_len_aligned; 3733 3734 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 3735 WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"), 3736 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 3737 return QDF_STATUS_E_INVAL; 3738 } 3739 3740 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3741 if (!wmi_buf) 3742 return QDF_STATUS_E_NOMEM; 3743 3744 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3745 3746 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 3747 WMITLV_SET_HDR(&cmd->tlv_header, 3748 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 3749 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 3750 cmd->vdev_id = vdev_id; 3751 cmd->buf_len = tmpl_len; 3752 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 3753 3754 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 3755 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 3756 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 3757 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 3758 bcn_prb_info->caps = 0; 3759 bcn_prb_info->erp = 0; 3760 buf_ptr += sizeof(wmi_bcn_prb_info); 3761 3762 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 3763 buf_ptr += WMI_TLV_HDR_SIZE; 3764 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 3765 3766 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 3767 ret = wmi_unified_cmd_send(wmi_handle, 3768 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 3769 if (QDF_IS_STATUS_ERROR(ret)) { 3770 WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret); 3771 wmi_buf_free(wmi_buf); 3772 } 3773 3774 return ret; 3775 } 3776 3777 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 3778 #define WPI_IV_LEN 16 3779 3780 /** 3781 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 3782 * 3783 * @dest_tx: destination address of tsc key counter 3784 * @src_tx: source address of tsc key counter 3785 * @dest_rx: destination address of rsc key counter 3786 * @src_rx: source address of rsc key counter 3787 * 3788 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 3789 * 3790 * Return: None 3791 * 3792 */ 3793 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 3794 uint8_t *dest_rx, uint8_t *src_rx) 3795 { 3796 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 3797 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 3798 } 3799 #else 3800 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 3801 uint8_t *dest_rx, uint8_t *src_rx) 3802 { 3803 return; 3804 } 3805 #endif 3806 3807 /** 3808 * send_setup_install_key_cmd_tlv() - set key parameters 3809 * @wmi_handle: wmi handle 3810 * @key_params: key parameters 3811 * 3812 * This function fills structure from information 3813 * passed in key_params. 3814 * 3815 * Return: QDF_STATUS_SUCCESS - success 3816 * QDF_STATUS_E_FAILURE - failure 3817 * QDF_STATUS_E_NOMEM - not able to allocate buffer 3818 */ 3819 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 3820 struct set_key_params *key_params) 3821 { 3822 wmi_vdev_install_key_cmd_fixed_param *cmd; 3823 wmi_buf_t buf; 3824 uint8_t *buf_ptr; 3825 uint32_t len; 3826 uint8_t *key_data; 3827 QDF_STATUS status; 3828 3829 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 3830 WMI_TLV_HDR_SIZE; 3831 3832 buf = wmi_buf_alloc(wmi_handle, len); 3833 if (!buf) 3834 return QDF_STATUS_E_NOMEM; 3835 3836 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3837 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 3838 WMITLV_SET_HDR(&cmd->tlv_header, 3839 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 3840 WMITLV_GET_STRUCT_TLVLEN 3841 (wmi_vdev_install_key_cmd_fixed_param)); 3842 cmd->vdev_id = key_params->vdev_id; 3843 cmd->key_ix = key_params->key_idx; 3844 3845 3846 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 3847 cmd->key_flags |= key_params->key_flags; 3848 cmd->key_cipher = key_params->key_cipher; 3849 if ((key_params->key_txmic_len) && 3850 (key_params->key_rxmic_len)) { 3851 cmd->key_txmic_len = key_params->key_txmic_len; 3852 cmd->key_rxmic_len = key_params->key_rxmic_len; 3853 } 3854 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 3855 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 3856 key_params->tx_iv, 3857 cmd->wpi_key_rsc_counter, 3858 key_params->rx_iv); 3859 #endif 3860 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 3861 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3862 roundup(key_params->key_len, sizeof(uint32_t))); 3863 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3864 qdf_mem_copy((void *)key_data, 3865 (const void *)key_params->key_data, key_params->key_len); 3866 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_ctr, 3867 sizeof(wmi_key_seq_counter)); 3868 cmd->key_len = key_params->key_len; 3869 3870 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 3871 status = wmi_unified_cmd_send(wmi_handle, buf, len, 3872 WMI_VDEV_INSTALL_KEY_CMDID); 3873 if (QDF_IS_STATUS_ERROR(status)) 3874 wmi_buf_free(buf); 3875 3876 return status; 3877 } 3878 3879 /** 3880 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 3881 * @wmi_handle: wmi handle 3882 * @vdev_id: vdev id 3883 * @p2p_ie: p2p IE 3884 * 3885 * Return: QDF_STATUS_SUCCESS for success or error code 3886 */ 3887 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 3888 uint32_t vdev_id, uint8_t *p2p_ie) 3889 { 3890 QDF_STATUS ret; 3891 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 3892 wmi_buf_t wmi_buf; 3893 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 3894 uint8_t *buf_ptr; 3895 3896 ie_len = (uint32_t) (p2p_ie[1] + 2); 3897 3898 /* More than one P2P IE may be included in a single frame. 3899 If multiple P2P IEs are present, the complete P2P attribute 3900 data consists of the concatenation of the P2P Attribute 3901 fields of the P2P IEs. The P2P Attributes field of each 3902 P2P IE may be any length up to the maximum (251 octets). 3903 In this case host sends one P2P IE to firmware so the length 3904 should not exceed more than 251 bytes 3905 */ 3906 if (ie_len > 251) { 3907 WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len); 3908 return QDF_STATUS_E_INVAL; 3909 } 3910 3911 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 3912 3913 wmi_buf_len = 3914 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 3915 WMI_TLV_HDR_SIZE; 3916 3917 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3918 if (!wmi_buf) 3919 return QDF_STATUS_E_NOMEM; 3920 3921 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3922 3923 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 3924 WMITLV_SET_HDR(&cmd->tlv_header, 3925 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 3926 WMITLV_GET_STRUCT_TLVLEN 3927 (wmi_p2p_go_set_beacon_ie_fixed_param)); 3928 cmd->vdev_id = vdev_id; 3929 cmd->ie_buf_len = ie_len; 3930 3931 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 3932 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 3933 buf_ptr += WMI_TLV_HDR_SIZE; 3934 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 3935 3936 WMI_LOGD("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__); 3937 3938 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 3939 ret = wmi_unified_cmd_send(wmi_handle, 3940 wmi_buf, wmi_buf_len, 3941 WMI_P2P_GO_SET_BEACON_IE); 3942 if (QDF_IS_STATUS_ERROR(ret)) { 3943 WMI_LOGE("Failed to send bcn tmpl: %d", ret); 3944 wmi_buf_free(wmi_buf); 3945 } 3946 3947 WMI_LOGD("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__); 3948 return ret; 3949 } 3950 3951 /** 3952 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 3953 * @wmi_handle: wmi handle 3954 * @psetoui: OUI parameters 3955 * 3956 * set scan probe OUI parameters in firmware 3957 * 3958 * Return: CDF status 3959 */ 3960 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 3961 struct scan_mac_oui *psetoui) 3962 { 3963 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 3964 wmi_buf_t wmi_buf; 3965 uint32_t len; 3966 uint8_t *buf_ptr; 3967 uint32_t *oui_buf; 3968 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 3969 3970 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3971 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 3972 3973 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3974 if (!wmi_buf) 3975 return QDF_STATUS_E_NOMEM; 3976 3977 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3978 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 3979 WMITLV_SET_HDR(&cmd->tlv_header, 3980 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 3981 WMITLV_GET_STRUCT_TLVLEN 3982 (wmi_scan_prob_req_oui_cmd_fixed_param)); 3983 3984 oui_buf = &cmd->prob_req_oui; 3985 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 3986 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 3987 | psetoui->oui[2]; 3988 WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__, 3989 cmd->prob_req_oui); 3990 3991 cmd->vdev_id = psetoui->vdev_id; 3992 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 3993 if (psetoui->enb_probe_req_sno_randomization) 3994 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 3995 3996 if (ie_whitelist->white_list) { 3997 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 3998 &cmd->num_vendor_oui, 3999 ie_whitelist); 4000 cmd->flags |= 4001 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 4002 } 4003 4004 buf_ptr += sizeof(*cmd); 4005 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4006 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4007 buf_ptr += WMI_TLV_HDR_SIZE; 4008 4009 if (cmd->num_vendor_oui != 0) { 4010 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4011 ie_whitelist->voui); 4012 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4013 } 4014 4015 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 4016 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4017 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 4018 WMI_LOGE("%s: failed to send command", __func__); 4019 wmi_buf_free(wmi_buf); 4020 return QDF_STATUS_E_FAILURE; 4021 } 4022 return QDF_STATUS_SUCCESS; 4023 } 4024 4025 #ifdef IPA_OFFLOAD 4026 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 4027 * @wmi_handle: wmi handle 4028 * @ipa_offload: ipa offload control parameter 4029 * 4030 * Returns: 0 on success, error number otherwise 4031 */ 4032 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 4033 struct ipa_uc_offload_control_params *ipa_offload) 4034 { 4035 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 4036 wmi_buf_t wmi_buf; 4037 uint32_t len; 4038 u_int8_t *buf_ptr; 4039 4040 len = sizeof(*cmd); 4041 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4042 if (!wmi_buf) 4043 return QDF_STATUS_E_NOMEM; 4044 4045 WMI_LOGD("%s: offload_type=%d, enable=%d", __func__, 4046 ipa_offload->offload_type, ipa_offload->enable); 4047 4048 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 4049 4050 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 4051 WMITLV_SET_HDR(&cmd->tlv_header, 4052 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 4053 WMITLV_GET_STRUCT_TLVLEN( 4054 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 4055 4056 cmd->offload_type = ipa_offload->offload_type; 4057 cmd->vdev_id = ipa_offload->vdev_id; 4058 cmd->enable = ipa_offload->enable; 4059 4060 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 4061 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4062 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 4063 WMI_LOGE("%s: failed to command", __func__); 4064 wmi_buf_free(wmi_buf); 4065 return QDF_STATUS_E_FAILURE; 4066 } 4067 4068 return QDF_STATUS_SUCCESS; 4069 } 4070 #endif 4071 4072 /** 4073 * send_pno_stop_cmd_tlv() - PNO stop request 4074 * @wmi_handle: wmi handle 4075 * @vdev_id: vdev id 4076 * 4077 * This function request FW to stop ongoing PNO operation. 4078 * 4079 * Return: CDF status 4080 */ 4081 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 4082 { 4083 wmi_nlo_config_cmd_fixed_param *cmd; 4084 int32_t len = sizeof(*cmd); 4085 wmi_buf_t buf; 4086 uint8_t *buf_ptr; 4087 int ret; 4088 4089 /* 4090 * TLV place holder for array of structures nlo_configured_parameters 4091 * TLV place holder for array of uint32_t channel_list 4092 * TLV place holder for chnl prediction cfg 4093 */ 4094 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 4095 buf = wmi_buf_alloc(wmi_handle, len); 4096 if (!buf) 4097 return QDF_STATUS_E_NOMEM; 4098 4099 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 4100 buf_ptr = (uint8_t *) cmd; 4101 4102 WMITLV_SET_HDR(&cmd->tlv_header, 4103 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 4104 WMITLV_GET_STRUCT_TLVLEN 4105 (wmi_nlo_config_cmd_fixed_param)); 4106 4107 cmd->vdev_id = vdev_id; 4108 cmd->flags = WMI_NLO_CONFIG_STOP; 4109 buf_ptr += sizeof(*cmd); 4110 4111 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 4112 buf_ptr += WMI_TLV_HDR_SIZE; 4113 4114 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 4115 buf_ptr += WMI_TLV_HDR_SIZE; 4116 4117 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 4118 buf_ptr += WMI_TLV_HDR_SIZE; 4119 4120 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 4121 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4122 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 4123 if (ret) { 4124 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 4125 wmi_buf_free(buf); 4126 return QDF_STATUS_E_FAILURE; 4127 } 4128 4129 return QDF_STATUS_SUCCESS; 4130 } 4131 4132 /** 4133 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 4134 * @buf_ptr: Buffer passed by upper layers 4135 * @pno: Buffer to be sent to the firmware 4136 * 4137 * Copy the PNO Channel prediction configuration parameters 4138 * passed by the upper layers to a WMI format TLV and send it 4139 * down to the firmware. 4140 * 4141 * Return: None 4142 */ 4143 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 4144 struct pno_scan_req_params *pno) 4145 { 4146 nlo_channel_prediction_cfg *channel_prediction_cfg = 4147 (nlo_channel_prediction_cfg *) buf_ptr; 4148 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 4149 WMITLV_TAG_ARRAY_BYTE, 4150 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 4151 #ifdef FEATURE_WLAN_SCAN_PNO 4152 channel_prediction_cfg->enable = pno->pno_channel_prediction; 4153 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 4154 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 4155 channel_prediction_cfg->full_scan_period_ms = 4156 pno->channel_prediction_full_scan; 4157 #endif 4158 buf_ptr += sizeof(nlo_channel_prediction_cfg); 4159 WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 4160 channel_prediction_cfg->enable, 4161 channel_prediction_cfg->top_k_num, 4162 channel_prediction_cfg->stationary_threshold, 4163 channel_prediction_cfg->full_scan_period_ms); 4164 } 4165 4166 /** 4167 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 4168 * @wmi_handle: wmi handle 4169 * @params: configuration parameters 4170 * 4171 * Return: QDF_STATUS 4172 */ 4173 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 4174 struct nlo_mawc_params *params) 4175 { 4176 wmi_buf_t buf = NULL; 4177 QDF_STATUS status; 4178 int len; 4179 uint8_t *buf_ptr; 4180 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 4181 4182 len = sizeof(*wmi_nlo_mawc_params); 4183 buf = wmi_buf_alloc(wmi_handle, len); 4184 if (!buf) 4185 return QDF_STATUS_E_NOMEM; 4186 4187 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4188 wmi_nlo_mawc_params = 4189 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 4190 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 4191 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 4192 WMITLV_GET_STRUCT_TLVLEN 4193 (wmi_nlo_configure_mawc_cmd_fixed_param)); 4194 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 4195 if (params->enable) 4196 wmi_nlo_mawc_params->enable = 1; 4197 else 4198 wmi_nlo_mawc_params->enable = 0; 4199 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 4200 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 4201 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 4202 WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"), 4203 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 4204 wmi_nlo_mawc_params->exp_backoff_ratio, 4205 wmi_nlo_mawc_params->init_scan_interval, 4206 wmi_nlo_mawc_params->max_scan_interval); 4207 4208 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 4209 status = wmi_unified_cmd_send(wmi_handle, buf, 4210 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 4211 if (QDF_IS_STATUS_ERROR(status)) { 4212 WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 4213 status); 4214 wmi_buf_free(buf); 4215 return QDF_STATUS_E_FAILURE; 4216 } 4217 4218 return QDF_STATUS_SUCCESS; 4219 } 4220 4221 /** 4222 * send_pno_start_cmd_tlv() - PNO start request 4223 * @wmi_handle: wmi handle 4224 * @pno: PNO request 4225 * 4226 * This function request FW to start PNO request. 4227 * Request: CDF status 4228 */ 4229 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 4230 struct pno_scan_req_params *pno) 4231 { 4232 wmi_nlo_config_cmd_fixed_param *cmd; 4233 nlo_configured_parameters *nlo_list; 4234 uint32_t *channel_list; 4235 int32_t len; 4236 wmi_buf_t buf; 4237 uint8_t *buf_ptr; 4238 uint8_t i; 4239 int ret; 4240 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 4241 connected_nlo_rssi_params *nlo_relative_rssi; 4242 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 4243 4244 /* 4245 * TLV place holder for array nlo_configured_parameters(nlo_list) 4246 * TLV place holder for array of uint32_t channel_list 4247 * TLV place holder for chnnl prediction cfg 4248 * TLV place holder for array of wmi_vendor_oui 4249 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 4250 */ 4251 len = sizeof(*cmd) + 4252 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 4253 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 4254 4255 len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt, 4256 WMI_NLO_MAX_CHAN); 4257 len += sizeof(nlo_configured_parameters) * 4258 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 4259 len += sizeof(nlo_channel_prediction_cfg); 4260 len += sizeof(enlo_candidate_score_params); 4261 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 4262 len += sizeof(connected_nlo_rssi_params); 4263 len += sizeof(connected_nlo_bss_band_rssi_pref); 4264 4265 buf = wmi_buf_alloc(wmi_handle, len); 4266 if (!buf) 4267 return QDF_STATUS_E_NOMEM; 4268 4269 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 4270 4271 buf_ptr = (uint8_t *) cmd; 4272 WMITLV_SET_HDR(&cmd->tlv_header, 4273 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 4274 WMITLV_GET_STRUCT_TLVLEN 4275 (wmi_nlo_config_cmd_fixed_param)); 4276 cmd->vdev_id = pno->vdev_id; 4277 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 4278 4279 #ifdef FEATURE_WLAN_SCAN_PNO 4280 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 4281 pno->adaptive_dwell_mode); 4282 #endif 4283 /* Current FW does not support min-max range for dwell time */ 4284 cmd->active_dwell_time = pno->active_dwell_time; 4285 cmd->passive_dwell_time = pno->passive_dwell_time; 4286 4287 if (pno->do_passive_scan) 4288 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 4289 /* Copy scan interval */ 4290 cmd->fast_scan_period = pno->fast_scan_period; 4291 cmd->slow_scan_period = pno->slow_scan_period; 4292 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 4293 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 4294 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 4295 WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec", 4296 cmd->fast_scan_period, cmd->slow_scan_period); 4297 WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles); 4298 4299 /* mac randomization attributes */ 4300 if (pno->scan_random.randomize) { 4301 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 4302 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 4303 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 4304 pno->scan_random.mac_mask, 4305 &cmd->mac_addr, 4306 &cmd->mac_mask); 4307 } 4308 4309 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 4310 4311 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 4312 WMI_LOGD("SSID count : %d", cmd->no_of_ssids); 4313 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4314 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 4315 buf_ptr += WMI_TLV_HDR_SIZE; 4316 4317 nlo_list = (nlo_configured_parameters *) buf_ptr; 4318 for (i = 0; i < cmd->no_of_ssids; i++) { 4319 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 4320 WMITLV_TAG_ARRAY_BYTE, 4321 WMITLV_GET_STRUCT_TLVLEN 4322 (nlo_configured_parameters)); 4323 /* Copy ssid and it's length */ 4324 nlo_list[i].ssid.valid = true; 4325 nlo_list[i].ssid.ssid.ssid_len = 4326 pno->networks_list[i].ssid.length; 4327 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 4328 pno->networks_list[i].ssid.ssid, 4329 nlo_list[i].ssid.ssid.ssid_len); 4330 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 4331 nlo_list[i].ssid.ssid.ssid_len, 4332 (char *)nlo_list[i].ssid.ssid.ssid, 4333 nlo_list[i].ssid.ssid.ssid_len); 4334 4335 /* Copy rssi threshold */ 4336 if (pno->networks_list[i].rssi_thresh && 4337 pno->networks_list[i].rssi_thresh > 4338 WMI_RSSI_THOLD_DEFAULT) { 4339 nlo_list[i].rssi_cond.valid = true; 4340 nlo_list[i].rssi_cond.rssi = 4341 pno->networks_list[i].rssi_thresh; 4342 WMI_LOGD("RSSI threshold : %d dBm", 4343 nlo_list[i].rssi_cond.rssi); 4344 } 4345 nlo_list[i].bcast_nw_type.valid = true; 4346 nlo_list[i].bcast_nw_type.bcast_nw_type = 4347 pno->networks_list[i].bc_new_type; 4348 WMI_LOGD("Broadcast NW type (%u)", 4349 nlo_list[i].bcast_nw_type.bcast_nw_type); 4350 } 4351 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 4352 4353 /* Copy channel info */ 4354 cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt, 4355 WMI_NLO_MAX_CHAN); 4356 WMI_LOGD("Channel count: %d", cmd->num_of_channels); 4357 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 4358 (cmd->num_of_channels * sizeof(uint32_t))); 4359 buf_ptr += WMI_TLV_HDR_SIZE; 4360 4361 channel_list = (uint32_t *) buf_ptr; 4362 for (i = 0; i < cmd->num_of_channels; i++) { 4363 channel_list[i] = pno->networks_list[0].channels[i]; 4364 4365 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 4366 channel_list[i] = 4367 wlan_chan_to_freq(pno-> 4368 networks_list[0].channels[i]); 4369 4370 WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]); 4371 } 4372 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 4373 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4374 sizeof(nlo_channel_prediction_cfg)); 4375 buf_ptr += WMI_TLV_HDR_SIZE; 4376 wmi_set_pno_channel_prediction(buf_ptr, pno); 4377 buf_ptr += sizeof(nlo_channel_prediction_cfg); 4378 /** TODO: Discrete firmware doesn't have command/option to configure 4379 * App IE which comes from wpa_supplicant as of part PNO start request. 4380 */ 4381 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 4382 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 4383 buf_ptr += sizeof(enlo_candidate_score_params); 4384 4385 if (ie_whitelist->white_list) { 4386 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 4387 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 4388 &cmd->num_vendor_oui, 4389 ie_whitelist); 4390 } 4391 4392 /* ie white list */ 4393 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4394 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4395 buf_ptr += WMI_TLV_HDR_SIZE; 4396 if (cmd->num_vendor_oui != 0) { 4397 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4398 ie_whitelist->voui); 4399 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4400 } 4401 4402 if (pno->relative_rssi_set) 4403 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 4404 4405 /* 4406 * Firmware calculation using connected PNO params: 4407 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 4408 * deduction of rssi_pref for chosen band_pref and 4409 * addition of rssi_pref for remaining bands (other than chosen band). 4410 */ 4411 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 4412 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 4413 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 4414 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 4415 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 4416 WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi); 4417 buf_ptr += sizeof(*nlo_relative_rssi); 4418 4419 /* 4420 * As of now Kernel and Host supports one band and rssi preference. 4421 * Firmware supports array of band and rssi preferences 4422 */ 4423 cmd->num_cnlo_band_pref = 1; 4424 WMITLV_SET_HDR(buf_ptr, 4425 WMITLV_TAG_ARRAY_STRUC, 4426 cmd->num_cnlo_band_pref * 4427 sizeof(connected_nlo_bss_band_rssi_pref)); 4428 buf_ptr += WMI_TLV_HDR_SIZE; 4429 4430 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 4431 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 4432 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 4433 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 4434 WMITLV_GET_STRUCT_TLVLEN( 4435 connected_nlo_bss_band_rssi_pref)); 4436 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 4437 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 4438 WMI_LOGI("band_pref %d, rssi_pref %d", 4439 nlo_band_rssi[i].band, 4440 nlo_band_rssi[i].rssi_pref); 4441 } 4442 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 4443 4444 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 4445 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4446 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 4447 if (ret) { 4448 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 4449 wmi_buf_free(buf); 4450 return QDF_STATUS_E_FAILURE; 4451 } 4452 4453 return QDF_STATUS_SUCCESS; 4454 } 4455 4456 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 4457 /** 4458 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 4459 * @wmi_handle: wmi handle 4460 * @clear_req: ll stats clear request command params 4461 * 4462 * Return: QDF_STATUS_SUCCESS for success or error code 4463 */ 4464 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 4465 const struct ll_stats_clear_params *clear_req, 4466 uint8_t addr[IEEE80211_ADDR_LEN]) 4467 { 4468 wmi_clear_link_stats_cmd_fixed_param *cmd; 4469 int32_t len; 4470 wmi_buf_t buf; 4471 uint8_t *buf_ptr; 4472 int ret; 4473 4474 len = sizeof(*cmd); 4475 buf = wmi_buf_alloc(wmi_handle, len); 4476 4477 if (!buf) 4478 return QDF_STATUS_E_NOMEM; 4479 4480 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4481 qdf_mem_zero(buf_ptr, len); 4482 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 4483 4484 WMITLV_SET_HDR(&cmd->tlv_header, 4485 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 4486 WMITLV_GET_STRUCT_TLVLEN 4487 (wmi_clear_link_stats_cmd_fixed_param)); 4488 4489 cmd->stop_stats_collection_req = clear_req->stop_req; 4490 cmd->vdev_id = clear_req->sta_id; 4491 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 4492 4493 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 4494 &cmd->peer_macaddr); 4495 4496 WMI_LOGD("LINK_LAYER_STATS - Clear Request Params"); 4497 WMI_LOGD("StopReq : %d", cmd->stop_stats_collection_req); 4498 WMI_LOGD("Vdev Id : %d", cmd->vdev_id); 4499 WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask); 4500 /* WMI_LOGD("Peer MAC Addr : %pM", 4501 cmd->peer_macaddr); */ 4502 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 4503 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4504 WMI_CLEAR_LINK_STATS_CMDID); 4505 if (ret) { 4506 WMI_LOGE("%s: Failed to send clear link stats req", __func__); 4507 wmi_buf_free(buf); 4508 return QDF_STATUS_E_FAILURE; 4509 } 4510 4511 WMI_LOGD("Clear Link Layer Stats request sent successfully"); 4512 return QDF_STATUS_SUCCESS; 4513 } 4514 4515 /** 4516 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 4517 * @wmi_handle: wmi handle 4518 * @setReq: ll stats set request command params 4519 * 4520 * Return: QDF_STATUS_SUCCESS for success or error code 4521 */ 4522 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 4523 const struct ll_stats_set_params *set_req) 4524 { 4525 wmi_start_link_stats_cmd_fixed_param *cmd; 4526 int32_t len; 4527 wmi_buf_t buf; 4528 uint8_t *buf_ptr; 4529 int ret; 4530 4531 len = sizeof(*cmd); 4532 buf = wmi_buf_alloc(wmi_handle, len); 4533 4534 if (!buf) 4535 return QDF_STATUS_E_NOMEM; 4536 4537 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4538 qdf_mem_zero(buf_ptr, len); 4539 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 4540 4541 WMITLV_SET_HDR(&cmd->tlv_header, 4542 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 4543 WMITLV_GET_STRUCT_TLVLEN 4544 (wmi_start_link_stats_cmd_fixed_param)); 4545 4546 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 4547 cmd->aggressive_statistics_gathering = 4548 set_req->aggressive_statistics_gathering; 4549 4550 WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params"); 4551 WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold); 4552 WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering); 4553 4554 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 4555 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4556 WMI_START_LINK_STATS_CMDID); 4557 if (ret) { 4558 WMI_LOGE("%s: Failed to send set link stats request", __func__); 4559 wmi_buf_free(buf); 4560 return QDF_STATUS_E_FAILURE; 4561 } 4562 4563 return QDF_STATUS_SUCCESS; 4564 } 4565 4566 /** 4567 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 4568 * @wmi_handle:wmi handle 4569 * @get_req:ll stats get request command params 4570 * @addr: mac address 4571 * 4572 * Return: QDF_STATUS_SUCCESS for success or error code 4573 */ 4574 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 4575 const struct ll_stats_get_params *get_req, 4576 uint8_t addr[IEEE80211_ADDR_LEN]) 4577 { 4578 wmi_request_link_stats_cmd_fixed_param *cmd; 4579 int32_t len; 4580 wmi_buf_t buf; 4581 uint8_t *buf_ptr; 4582 int ret; 4583 4584 len = sizeof(*cmd); 4585 buf = wmi_buf_alloc(wmi_handle, len); 4586 4587 if (!buf) 4588 return QDF_STATUS_E_NOMEM; 4589 4590 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4591 qdf_mem_zero(buf_ptr, len); 4592 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 4593 4594 WMITLV_SET_HDR(&cmd->tlv_header, 4595 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 4596 WMITLV_GET_STRUCT_TLVLEN 4597 (wmi_request_link_stats_cmd_fixed_param)); 4598 4599 cmd->request_id = get_req->req_id; 4600 cmd->stats_type = get_req->param_id_mask; 4601 cmd->vdev_id = get_req->sta_id; 4602 4603 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 4604 &cmd->peer_macaddr); 4605 4606 WMI_LOGD("LINK_LAYER_STATS - Get Request Params"); 4607 WMI_LOGD("Request ID : %u", cmd->request_id); 4608 WMI_LOGD("Stats Type : %0x", cmd->stats_type); 4609 WMI_LOGD("Vdev ID : %d", cmd->vdev_id); 4610 WMI_LOGD("Peer MAC Addr : %pM", addr); 4611 4612 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 4613 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4614 WMI_REQUEST_LINK_STATS_CMDID); 4615 if (ret) { 4616 WMI_LOGE("%s: Failed to send get link stats request", __func__); 4617 wmi_buf_free(buf); 4618 return QDF_STATUS_E_FAILURE; 4619 } 4620 4621 return QDF_STATUS_SUCCESS; 4622 } 4623 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 4624 4625 /** 4626 * send_congestion_cmd_tlv() - send request to fw to get CCA 4627 * @wmi_handle: wmi handle 4628 * @vdev_id: vdev id 4629 * 4630 * Return: CDF status 4631 */ 4632 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 4633 uint8_t vdev_id) 4634 { 4635 wmi_buf_t buf; 4636 wmi_request_stats_cmd_fixed_param *cmd; 4637 uint8_t len; 4638 uint8_t *buf_ptr; 4639 4640 len = sizeof(*cmd); 4641 buf = wmi_buf_alloc(wmi_handle, len); 4642 if (!buf) 4643 return QDF_STATUS_E_FAILURE; 4644 4645 buf_ptr = wmi_buf_data(buf); 4646 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 4647 WMITLV_SET_HDR(&cmd->tlv_header, 4648 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 4649 WMITLV_GET_STRUCT_TLVLEN 4650 (wmi_request_stats_cmd_fixed_param)); 4651 4652 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 4653 cmd->vdev_id = vdev_id; 4654 WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->", 4655 cmd->vdev_id, cmd->stats_id); 4656 4657 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 4658 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4659 WMI_REQUEST_STATS_CMDID)) { 4660 WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", 4661 __func__); 4662 wmi_buf_free(buf); 4663 return QDF_STATUS_E_FAILURE; 4664 } 4665 4666 return QDF_STATUS_SUCCESS; 4667 } 4668 4669 /** 4670 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 4671 * @wmi_handle: wmi handle 4672 * @rssi_req: get RSSI request 4673 * 4674 * Return: CDF status 4675 */ 4676 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 4677 { 4678 wmi_buf_t buf; 4679 wmi_request_stats_cmd_fixed_param *cmd; 4680 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 4681 4682 buf = wmi_buf_alloc(wmi_handle, len); 4683 if (!buf) 4684 return QDF_STATUS_E_FAILURE; 4685 4686 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 4687 WMITLV_SET_HDR(&cmd->tlv_header, 4688 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 4689 WMITLV_GET_STRUCT_TLVLEN 4690 (wmi_request_stats_cmd_fixed_param)); 4691 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 4692 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 4693 if (wmi_unified_cmd_send 4694 (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) { 4695 WMI_LOGE("Failed to send host stats request to fw"); 4696 wmi_buf_free(buf); 4697 return QDF_STATUS_E_FAILURE; 4698 } 4699 4700 return QDF_STATUS_SUCCESS; 4701 } 4702 4703 /** 4704 * send_snr_cmd_tlv() - get RSSI from fw 4705 * @wmi_handle: wmi handle 4706 * @vdev_id: vdev id 4707 * 4708 * Return: CDF status 4709 */ 4710 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 4711 { 4712 wmi_buf_t buf; 4713 wmi_request_stats_cmd_fixed_param *cmd; 4714 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 4715 4716 buf = wmi_buf_alloc(wmi_handle, len); 4717 if (!buf) 4718 return QDF_STATUS_E_FAILURE; 4719 4720 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 4721 cmd->vdev_id = vdev_id; 4722 4723 WMITLV_SET_HDR(&cmd->tlv_header, 4724 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 4725 WMITLV_GET_STRUCT_TLVLEN 4726 (wmi_request_stats_cmd_fixed_param)); 4727 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 4728 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 4729 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4730 WMI_REQUEST_STATS_CMDID)) { 4731 WMI_LOGE("Failed to send host stats request to fw"); 4732 wmi_buf_free(buf); 4733 return QDF_STATUS_E_FAILURE; 4734 } 4735 4736 return QDF_STATUS_SUCCESS; 4737 } 4738 4739 /** 4740 * send_link_status_req_cmd_tlv() - process link status request from UMAC 4741 * @wmi_handle: wmi handle 4742 * @link_status: get link params 4743 * 4744 * Return: CDF status 4745 */ 4746 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 4747 struct link_status_params *link_status) 4748 { 4749 wmi_buf_t buf; 4750 wmi_request_stats_cmd_fixed_param *cmd; 4751 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 4752 4753 buf = wmi_buf_alloc(wmi_handle, len); 4754 if (!buf) 4755 return QDF_STATUS_E_FAILURE; 4756 4757 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 4758 WMITLV_SET_HDR(&cmd->tlv_header, 4759 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 4760 WMITLV_GET_STRUCT_TLVLEN 4761 (wmi_request_stats_cmd_fixed_param)); 4762 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 4763 cmd->vdev_id = link_status->vdev_id; 4764 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 4765 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4766 WMI_REQUEST_STATS_CMDID)) { 4767 WMI_LOGE("Failed to send WMI link status request to fw"); 4768 wmi_buf_free(buf); 4769 return QDF_STATUS_E_FAILURE; 4770 } 4771 4772 return QDF_STATUS_SUCCESS; 4773 } 4774 4775 #ifdef WLAN_SUPPORT_GREEN_AP 4776 /** 4777 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 4778 * @wmi_handle: wmi handler 4779 * @egap_params: pointer to egap_params 4780 * 4781 * Return: 0 for success, otherwise appropriate error code 4782 */ 4783 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 4784 struct wlan_green_ap_egap_params *egap_params) 4785 { 4786 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 4787 wmi_buf_t buf; 4788 int32_t err; 4789 4790 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4791 if (!buf) 4792 return QDF_STATUS_E_NOMEM; 4793 4794 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 4795 WMITLV_SET_HDR(&cmd->tlv_header, 4796 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 4797 WMITLV_GET_STRUCT_TLVLEN( 4798 wmi_ap_ps_egap_param_cmd_fixed_param)); 4799 4800 cmd->enable = egap_params->host_enable_egap; 4801 cmd->inactivity_time = egap_params->egap_inactivity_time; 4802 cmd->wait_time = egap_params->egap_wait_time; 4803 cmd->flags = egap_params->egap_feature_flags; 4804 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 4805 err = wmi_unified_cmd_send(wmi_handle, buf, 4806 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 4807 if (err) { 4808 WMI_LOGE("Failed to send ap_ps_egap cmd"); 4809 wmi_buf_free(buf); 4810 return QDF_STATUS_E_FAILURE; 4811 } 4812 4813 return QDF_STATUS_SUCCESS; 4814 } 4815 #endif 4816 4817 /** 4818 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 4819 * @wmi_handle: wmi handle 4820 * @vdev_id: vdev id 4821 * 4822 * Return: QDF_STATUS_SUCCESS for success or error code 4823 */ 4824 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 4825 uint8_t vdev_id) 4826 { 4827 wmi_csa_offload_enable_cmd_fixed_param *cmd; 4828 wmi_buf_t buf; 4829 int32_t len = sizeof(*cmd); 4830 4831 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 4832 buf = wmi_buf_alloc(wmi_handle, len); 4833 if (!buf) 4834 return QDF_STATUS_E_NOMEM; 4835 4836 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 4837 WMITLV_SET_HDR(&cmd->tlv_header, 4838 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 4839 WMITLV_GET_STRUCT_TLVLEN 4840 (wmi_csa_offload_enable_cmd_fixed_param)); 4841 cmd->vdev_id = vdev_id; 4842 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 4843 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 4844 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4845 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 4846 WMI_LOGP("%s: Failed to send CSA offload enable command", 4847 __func__); 4848 wmi_buf_free(buf); 4849 return QDF_STATUS_E_FAILURE; 4850 } 4851 4852 return 0; 4853 } 4854 4855 #ifdef WLAN_FEATURE_CIF_CFR 4856 /** 4857 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 4858 * @wmi_handle: wmi handle 4859 * @data_len: len of dma cfg req 4860 * @data: dma cfg req 4861 * 4862 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 4863 */ 4864 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 4865 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 4866 { 4867 wmi_buf_t buf; 4868 uint8_t *cmd; 4869 QDF_STATUS ret; 4870 4871 WMITLV_SET_HDR(cfg, 4872 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 4873 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 4874 4875 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 4876 if (!buf) 4877 return QDF_STATUS_E_FAILURE; 4878 4879 cmd = (uint8_t *) wmi_buf_data(buf); 4880 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 4881 WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"), 4882 sizeof(*cfg)); 4883 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 4884 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 4885 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 4886 if (QDF_IS_STATUS_ERROR(ret)) { 4887 WMI_LOGE(FL(":wmi cmd send failed")); 4888 wmi_buf_free(buf); 4889 } 4890 4891 return ret; 4892 } 4893 #endif 4894 4895 /** 4896 * send_start_11d_scan_cmd_tlv() - start 11d scan request 4897 * @wmi_handle: wmi handle 4898 * @start_11d_scan: 11d scan start request parameters 4899 * 4900 * This function request FW to start 11d scan. 4901 * 4902 * Return: QDF status 4903 */ 4904 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 4905 struct reg_start_11d_scan_req *start_11d_scan) 4906 { 4907 wmi_11d_scan_start_cmd_fixed_param *cmd; 4908 int32_t len; 4909 wmi_buf_t buf; 4910 int ret; 4911 4912 len = sizeof(*cmd); 4913 buf = wmi_buf_alloc(wmi_handle, len); 4914 if (!buf) 4915 return QDF_STATUS_E_NOMEM; 4916 4917 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 4918 4919 WMITLV_SET_HDR(&cmd->tlv_header, 4920 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 4921 WMITLV_GET_STRUCT_TLVLEN 4922 (wmi_11d_scan_start_cmd_fixed_param)); 4923 4924 cmd->vdev_id = start_11d_scan->vdev_id; 4925 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 4926 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 4927 4928 WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id); 4929 4930 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 4931 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4932 WMI_11D_SCAN_START_CMDID); 4933 if (ret) { 4934 WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__); 4935 wmi_buf_free(buf); 4936 return QDF_STATUS_E_FAILURE; 4937 } 4938 4939 return QDF_STATUS_SUCCESS; 4940 } 4941 4942 /** 4943 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 4944 * @wmi_handle: wmi handle 4945 * @start_11d_scan: 11d scan stop request parameters 4946 * 4947 * This function request FW to stop 11d scan. 4948 * 4949 * Return: QDF status 4950 */ 4951 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 4952 struct reg_stop_11d_scan_req *stop_11d_scan) 4953 { 4954 wmi_11d_scan_stop_cmd_fixed_param *cmd; 4955 int32_t len; 4956 wmi_buf_t buf; 4957 int ret; 4958 4959 len = sizeof(*cmd); 4960 buf = wmi_buf_alloc(wmi_handle, len); 4961 if (!buf) 4962 return QDF_STATUS_E_NOMEM; 4963 4964 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 4965 4966 WMITLV_SET_HDR(&cmd->tlv_header, 4967 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 4968 WMITLV_GET_STRUCT_TLVLEN 4969 (wmi_11d_scan_stop_cmd_fixed_param)); 4970 4971 cmd->vdev_id = stop_11d_scan->vdev_id; 4972 4973 WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id); 4974 4975 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 4976 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4977 WMI_11D_SCAN_STOP_CMDID); 4978 if (ret) { 4979 WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__); 4980 wmi_buf_free(buf); 4981 return QDF_STATUS_E_FAILURE; 4982 } 4983 4984 return QDF_STATUS_SUCCESS; 4985 } 4986 4987 /** 4988 * send_start_oem_data_cmd_tlv() - start OEM data request to target 4989 * @wmi_handle: wmi handle 4990 * @startOemDataReq: start request params 4991 * 4992 * Return: CDF status 4993 */ 4994 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 4995 uint32_t data_len, 4996 uint8_t *data) 4997 { 4998 wmi_buf_t buf; 4999 uint8_t *cmd; 5000 QDF_STATUS ret; 5001 5002 buf = wmi_buf_alloc(wmi_handle, 5003 (data_len + WMI_TLV_HDR_SIZE)); 5004 if (!buf) 5005 return QDF_STATUS_E_FAILURE; 5006 5007 cmd = (uint8_t *) wmi_buf_data(buf); 5008 5009 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 5010 cmd += WMI_TLV_HDR_SIZE; 5011 qdf_mem_copy(cmd, data, 5012 data_len); 5013 5014 WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"), 5015 data_len); 5016 5017 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 5018 ret = wmi_unified_cmd_send(wmi_handle, buf, 5019 (data_len + 5020 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 5021 5022 if (QDF_IS_STATUS_ERROR(ret)) { 5023 WMI_LOGE(FL(":wmi cmd send failed")); 5024 wmi_buf_free(buf); 5025 } 5026 5027 return ret; 5028 } 5029 5030 /** 5031 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 5032 * @wmi_handle: wmi handle 5033 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 5034 * 5035 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 5036 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 5037 * to firmware based on phyerr filtering 5038 * offload status. 5039 * 5040 * Return: 1 success, 0 failure 5041 */ 5042 static QDF_STATUS 5043 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 5044 bool dfs_phyerr_filter_offload) 5045 { 5046 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 5047 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 5048 wmi_buf_t buf; 5049 uint16_t len; 5050 QDF_STATUS ret; 5051 5052 5053 if (false == dfs_phyerr_filter_offload) { 5054 WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini", 5055 __func__); 5056 len = sizeof(*disable_phyerr_offload_cmd); 5057 buf = wmi_buf_alloc(wmi_handle, len); 5058 if (!buf) 5059 return 0; 5060 5061 disable_phyerr_offload_cmd = 5062 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 5063 wmi_buf_data(buf); 5064 5065 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 5066 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 5067 WMITLV_GET_STRUCT_TLVLEN 5068 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 5069 5070 /* 5071 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 5072 * to the firmware to disable the phyerror 5073 * filtering offload. 5074 */ 5075 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 5076 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5077 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 5078 if (QDF_IS_STATUS_ERROR(ret)) { 5079 WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 5080 __func__, ret); 5081 wmi_buf_free(buf); 5082 return QDF_STATUS_E_FAILURE; 5083 } 5084 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success", 5085 __func__); 5086 } else { 5087 WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini", 5088 __func__); 5089 5090 len = sizeof(*enable_phyerr_offload_cmd); 5091 buf = wmi_buf_alloc(wmi_handle, len); 5092 if (!buf) 5093 return QDF_STATUS_E_FAILURE; 5094 5095 enable_phyerr_offload_cmd = 5096 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 5097 wmi_buf_data(buf); 5098 5099 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 5100 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 5101 WMITLV_GET_STRUCT_TLVLEN 5102 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 5103 5104 /* 5105 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 5106 * to the firmware to enable the phyerror 5107 * filtering offload. 5108 */ 5109 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 5110 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5111 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 5112 5113 if (QDF_IS_STATUS_ERROR(ret)) { 5114 WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d", 5115 __func__, ret); 5116 wmi_buf_free(buf); 5117 return QDF_STATUS_E_FAILURE; 5118 } 5119 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success", 5120 __func__); 5121 } 5122 5123 return QDF_STATUS_SUCCESS; 5124 } 5125 5126 #if !defined(REMOVE_PKT_LOG) && defined(CONFIG_MCL) 5127 /** 5128 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 5129 * @wmi_handle: wmi handle 5130 * @pktlog_event: pktlog event 5131 * @cmd_id: pktlog cmd id 5132 * 5133 * Return: CDF status 5134 */ 5135 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 5136 WMI_PKTLOG_EVENT pktlog_event, 5137 WMI_CMD_ID cmd_id, uint8_t user_triggered) 5138 { 5139 WMI_PKTLOG_EVENT PKTLOG_EVENT; 5140 WMI_CMD_ID CMD_ID; 5141 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 5142 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 5143 int len = 0; 5144 wmi_buf_t buf; 5145 5146 PKTLOG_EVENT = pktlog_event; 5147 CMD_ID = cmd_id; 5148 5149 switch (CMD_ID) { 5150 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 5151 len = sizeof(*cmd); 5152 buf = wmi_buf_alloc(wmi_handle, len); 5153 if (!buf) 5154 return QDF_STATUS_E_NOMEM; 5155 5156 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 5157 wmi_buf_data(buf); 5158 WMITLV_SET_HDR(&cmd->tlv_header, 5159 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 5160 WMITLV_GET_STRUCT_TLVLEN 5161 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 5162 cmd->evlist = PKTLOG_EVENT; 5163 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 5164 : WMI_PKTLOG_ENABLE_AUTO; 5165 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5166 WMI_HOST_PDEV_ID_SOC); 5167 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 5168 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5169 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 5170 WMI_LOGE("failed to send pktlog enable cmdid"); 5171 goto wmi_send_failed; 5172 } 5173 break; 5174 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 5175 len = sizeof(*disable_cmd); 5176 buf = wmi_buf_alloc(wmi_handle, len); 5177 if (!buf) 5178 return QDF_STATUS_E_NOMEM; 5179 5180 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 5181 wmi_buf_data(buf); 5182 WMITLV_SET_HDR(&disable_cmd->tlv_header, 5183 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 5184 WMITLV_GET_STRUCT_TLVLEN 5185 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 5186 disable_cmd->pdev_id = 5187 wmi_handle->ops->convert_pdev_id_host_to_target( 5188 WMI_HOST_PDEV_ID_SOC); 5189 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 5190 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5191 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 5192 WMI_LOGE("failed to send pktlog disable cmdid"); 5193 goto wmi_send_failed; 5194 } 5195 break; 5196 default: 5197 WMI_LOGD("%s: invalid PKTLOG command", __func__); 5198 break; 5199 } 5200 5201 return QDF_STATUS_SUCCESS; 5202 5203 wmi_send_failed: 5204 wmi_buf_free(buf); 5205 return QDF_STATUS_E_FAILURE; 5206 } 5207 #endif /* !REMOVE_PKT_LOG && CONFIG_MCL*/ 5208 5209 /** 5210 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 5211 * @wmi_handle: wmi handle 5212 * @preq: stats ext params 5213 * 5214 * Return: CDF status 5215 */ 5216 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 5217 struct stats_ext_params *preq) 5218 { 5219 QDF_STATUS ret; 5220 wmi_req_stats_ext_cmd_fixed_param *cmd; 5221 wmi_buf_t buf; 5222 size_t len; 5223 uint8_t *buf_ptr; 5224 5225 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 5226 5227 buf = wmi_buf_alloc(wmi_handle, len); 5228 if (!buf) 5229 return QDF_STATUS_E_NOMEM; 5230 5231 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5232 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 5233 5234 WMITLV_SET_HDR(&cmd->tlv_header, 5235 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 5236 WMITLV_GET_STRUCT_TLVLEN 5237 (wmi_req_stats_ext_cmd_fixed_param)); 5238 cmd->vdev_id = preq->vdev_id; 5239 cmd->data_len = preq->request_data_len; 5240 5241 WMI_LOGD("%s: The data len value is %u and vdev id set is %u ", 5242 __func__, preq->request_data_len, preq->vdev_id); 5243 5244 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 5245 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 5246 5247 buf_ptr += WMI_TLV_HDR_SIZE; 5248 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 5249 5250 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 5251 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5252 WMI_REQUEST_STATS_EXT_CMDID); 5253 if (QDF_IS_STATUS_ERROR(ret)) { 5254 WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__, 5255 ret); 5256 wmi_buf_free(buf); 5257 } 5258 5259 return ret; 5260 } 5261 5262 /** 5263 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 5264 * @wmi_handle: wmi handle 5265 * @params: DHCP server offload info 5266 * 5267 * Return: QDF_STATUS_SUCCESS for success or error code 5268 */ 5269 static QDF_STATUS 5270 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 5271 struct dhcp_offload_info_params *params) 5272 { 5273 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 5274 wmi_buf_t buf; 5275 QDF_STATUS status; 5276 5277 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5278 if (!buf) 5279 return QDF_STATUS_E_NOMEM; 5280 5281 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 5282 5283 WMITLV_SET_HDR(&cmd->tlv_header, 5284 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 5285 WMITLV_GET_STRUCT_TLVLEN 5286 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 5287 cmd->vdev_id = params->vdev_id; 5288 cmd->enable = params->dhcp_offload_enabled; 5289 cmd->num_client = params->dhcp_client_num; 5290 cmd->srv_ipv4 = params->dhcp_srv_addr; 5291 cmd->start_lsb = 0; 5292 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 5293 status = wmi_unified_cmd_send(wmi_handle, buf, 5294 sizeof(*cmd), 5295 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 5296 if (QDF_IS_STATUS_ERROR(status)) { 5297 WMI_LOGE("Failed to send set_dhcp_server_offload cmd"); 5298 wmi_buf_free(buf); 5299 return QDF_STATUS_E_FAILURE; 5300 } 5301 WMI_LOGD("Set dhcp server offload to vdevId %d", 5302 params->vdev_id); 5303 5304 return status; 5305 } 5306 5307 /** 5308 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 5309 * @wmi_handle: wmi handle 5310 * @param: pointer to pdev regdomain params 5311 * 5312 * Return: 0 for success or error code 5313 */ 5314 static QDF_STATUS 5315 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 5316 struct pdev_set_regdomain_params *param) 5317 { 5318 wmi_buf_t buf; 5319 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 5320 int32_t len = sizeof(*cmd); 5321 5322 buf = wmi_buf_alloc(wmi_handle, len); 5323 if (!buf) 5324 return QDF_STATUS_E_NOMEM; 5325 5326 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 5327 WMITLV_SET_HDR(&cmd->tlv_header, 5328 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 5329 WMITLV_GET_STRUCT_TLVLEN 5330 (wmi_pdev_set_regdomain_cmd_fixed_param)); 5331 5332 cmd->reg_domain = param->currentRDinuse; 5333 cmd->reg_domain_2G = param->currentRD2G; 5334 cmd->reg_domain_5G = param->currentRD5G; 5335 cmd->conformance_test_limit_2G = param->ctl_2G; 5336 cmd->conformance_test_limit_5G = param->ctl_5G; 5337 cmd->dfs_domain = param->dfsDomain; 5338 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5339 param->pdev_id); 5340 5341 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 5342 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5343 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 5344 WMI_LOGE("%s: Failed to send pdev set regdomain command", 5345 __func__); 5346 wmi_buf_free(buf); 5347 return QDF_STATUS_E_FAILURE; 5348 } 5349 5350 return QDF_STATUS_SUCCESS; 5351 } 5352 5353 /** 5354 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 5355 * @wmi_handle: wmi handle 5356 * @reg_dmn: reg domain 5357 * @regdmn2G: 2G reg domain 5358 * @regdmn5G: 5G reg domain 5359 * @ctl2G: 2G test limit 5360 * @ctl5G: 5G test limit 5361 * 5362 * Return: none 5363 */ 5364 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 5365 uint32_t reg_dmn, uint16_t regdmn2G, 5366 uint16_t regdmn5G, uint8_t ctl2G, 5367 uint8_t ctl5G) 5368 { 5369 wmi_buf_t buf; 5370 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 5371 int32_t len = sizeof(*cmd); 5372 5373 5374 buf = wmi_buf_alloc(wmi_handle, len); 5375 if (!buf) 5376 return QDF_STATUS_E_NOMEM; 5377 5378 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 5379 WMITLV_SET_HDR(&cmd->tlv_header, 5380 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 5381 WMITLV_GET_STRUCT_TLVLEN 5382 (wmi_pdev_set_regdomain_cmd_fixed_param)); 5383 cmd->reg_domain = reg_dmn; 5384 cmd->reg_domain_2G = regdmn2G; 5385 cmd->reg_domain_5G = regdmn5G; 5386 cmd->conformance_test_limit_2G = ctl2G; 5387 cmd->conformance_test_limit_5G = ctl5G; 5388 5389 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 5390 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5391 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 5392 WMI_LOGP("%s: Failed to send pdev set regdomain command", 5393 __func__); 5394 wmi_buf_free(buf); 5395 return QDF_STATUS_E_FAILURE; 5396 } 5397 5398 return QDF_STATUS_SUCCESS; 5399 } 5400 5401 /** 5402 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 5403 * @param: param sent from the host side 5404 * @cmd: param to be sent to the fw side 5405 */ 5406 static inline void copy_custom_aggr_bitmap( 5407 struct set_custom_aggr_size_params *param, 5408 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 5409 { 5410 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 5411 param->ac); 5412 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 5413 param->aggr_type); 5414 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 5415 param->tx_aggr_size_disable); 5416 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 5417 param->rx_aggr_size_disable); 5418 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 5419 param->tx_ac_enable); 5420 } 5421 5422 /** 5423 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 5424 * @wmi_handle: wmi handle 5425 * @param: pointer to hold custom aggr size params 5426 * 5427 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 5428 */ 5429 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 5430 wmi_unified_t wmi_handle, 5431 struct set_custom_aggr_size_params *param) 5432 { 5433 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 5434 wmi_buf_t buf; 5435 int32_t len = sizeof(*cmd); 5436 5437 buf = wmi_buf_alloc(wmi_handle, len); 5438 if (!buf) 5439 return QDF_STATUS_E_FAILURE; 5440 5441 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 5442 wmi_buf_data(buf); 5443 WMITLV_SET_HDR(&cmd->tlv_header, 5444 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 5445 WMITLV_GET_STRUCT_TLVLEN( 5446 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 5447 cmd->vdev_id = param->vdev_id; 5448 cmd->tx_aggr_size = param->tx_aggr_size; 5449 cmd->rx_aggr_size = param->rx_aggr_size; 5450 copy_custom_aggr_bitmap(param, cmd); 5451 5452 WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 5453 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 5454 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 5455 "tx_ac_enable=0x%X", 5456 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 5457 param->ac, param->aggr_type, param->tx_aggr_size_disable, 5458 param->rx_aggr_size_disable, param->tx_ac_enable); 5459 5460 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 5461 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5462 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 5463 WMI_LOGE("Seting custom aggregation size failed"); 5464 wmi_buf_free(buf); 5465 return QDF_STATUS_E_FAILURE; 5466 } 5467 5468 return QDF_STATUS_SUCCESS; 5469 } 5470 5471 /** 5472 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 5473 * @param wmi_handle : handle to WMI. 5474 * @param param : pointer to tx antenna param 5475 * 5476 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 5477 */ 5478 5479 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 5480 struct set_qdepth_thresh_params *param) 5481 { 5482 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 5483 wmi_msduq_qdepth_thresh_update *cmd_update; 5484 wmi_buf_t buf; 5485 int32_t len = 0; 5486 int i; 5487 uint8_t *buf_ptr; 5488 QDF_STATUS ret; 5489 5490 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 5491 WMI_LOGE("%s: Invalid Update Count!", __func__); 5492 return QDF_STATUS_E_INVAL; 5493 } 5494 5495 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 5496 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 5497 param->num_of_msduq_updates); 5498 buf = wmi_buf_alloc(wmi_handle, len); 5499 5500 if (!buf) 5501 return QDF_STATUS_E_NOMEM; 5502 5503 buf_ptr = (uint8_t *)wmi_buf_data(buf); 5504 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 5505 buf_ptr; 5506 5507 WMITLV_SET_HDR(&cmd->tlv_header, 5508 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 5509 , WMITLV_GET_STRUCT_TLVLEN( 5510 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 5511 5512 cmd->pdev_id = 5513 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 5514 cmd->vdev_id = param->vdev_id; 5515 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 5516 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 5517 5518 buf_ptr += sizeof( 5519 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 5520 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5521 param->num_of_msduq_updates * 5522 sizeof(wmi_msduq_qdepth_thresh_update)); 5523 buf_ptr += WMI_TLV_HDR_SIZE; 5524 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 5525 5526 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 5527 WMITLV_SET_HDR(&cmd_update->tlv_header, 5528 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 5529 WMITLV_GET_STRUCT_TLVLEN( 5530 wmi_msduq_qdepth_thresh_update)); 5531 cmd_update->tid_num = param->update_params[i].tid_num; 5532 cmd_update->msduq_update_mask = 5533 param->update_params[i].msduq_update_mask; 5534 cmd_update->qdepth_thresh_value = 5535 param->update_params[i].qdepth_thresh_value; 5536 WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 5537 "mac_addr_upper4=%X, mac_addr_lower2:%X," 5538 " update mask=0x%X thresh val=0x%X", 5539 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 5540 cmd->peer_mac_address.mac_addr31to0, 5541 cmd->peer_mac_address.mac_addr47to32, 5542 cmd_update->msduq_update_mask, 5543 cmd_update->qdepth_thresh_value); 5544 cmd_update++; 5545 } 5546 5547 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 5548 cmd->vdev_id, 0); 5549 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5550 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 5551 5552 if (ret != 0) { 5553 WMI_LOGE(" %s :WMI Failed", __func__); 5554 wmi_buf_free(buf); 5555 } 5556 5557 return ret; 5558 } 5559 5560 /** 5561 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 5562 * @wmi_handle: wmi handle 5563 * @param: pointer to hold vap dscp tid map param 5564 * 5565 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 5566 */ 5567 static QDF_STATUS 5568 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 5569 struct vap_dscp_tid_map_params *param) 5570 { 5571 wmi_buf_t buf; 5572 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 5573 int32_t len = sizeof(*cmd); 5574 5575 buf = wmi_buf_alloc(wmi_handle, len); 5576 if (!buf) 5577 return QDF_STATUS_E_FAILURE; 5578 5579 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 5580 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 5581 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 5582 5583 cmd->vdev_id = param->vdev_id; 5584 cmd->enable_override = 0; 5585 5586 WMI_LOGI("Setting dscp for vap id: %d", cmd->vdev_id); 5587 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 5588 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5589 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 5590 WMI_LOGE("Failed to set dscp cmd"); 5591 wmi_buf_free(buf); 5592 return QDF_STATUS_E_FAILURE; 5593 } 5594 5595 return QDF_STATUS_SUCCESS; 5596 } 5597 5598 /** 5599 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 5600 * @wmi_handle: wmi handle 5601 * @param: pointer to hold fwtest param 5602 * 5603 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 5604 */ 5605 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 5606 struct set_fwtest_params *param) 5607 { 5608 wmi_fwtest_set_param_cmd_fixed_param *cmd; 5609 wmi_buf_t buf; 5610 int32_t len = sizeof(*cmd); 5611 5612 buf = wmi_buf_alloc(wmi_handle, len); 5613 5614 if (!buf) 5615 return QDF_STATUS_E_FAILURE; 5616 5617 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 5618 WMITLV_SET_HDR(&cmd->tlv_header, 5619 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 5620 WMITLV_GET_STRUCT_TLVLEN( 5621 wmi_fwtest_set_param_cmd_fixed_param)); 5622 cmd->param_id = param->arg; 5623 cmd->param_value = param->value; 5624 5625 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 5626 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 5627 WMI_LOGE("Setting FW test param failed"); 5628 wmi_buf_free(buf); 5629 return QDF_STATUS_E_FAILURE; 5630 } 5631 5632 return QDF_STATUS_SUCCESS; 5633 } 5634 5635 /** 5636 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 5637 * 5638 * @param wmi_handle : handle to WMI. 5639 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 5640 */ 5641 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 5642 { 5643 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 5644 wmi_buf_t buf; 5645 QDF_STATUS ret; 5646 int32_t len; 5647 5648 len = sizeof(*cmd); 5649 5650 buf = wmi_buf_alloc(wmi_handle, len); 5651 if (!buf) 5652 return QDF_STATUS_E_FAILURE; 5653 5654 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 5655 WMITLV_SET_HDR(&cmd->tlv_header, 5656 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 5657 WMITLV_GET_STRUCT_TLVLEN( 5658 wmi_pdev_dfs_disable_cmd_fixed_param)); 5659 /* Filling it with WMI_PDEV_ID_SOC for now */ 5660 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5661 WMI_HOST_PDEV_ID_SOC); 5662 5663 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 5664 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 5665 WMI_PDEV_DFS_DISABLE_CMDID); 5666 5667 if (ret != 0) { 5668 WMI_LOGE("Sending PDEV DFS disable cmd failed"); 5669 wmi_buf_free(buf); 5670 } 5671 5672 return ret; 5673 } 5674 5675 /** 5676 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 5677 * 5678 * @param wmi_handle : handle to WMI. 5679 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 5680 */ 5681 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 5682 { 5683 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 5684 wmi_buf_t buf; 5685 QDF_STATUS ret; 5686 int32_t len; 5687 5688 len = sizeof(*cmd); 5689 5690 buf = wmi_buf_alloc(wmi_handle, len); 5691 if (!buf) 5692 return QDF_STATUS_E_FAILURE; 5693 5694 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 5695 WMITLV_SET_HDR(&cmd->tlv_header, 5696 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 5697 WMITLV_GET_STRUCT_TLVLEN( 5698 wmi_pdev_dfs_enable_cmd_fixed_param)); 5699 /* Reserved for future use */ 5700 cmd->reserved0 = 0; 5701 5702 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 5703 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 5704 WMI_PDEV_DFS_ENABLE_CMDID); 5705 5706 if (ret != 0) { 5707 WMI_LOGE("Sending PDEV DFS enable cmd failed"); 5708 wmi_buf_free(buf); 5709 } 5710 5711 return ret; 5712 } 5713 5714 /** 5715 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 5716 * to fw 5717 * @wmi_handle: wmi handle 5718 * @param: pointer to hold periodic chan stats param 5719 * 5720 * Return: 0 for success or error code 5721 */ 5722 static QDF_STATUS 5723 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 5724 struct periodic_chan_stats_params *param) 5725 { 5726 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 5727 wmi_buf_t buf; 5728 QDF_STATUS ret; 5729 int32_t len; 5730 5731 len = sizeof(*cmd); 5732 5733 buf = wmi_buf_alloc(wmi_handle, len); 5734 if (!buf) 5735 return QDF_STATUS_E_FAILURE; 5736 5737 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 5738 wmi_buf_data(buf); 5739 WMITLV_SET_HDR(&cmd->tlv_header, 5740 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 5741 WMITLV_GET_STRUCT_TLVLEN( 5742 wmi_set_periodic_channel_stats_config_fixed_param)); 5743 cmd->enable = param->enable; 5744 cmd->stats_period = param->stats_period; 5745 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5746 param->pdev_id); 5747 5748 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 5749 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 5750 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 5751 5752 if (ret != 0) { 5753 WMI_LOGE("Sending periodic chan stats config failed"); 5754 wmi_buf_free(buf); 5755 } 5756 5757 return ret; 5758 } 5759 5760 /** 5761 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 5762 * command to fw 5763 * @wmi_handle: wmi handle 5764 * @param: pointer to hold spectral config parameter 5765 * 5766 * Return: 0 for success or error code 5767 */ 5768 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 5769 struct vdev_spectral_configure_params *param) 5770 { 5771 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 5772 wmi_buf_t buf; 5773 QDF_STATUS ret; 5774 int32_t len; 5775 5776 len = sizeof(*cmd); 5777 buf = wmi_buf_alloc(wmi_handle, len); 5778 if (!buf) 5779 return QDF_STATUS_E_FAILURE; 5780 5781 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 5782 WMITLV_SET_HDR(&cmd->tlv_header, 5783 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 5784 WMITLV_GET_STRUCT_TLVLEN( 5785 wmi_vdev_spectral_configure_cmd_fixed_param)); 5786 5787 cmd->vdev_id = param->vdev_id; 5788 cmd->spectral_scan_count = param->count; 5789 cmd->spectral_scan_period = param->period; 5790 cmd->spectral_scan_priority = param->spectral_pri; 5791 cmd->spectral_scan_fft_size = param->fft_size; 5792 cmd->spectral_scan_gc_ena = param->gc_enable; 5793 cmd->spectral_scan_restart_ena = param->restart_enable; 5794 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 5795 cmd->spectral_scan_init_delay = param->init_delay; 5796 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 5797 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 5798 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 5799 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 5800 cmd->spectral_scan_rssi_thr = param->rssi_thr; 5801 cmd->spectral_scan_pwr_format = param->pwr_format; 5802 cmd->spectral_scan_rpt_mode = param->rpt_mode; 5803 cmd->spectral_scan_bin_scale = param->bin_scale; 5804 cmd->spectral_scan_dBm_adj = param->dbm_adj; 5805 cmd->spectral_scan_chn_mask = param->chn_mask; 5806 5807 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 5808 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5809 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 5810 5811 if (ret != 0) { 5812 WMI_LOGE("Sending set quiet cmd failed"); 5813 wmi_buf_free(buf); 5814 } 5815 5816 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID", 5817 __func__); 5818 5819 WMI_LOGI("vdev_id = %u\n" 5820 "spectral_scan_count = %u\n" 5821 "spectral_scan_period = %u\n" 5822 "spectral_scan_priority = %u\n" 5823 "spectral_scan_fft_size = %u\n" 5824 "spectral_scan_gc_ena = %u\n" 5825 "spectral_scan_restart_ena = %u\n" 5826 "spectral_scan_noise_floor_ref = %u\n" 5827 "spectral_scan_init_delay = %u\n" 5828 "spectral_scan_nb_tone_thr = %u\n" 5829 "spectral_scan_str_bin_thr = %u\n" 5830 "spectral_scan_wb_rpt_mode = %u\n" 5831 "spectral_scan_rssi_rpt_mode = %u\n" 5832 "spectral_scan_rssi_thr = %u\n" 5833 "spectral_scan_pwr_format = %u\n" 5834 "spectral_scan_rpt_mode = %u\n" 5835 "spectral_scan_bin_scale = %u\n" 5836 "spectral_scan_dBm_adj = %u\n" 5837 "spectral_scan_chn_mask = %u", 5838 param->vdev_id, 5839 param->count, 5840 param->period, 5841 param->spectral_pri, 5842 param->fft_size, 5843 param->gc_enable, 5844 param->restart_enable, 5845 param->noise_floor_ref, 5846 param->init_delay, 5847 param->nb_tone_thr, 5848 param->str_bin_thr, 5849 param->wb_rpt_mode, 5850 param->rssi_rpt_mode, 5851 param->rssi_thr, 5852 param->pwr_format, 5853 param->rpt_mode, 5854 param->bin_scale, 5855 param->dbm_adj, 5856 param->chn_mask); 5857 WMI_LOGI("%s: Status: %d", __func__, ret); 5858 5859 return ret; 5860 } 5861 5862 /** 5863 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 5864 * command to fw 5865 * @wmi_handle: wmi handle 5866 * @param: pointer to hold spectral enable parameter 5867 * 5868 * Return: 0 for success or error code 5869 */ 5870 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 5871 struct vdev_spectral_enable_params *param) 5872 { 5873 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 5874 wmi_buf_t buf; 5875 QDF_STATUS ret; 5876 int32_t len; 5877 5878 len = sizeof(*cmd); 5879 buf = wmi_buf_alloc(wmi_handle, len); 5880 if (!buf) 5881 return QDF_STATUS_E_FAILURE; 5882 5883 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 5884 WMITLV_SET_HDR(&cmd->tlv_header, 5885 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 5886 WMITLV_GET_STRUCT_TLVLEN( 5887 wmi_vdev_spectral_enable_cmd_fixed_param)); 5888 5889 cmd->vdev_id = param->vdev_id; 5890 5891 if (param->active_valid) { 5892 cmd->trigger_cmd = param->active ? 1 : 2; 5893 /* 1: Trigger, 2: Clear Trigger */ 5894 } else { 5895 cmd->trigger_cmd = 0; /* 0: Ignore */ 5896 } 5897 5898 if (param->enabled_valid) { 5899 cmd->enable_cmd = param->enabled ? 1 : 2; 5900 /* 1: Enable 2: Disable */ 5901 } else { 5902 cmd->enable_cmd = 0; /* 0: Ignore */ 5903 } 5904 5905 WMI_LOGI("vdev_id = %u\n" 5906 "trigger_cmd = %u\n" 5907 "enable_cmd = %u", 5908 cmd->vdev_id, 5909 cmd->trigger_cmd, 5910 cmd->enable_cmd); 5911 5912 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 5913 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5914 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 5915 5916 if (ret != 0) { 5917 WMI_LOGE("Sending scan enable CMD failed"); 5918 wmi_buf_free(buf); 5919 } 5920 5921 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID", __func__); 5922 5923 WMI_LOGI("%s: Status: %d", __func__, ret); 5924 5925 return ret; 5926 } 5927 5928 /** 5929 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 5930 * @param wmi_handle : handle to WMI. 5931 * @param param : pointer to hold thermal mitigation param 5932 * 5933 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 5934 */ 5935 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 5936 wmi_unified_t wmi_handle, 5937 struct thermal_mitigation_params *param) 5938 { 5939 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 5940 wmi_therm_throt_level_config_info *lvl_conf = NULL; 5941 wmi_buf_t buf = NULL; 5942 uint8_t *buf_ptr = NULL; 5943 int error; 5944 int32_t len; 5945 int i; 5946 5947 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 5948 THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info); 5949 5950 buf = wmi_buf_alloc(wmi_handle, len); 5951 if (!buf) 5952 return QDF_STATUS_E_NOMEM; 5953 5954 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 5955 5956 /* init fixed params */ 5957 WMITLV_SET_HDR(tt_conf, 5958 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 5959 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 5960 5961 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5962 param->pdev_id); 5963 tt_conf->enable = param->enable; 5964 tt_conf->dc = param->dc; 5965 tt_conf->dc_per_event = param->dc_per_event; 5966 tt_conf->therm_throt_levels = THERMAL_LEVELS; 5967 5968 buf_ptr = (uint8_t *) ++tt_conf; 5969 /* init TLV params */ 5970 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5971 (THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info))); 5972 5973 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 5974 for (i = 0; i < THERMAL_LEVELS; i++) { 5975 WMITLV_SET_HDR(&lvl_conf->tlv_header, 5976 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 5977 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 5978 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 5979 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 5980 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 5981 lvl_conf->prio = param->levelconf[i].priority; 5982 lvl_conf++; 5983 } 5984 5985 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 5986 error = wmi_unified_cmd_send(wmi_handle, buf, len, 5987 WMI_THERM_THROT_SET_CONF_CMDID); 5988 if (QDF_IS_STATUS_ERROR(error)) { 5989 wmi_buf_free(buf); 5990 WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 5991 } 5992 5993 return error; 5994 } 5995 5996 /** 5997 * send_coex_config_cmd_tlv() - send coex config command to fw 5998 * @wmi_handle: wmi handle 5999 * @param: pointer to coex config param 6000 * 6001 * Return: 0 for success or error code 6002 */ 6003 static QDF_STATUS 6004 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 6005 struct coex_config_params *param) 6006 { 6007 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 6008 wmi_buf_t buf; 6009 QDF_STATUS ret; 6010 int32_t len; 6011 6012 len = sizeof(*cmd); 6013 buf = wmi_buf_alloc(wmi_handle, len); 6014 if (!buf) 6015 return QDF_STATUS_E_FAILURE; 6016 6017 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 6018 WMITLV_SET_HDR(&cmd->tlv_header, 6019 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 6020 WMITLV_GET_STRUCT_TLVLEN( 6021 WMI_COEX_CONFIG_CMD_fixed_param)); 6022 6023 cmd->vdev_id = param->vdev_id; 6024 cmd->config_type = param->config_type; 6025 cmd->config_arg1 = param->config_arg1; 6026 cmd->config_arg2 = param->config_arg2; 6027 cmd->config_arg3 = param->config_arg3; 6028 cmd->config_arg4 = param->config_arg4; 6029 cmd->config_arg5 = param->config_arg5; 6030 cmd->config_arg6 = param->config_arg6; 6031 6032 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 6033 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6034 WMI_COEX_CONFIG_CMDID); 6035 6036 if (ret != 0) { 6037 WMI_LOGE("Sending COEX CONFIG CMD failed"); 6038 wmi_buf_free(buf); 6039 } 6040 6041 return ret; 6042 } 6043 6044 #ifdef WLAN_SUPPORT_TWT 6045 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 6046 target_resource_config *tgt_res_cfg) 6047 { 6048 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 6049 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 6050 } 6051 #else 6052 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 6053 target_resource_config *tgt_res_cfg) 6054 { 6055 resource_cfg->twt_ap_pdev_count = 0; 6056 resource_cfg->twt_ap_sta_count = 0; 6057 } 6058 #endif 6059 6060 static 6061 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 6062 target_resource_config *tgt_res_cfg) 6063 { 6064 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 6065 resource_cfg->num_peers = tgt_res_cfg->num_peers; 6066 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 6067 resource_cfg->num_offload_reorder_buffs = 6068 tgt_res_cfg->num_offload_reorder_buffs; 6069 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 6070 resource_cfg->num_tids = tgt_res_cfg->num_tids; 6071 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 6072 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 6073 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 6074 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 6075 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 6076 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 6077 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 6078 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 6079 resource_cfg->scan_max_pending_req = 6080 tgt_res_cfg->scan_max_pending_req; 6081 resource_cfg->bmiss_offload_max_vdev = 6082 tgt_res_cfg->bmiss_offload_max_vdev; 6083 resource_cfg->roam_offload_max_vdev = 6084 tgt_res_cfg->roam_offload_max_vdev; 6085 resource_cfg->roam_offload_max_ap_profiles = 6086 tgt_res_cfg->roam_offload_max_ap_profiles; 6087 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 6088 resource_cfg->num_mcast_table_elems = 6089 tgt_res_cfg->num_mcast_table_elems; 6090 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 6091 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 6092 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 6093 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 6094 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 6095 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 6096 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 6097 resource_cfg->vow_config = tgt_res_cfg->vow_config; 6098 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 6099 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 6100 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 6101 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 6102 resource_cfg->num_tdls_conn_table_entries = 6103 tgt_res_cfg->num_tdls_conn_table_entries; 6104 resource_cfg->beacon_tx_offload_max_vdev = 6105 tgt_res_cfg->beacon_tx_offload_max_vdev; 6106 resource_cfg->num_multicast_filter_entries = 6107 tgt_res_cfg->num_multicast_filter_entries; 6108 resource_cfg->num_wow_filters = 6109 tgt_res_cfg->num_wow_filters; 6110 resource_cfg->num_keep_alive_pattern = 6111 tgt_res_cfg->num_keep_alive_pattern; 6112 resource_cfg->keep_alive_pattern_size = 6113 tgt_res_cfg->keep_alive_pattern_size; 6114 resource_cfg->max_tdls_concurrent_sleep_sta = 6115 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 6116 resource_cfg->max_tdls_concurrent_buffer_sta = 6117 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 6118 resource_cfg->wmi_send_separate = 6119 tgt_res_cfg->wmi_send_separate; 6120 resource_cfg->num_ocb_vdevs = 6121 tgt_res_cfg->num_ocb_vdevs; 6122 resource_cfg->num_ocb_channels = 6123 tgt_res_cfg->num_ocb_channels; 6124 resource_cfg->num_ocb_schedules = 6125 tgt_res_cfg->num_ocb_schedules; 6126 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 6127 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 6128 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 6129 resource_cfg->max_num_dbs_scan_duty_cycle = 6130 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 6131 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 6132 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 6133 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 6134 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 6135 if (tgt_res_cfg->atf_config) 6136 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 6137 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 6138 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 6139 resource_cfg->flag1, 1); 6140 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 6141 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 6142 resource_cfg->flag1, 1); 6143 if (tgt_res_cfg->cce_disable) 6144 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 6145 if (tgt_res_cfg->eapol_minrate_set) { 6146 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 6147 resource_cfg->flag1, 1); 6148 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 6149 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 6150 resource_cfg->flag1, 1); 6151 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 6152 resource_cfg->flag1, 6153 tgt_res_cfg->eapol_minrate_ac_set); 6154 } 6155 } 6156 if (tgt_res_cfg->new_htt_msg_format) { 6157 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 6158 resource_cfg->flag1, 1); 6159 } 6160 6161 if (tgt_res_cfg->peer_unmap_conf_support) 6162 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 6163 resource_cfg->flag1, 1); 6164 6165 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 6166 resource_cfg->peer_map_unmap_v2_support = 6167 tgt_res_cfg->peer_map_unmap_v2; 6168 } 6169 6170 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 6171 * @wmi_handle: pointer to wmi handle 6172 * @buf_ptr: pointer to current position in init command buffer 6173 * @len: pointer to length. This will be updated with current length of cmd 6174 * @param: point host parameters for init command 6175 * 6176 * Return: Updated pointer of buf_ptr. 6177 */ 6178 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 6179 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 6180 { 6181 uint16_t idx; 6182 6183 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 6184 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 6185 wmi_pdev_band_to_mac *band_to_mac; 6186 6187 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 6188 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 6189 sizeof(wmi_resource_config) + 6190 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 6191 sizeof(wlan_host_memory_chunk))); 6192 6193 WMITLV_SET_HDR(&hw_mode->tlv_header, 6194 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 6195 (WMITLV_GET_STRUCT_TLVLEN 6196 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 6197 6198 hw_mode->hw_mode_index = param->hw_mode_id; 6199 hw_mode->num_band_to_mac = param->num_band_to_mac; 6200 6201 buf_ptr = (uint8_t *) (hw_mode + 1); 6202 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 6203 WMI_TLV_HDR_SIZE); 6204 for (idx = 0; idx < param->num_band_to_mac; idx++) { 6205 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 6206 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 6207 WMITLV_GET_STRUCT_TLVLEN 6208 (wmi_pdev_band_to_mac)); 6209 band_to_mac[idx].pdev_id = 6210 wmi_handle->ops->convert_pdev_id_host_to_target( 6211 param->band_to_mac[idx].pdev_id); 6212 band_to_mac[idx].start_freq = 6213 param->band_to_mac[idx].start_freq; 6214 band_to_mac[idx].end_freq = 6215 param->band_to_mac[idx].end_freq; 6216 } 6217 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 6218 (param->num_band_to_mac * 6219 sizeof(wmi_pdev_band_to_mac)) + 6220 WMI_TLV_HDR_SIZE; 6221 6222 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6223 (param->num_band_to_mac * 6224 sizeof(wmi_pdev_band_to_mac))); 6225 } 6226 6227 return buf_ptr; 6228 } 6229 6230 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 6231 wmi_init_cmd_fixed_param *cmd) 6232 { 6233 int num_whitelist; 6234 wmi_abi_version my_vers; 6235 6236 num_whitelist = sizeof(version_whitelist) / 6237 sizeof(wmi_whitelist_version_info); 6238 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 6239 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 6240 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 6241 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 6242 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 6243 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 6244 6245 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 6246 &my_vers, 6247 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 6248 &cmd->host_abi_vers); 6249 6250 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 6251 __func__, 6252 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 6253 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 6254 cmd->host_abi_vers.abi_version_ns_0, 6255 cmd->host_abi_vers.abi_version_ns_1, 6256 cmd->host_abi_vers.abi_version_ns_2, 6257 cmd->host_abi_vers.abi_version_ns_3); 6258 6259 /* Save version sent from host - 6260 * Will be used to check ready event 6261 */ 6262 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 6263 sizeof(wmi_abi_version)); 6264 } 6265 6266 /* 6267 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 6268 * @wmi_handle: Pointer to WMi handle 6269 * @ie_data: Pointer for ie data 6270 * 6271 * This function sends action frame tb ppdu cfg to FW 6272 * 6273 * Return: QDF_STATUS_SUCCESS for success otherwise failure 6274 * 6275 */ 6276 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 6277 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 6278 { 6279 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 6280 wmi_buf_t buf; 6281 uint8_t *buf_ptr; 6282 uint32_t len, frm_len_aligned; 6283 QDF_STATUS ret; 6284 6285 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 6286 /* Allocate memory for the WMI command */ 6287 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 6288 6289 buf = wmi_buf_alloc(wmi_handle, len); 6290 if (!buf) 6291 return QDF_STATUS_E_NOMEM; 6292 6293 buf_ptr = wmi_buf_data(buf); 6294 qdf_mem_zero(buf_ptr, len); 6295 6296 /* Populate the WMI command */ 6297 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 6298 6299 WMITLV_SET_HDR(&cmd->tlv_header, 6300 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 6301 WMITLV_GET_STRUCT_TLVLEN( 6302 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 6303 cmd->enable = cfg_msg->cfg; 6304 cmd->data_len = cfg_msg->frm_len; 6305 6306 buf_ptr += sizeof(*cmd); 6307 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 6308 buf_ptr += WMI_TLV_HDR_SIZE; 6309 6310 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 6311 6312 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6313 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 6314 if (QDF_IS_STATUS_ERROR(ret)) { 6315 WMI_LOGE(FL("HE TB action frame cmnd send fail, ret %d"), ret); 6316 wmi_buf_free(buf); 6317 } 6318 6319 return ret; 6320 } 6321 6322 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 6323 { 6324 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 6325 wmi_service_ready_event_fixed_param *ev; 6326 6327 6328 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 6329 6330 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 6331 if (!ev) 6332 return QDF_STATUS_E_FAILURE; 6333 6334 /*Save fw version from service ready message */ 6335 /*This will be used while sending INIT message */ 6336 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 6337 sizeof(wmi_handle->fw_abi_version)); 6338 6339 return QDF_STATUS_SUCCESS; 6340 } 6341 6342 /** 6343 * wmi_unified_save_fw_version_cmd() - save fw version 6344 * @wmi_handle: pointer to wmi handle 6345 * @res_cfg: resource config 6346 * @num_mem_chunks: no of mem chunck 6347 * @mem_chunk: pointer to mem chunck structure 6348 * 6349 * This function sends IE information to firmware 6350 * 6351 * Return: QDF_STATUS_SUCCESS for success otherwise failure 6352 * 6353 */ 6354 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 6355 void *evt_buf) 6356 { 6357 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 6358 wmi_ready_event_fixed_param *ev = NULL; 6359 6360 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 6361 ev = param_buf->fixed_param; 6362 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 6363 &wmi_handle->final_abi_vers, 6364 &ev->fw_abi_vers)) { 6365 /* 6366 * Error: Our host version and the given firmware version 6367 * are incompatible. 6368 **/ 6369 WMI_LOGD("%s: Error: Incompatible WMI version." 6370 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 6371 __func__, 6372 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 6373 abi_version_0), 6374 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 6375 abi_version_0), 6376 wmi_handle->final_abi_vers.abi_version_ns_0, 6377 wmi_handle->final_abi_vers.abi_version_ns_1, 6378 wmi_handle->final_abi_vers.abi_version_ns_2, 6379 wmi_handle->final_abi_vers.abi_version_ns_3, 6380 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 6381 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 6382 ev->fw_abi_vers.abi_version_ns_0, 6383 ev->fw_abi_vers.abi_version_ns_1, 6384 ev->fw_abi_vers.abi_version_ns_2, 6385 ev->fw_abi_vers.abi_version_ns_3); 6386 6387 return QDF_STATUS_E_FAILURE; 6388 } 6389 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 6390 sizeof(wmi_abi_version)); 6391 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 6392 sizeof(wmi_abi_version)); 6393 6394 return QDF_STATUS_SUCCESS; 6395 } 6396 6397 /** 6398 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 6399 * @handle: wmi handle 6400 * @event: Event received from FW 6401 * @len: Length of the event 6402 * 6403 * Enables the low frequency events and disables the high frequency 6404 * events. Bit 17 indicates if the event if low/high frequency. 6405 * 1 - high frequency, 0 - low frequency 6406 * 6407 * Return: 0 on successfully enabling/disabling the events 6408 */ 6409 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 6410 uint8_t *event, 6411 uint32_t len) 6412 { 6413 uint32_t num_of_diag_events_logs; 6414 wmi_diag_event_log_config_fixed_param *cmd; 6415 wmi_buf_t buf; 6416 uint8_t *buf_ptr; 6417 uint32_t *cmd_args, *evt_args; 6418 uint32_t buf_len, i; 6419 6420 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 6421 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 6422 6423 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 6424 6425 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 6426 if (!param_buf) { 6427 WMI_LOGE("Invalid log supported event buffer"); 6428 return QDF_STATUS_E_INVAL; 6429 } 6430 wmi_event = param_buf->fixed_param; 6431 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 6432 6433 if (num_of_diag_events_logs > 6434 param_buf->num_diag_events_logs_list) { 6435 WMI_LOGE("message number of events %d is more than tlv hdr content %d", 6436 num_of_diag_events_logs, 6437 param_buf->num_diag_events_logs_list); 6438 return QDF_STATUS_E_INVAL; 6439 } 6440 6441 evt_args = param_buf->diag_events_logs_list; 6442 if (!evt_args) { 6443 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d", 6444 __func__, num_of_diag_events_logs); 6445 return QDF_STATUS_E_INVAL; 6446 } 6447 6448 WMI_LOGD("%s: num_of_diag_events_logs=%d", 6449 __func__, num_of_diag_events_logs); 6450 6451 /* Free any previous allocation */ 6452 if (wmi_handle->events_logs_list) 6453 qdf_mem_free(wmi_handle->events_logs_list); 6454 6455 if (num_of_diag_events_logs > 6456 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 6457 WMI_LOGE("%s: excess num of logs:%d", __func__, 6458 num_of_diag_events_logs); 6459 QDF_ASSERT(0); 6460 return QDF_STATUS_E_INVAL; 6461 } 6462 /* Store the event list for run time enable/disable */ 6463 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 6464 sizeof(uint32_t)); 6465 if (!wmi_handle->events_logs_list) 6466 return QDF_STATUS_E_NOMEM; 6467 6468 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 6469 6470 /* Prepare the send buffer */ 6471 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 6472 (num_of_diag_events_logs * sizeof(uint32_t)); 6473 6474 buf = wmi_buf_alloc(wmi_handle, buf_len); 6475 if (!buf) { 6476 qdf_mem_free(wmi_handle->events_logs_list); 6477 wmi_handle->events_logs_list = NULL; 6478 return QDF_STATUS_E_NOMEM; 6479 } 6480 6481 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 6482 buf_ptr = (uint8_t *) cmd; 6483 6484 WMITLV_SET_HDR(&cmd->tlv_header, 6485 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 6486 WMITLV_GET_STRUCT_TLVLEN( 6487 wmi_diag_event_log_config_fixed_param)); 6488 6489 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 6490 6491 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 6492 6493 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6494 (num_of_diag_events_logs * sizeof(uint32_t))); 6495 6496 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 6497 6498 /* Populate the events */ 6499 for (i = 0; i < num_of_diag_events_logs; i++) { 6500 /* Low freq (0) - Enable (1) the event 6501 * High freq (1) - Disable (0) the event 6502 */ 6503 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 6504 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 6505 /* Set the event ID */ 6506 WMI_DIAG_ID_SET(cmd_args[i], 6507 WMI_DIAG_ID_GET(evt_args[i])); 6508 /* Set the type */ 6509 WMI_DIAG_TYPE_SET(cmd_args[i], 6510 WMI_DIAG_TYPE_GET(evt_args[i])); 6511 /* Storing the event/log list in WMI */ 6512 wmi_handle->events_logs_list[i] = evt_args[i]; 6513 } 6514 6515 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 6516 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 6517 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 6518 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 6519 __func__); 6520 wmi_buf_free(buf); 6521 /* Not clearing events_logs_list, though wmi cmd failed. 6522 * Host can still have this list 6523 */ 6524 return QDF_STATUS_E_INVAL; 6525 } 6526 6527 return 0; 6528 } 6529 6530 /** 6531 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 6532 * @wmi_handle: wmi handle 6533 * @start_log: Start logging related parameters 6534 * 6535 * Send the command to the FW based on which specific logging of diag 6536 * event/log id can be started/stopped 6537 * 6538 * Return: None 6539 */ 6540 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 6541 struct wmi_wifi_start_log *start_log) 6542 { 6543 wmi_diag_event_log_config_fixed_param *cmd; 6544 wmi_buf_t buf; 6545 uint8_t *buf_ptr; 6546 uint32_t len, count, log_level, i; 6547 uint32_t *cmd_args; 6548 uint32_t total_len; 6549 count = 0; 6550 6551 if (!wmi_handle->events_logs_list) { 6552 WMI_LOGD("%s: Not received event/log list from FW, yet", 6553 __func__); 6554 return QDF_STATUS_E_NOMEM; 6555 } 6556 /* total_len stores the number of events where BITS 17 and 18 are set. 6557 * i.e., events of high frequency (17) and for extended debugging (18) 6558 */ 6559 total_len = 0; 6560 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 6561 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 6562 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 6563 total_len++; 6564 } 6565 6566 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 6567 (total_len * sizeof(uint32_t)); 6568 6569 buf = wmi_buf_alloc(wmi_handle, len); 6570 if (!buf) 6571 return QDF_STATUS_E_NOMEM; 6572 6573 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 6574 buf_ptr = (uint8_t *) cmd; 6575 6576 WMITLV_SET_HDR(&cmd->tlv_header, 6577 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 6578 WMITLV_GET_STRUCT_TLVLEN( 6579 wmi_diag_event_log_config_fixed_param)); 6580 6581 cmd->num_of_diag_events_logs = total_len; 6582 6583 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 6584 6585 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6586 (total_len * sizeof(uint32_t))); 6587 6588 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 6589 6590 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 6591 log_level = 1; 6592 else 6593 log_level = 0; 6594 6595 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level); 6596 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 6597 uint32_t val = wmi_handle->events_logs_list[i]; 6598 if ((WMI_DIAG_FREQUENCY_GET(val)) && 6599 (WMI_DIAG_EXT_FEATURE_GET(val))) { 6600 6601 WMI_DIAG_ID_SET(cmd_args[count], 6602 WMI_DIAG_ID_GET(val)); 6603 WMI_DIAG_TYPE_SET(cmd_args[count], 6604 WMI_DIAG_TYPE_GET(val)); 6605 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 6606 log_level); 6607 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val); 6608 count++; 6609 } 6610 } 6611 6612 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 6613 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6614 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 6615 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 6616 __func__); 6617 wmi_buf_free(buf); 6618 return QDF_STATUS_E_INVAL; 6619 } 6620 6621 return QDF_STATUS_SUCCESS; 6622 } 6623 6624 /** 6625 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 6626 * @wmi_handle: WMI handle 6627 * 6628 * This function is used to send the flush command to the FW, 6629 * that will flush the fw logs that are residue in the FW 6630 * 6631 * Return: None 6632 */ 6633 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 6634 { 6635 wmi_debug_mesg_flush_fixed_param *cmd; 6636 wmi_buf_t buf; 6637 int len = sizeof(*cmd); 6638 QDF_STATUS ret; 6639 6640 buf = wmi_buf_alloc(wmi_handle, len); 6641 if (!buf) 6642 return QDF_STATUS_E_NOMEM; 6643 6644 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 6645 WMITLV_SET_HDR(&cmd->tlv_header, 6646 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 6647 WMITLV_GET_STRUCT_TLVLEN( 6648 wmi_debug_mesg_flush_fixed_param)); 6649 cmd->reserved0 = 0; 6650 6651 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 6652 ret = wmi_unified_cmd_send(wmi_handle, 6653 buf, 6654 len, 6655 WMI_DEBUG_MESG_FLUSH_CMDID); 6656 if (QDF_IS_STATUS_ERROR(ret)) { 6657 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 6658 wmi_buf_free(buf); 6659 return QDF_STATUS_E_INVAL; 6660 } 6661 WMI_LOGD("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 6662 6663 return ret; 6664 } 6665 6666 #ifdef BIG_ENDIAN_HOST 6667 /** 6668 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 6669 * @param data_len - data length 6670 * @param data - pointer to data 6671 * 6672 * Return: QDF_STATUS - success or error status 6673 */ 6674 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 6675 struct fips_params *param) 6676 { 6677 unsigned char *key_unaligned, *data_unaligned; 6678 int c; 6679 u_int8_t *key_aligned = NULL; 6680 u_int8_t *data_aligned = NULL; 6681 6682 /* Assigning unaligned space to copy the key */ 6683 key_unaligned = qdf_mem_malloc( 6684 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 6685 data_unaligned = qdf_mem_malloc( 6686 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 6687 6688 /* Checking if kmalloc is successful to allocate space */ 6689 if (key_unaligned == NULL) 6690 return QDF_STATUS_SUCCESS; 6691 /* Checking if space is aligned */ 6692 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 6693 /* align to 4 */ 6694 key_aligned = 6695 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 6696 FIPS_ALIGN); 6697 } else { 6698 key_aligned = (u_int8_t *)key_unaligned; 6699 } 6700 6701 /* memset and copy content from key to key aligned */ 6702 OS_MEMSET(key_aligned, 0, param->key_len); 6703 OS_MEMCPY(key_aligned, param->key, param->key_len); 6704 6705 /* print a hexdump for host debug */ 6706 print_hex_dump(KERN_DEBUG, 6707 "\t Aligned and Copied Key:@@@@ ", 6708 DUMP_PREFIX_NONE, 6709 16, 1, key_aligned, param->key_len, true); 6710 6711 /* Checking if kmalloc is successful to allocate space */ 6712 if (data_unaligned == NULL) 6713 return QDF_STATUS_SUCCESS; 6714 /* Checking of space is aligned */ 6715 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 6716 /* align to 4 */ 6717 data_aligned = 6718 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 6719 FIPS_ALIGN); 6720 } else { 6721 data_aligned = (u_int8_t *)data_unaligned; 6722 } 6723 6724 /* memset and copy content from data to data aligned */ 6725 OS_MEMSET(data_aligned, 0, param->data_len); 6726 OS_MEMCPY(data_aligned, param->data, param->data_len); 6727 6728 /* print a hexdump for host debug */ 6729 print_hex_dump(KERN_DEBUG, 6730 "\t Properly Aligned and Copied Data:@@@@ ", 6731 DUMP_PREFIX_NONE, 6732 16, 1, data_aligned, param->data_len, true); 6733 6734 /* converting to little Endian both key_aligned and 6735 * data_aligned*/ 6736 for (c = 0; c < param->key_len/4; c++) { 6737 *((u_int32_t *)key_aligned+c) = 6738 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 6739 } 6740 for (c = 0; c < param->data_len/4; c++) { 6741 *((u_int32_t *)data_aligned+c) = 6742 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 6743 } 6744 6745 /* update endian data to key and data vectors */ 6746 OS_MEMCPY(param->key, key_aligned, param->key_len); 6747 OS_MEMCPY(param->data, data_aligned, param->data_len); 6748 6749 /* clean up allocated spaces */ 6750 qdf_mem_free(key_unaligned); 6751 key_unaligned = NULL; 6752 key_aligned = NULL; 6753 6754 qdf_mem_free(data_unaligned); 6755 data_unaligned = NULL; 6756 data_aligned = NULL; 6757 6758 return QDF_STATUS_SUCCESS; 6759 } 6760 #else 6761 /** 6762 * fips_align_data_be() - DUMMY for LE platform 6763 * 6764 * Return: QDF_STATUS - success 6765 */ 6766 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 6767 struct fips_params *param) 6768 { 6769 return QDF_STATUS_SUCCESS; 6770 } 6771 #endif 6772 6773 /** 6774 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 6775 * @wmi_handle: wmi handle 6776 * @param: pointer to hold pdev fips param 6777 * 6778 * Return: 0 for success or error code 6779 */ 6780 static QDF_STATUS 6781 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 6782 struct fips_params *param) 6783 { 6784 wmi_pdev_fips_cmd_fixed_param *cmd; 6785 wmi_buf_t buf; 6786 uint8_t *buf_ptr; 6787 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 6788 QDF_STATUS retval = QDF_STATUS_SUCCESS; 6789 6790 /* Length TLV placeholder for array of bytes */ 6791 len += WMI_TLV_HDR_SIZE; 6792 if (param->data_len) 6793 len += (param->data_len*sizeof(uint8_t)); 6794 6795 /* 6796 * Data length must be multiples of 16 bytes - checked against 0xF - 6797 * and must be less than WMI_SVC_MSG_SIZE - static size of 6798 * wmi_pdev_fips_cmd structure 6799 */ 6800 6801 /* do sanity on the input */ 6802 if (!(((param->data_len & 0xF) == 0) && 6803 ((param->data_len > 0) && 6804 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 6805 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 6806 return QDF_STATUS_E_INVAL; 6807 } 6808 6809 buf = wmi_buf_alloc(wmi_handle, len); 6810 if (!buf) 6811 return QDF_STATUS_E_FAILURE; 6812 6813 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6814 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 6815 WMITLV_SET_HDR(&cmd->tlv_header, 6816 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 6817 WMITLV_GET_STRUCT_TLVLEN 6818 (wmi_pdev_fips_cmd_fixed_param)); 6819 6820 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6821 param->pdev_id); 6822 if (param->key != NULL && param->data != NULL) { 6823 cmd->key_len = param->key_len; 6824 cmd->data_len = param->data_len; 6825 cmd->fips_cmd = !!(param->op); 6826 6827 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 6828 return QDF_STATUS_E_FAILURE; 6829 6830 qdf_mem_copy(cmd->key, param->key, param->key_len); 6831 6832 if (param->mode == FIPS_ENGINE_AES_CTR || 6833 param->mode == FIPS_ENGINE_AES_MIC) { 6834 cmd->mode = param->mode; 6835 } else { 6836 cmd->mode = FIPS_ENGINE_AES_CTR; 6837 } 6838 qdf_print("Key len = %d, Data len = %d", 6839 cmd->key_len, cmd->data_len); 6840 6841 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 6842 cmd->key, cmd->key_len, true); 6843 buf_ptr += sizeof(*cmd); 6844 6845 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 6846 6847 buf_ptr += WMI_TLV_HDR_SIZE; 6848 if (param->data_len) 6849 qdf_mem_copy(buf_ptr, 6850 (uint8_t *) param->data, param->data_len); 6851 6852 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 6853 16, 1, buf_ptr, cmd->data_len, true); 6854 6855 buf_ptr += param->data_len; 6856 6857 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 6858 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 6859 WMI_PDEV_FIPS_CMDID); 6860 qdf_print("%s return value %d", __func__, retval); 6861 } else { 6862 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 6863 wmi_buf_free(buf); 6864 retval = -QDF_STATUS_E_BADMSG; 6865 } 6866 6867 return retval; 6868 } 6869 6870 /** 6871 * send_fw_test_cmd_tlv() - send fw test command to fw. 6872 * @wmi_handle: wmi handle 6873 * @wmi_fwtest: fw test command 6874 * 6875 * This function sends fw test command to fw. 6876 * 6877 * Return: CDF STATUS 6878 */ 6879 static 6880 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 6881 struct set_fwtest_params *wmi_fwtest) 6882 { 6883 wmi_fwtest_set_param_cmd_fixed_param *cmd; 6884 wmi_buf_t wmi_buf; 6885 uint16_t len; 6886 6887 len = sizeof(*cmd); 6888 6889 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6890 if (!wmi_buf) 6891 return QDF_STATUS_E_NOMEM; 6892 6893 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 6894 WMITLV_SET_HDR(&cmd->tlv_header, 6895 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 6896 WMITLV_GET_STRUCT_TLVLEN( 6897 wmi_fwtest_set_param_cmd_fixed_param)); 6898 cmd->param_id = wmi_fwtest->arg; 6899 cmd->param_value = wmi_fwtest->value; 6900 6901 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 6902 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6903 WMI_FWTEST_CMDID)) { 6904 WMI_LOGP("%s: failed to send fw test command", __func__); 6905 wmi_buf_free(wmi_buf); 6906 return QDF_STATUS_E_FAILURE; 6907 } 6908 6909 return QDF_STATUS_SUCCESS; 6910 } 6911 6912 /** 6913 * send_unit_test_cmd_tlv() - send unit test command to fw. 6914 * @wmi_handle: wmi handle 6915 * @wmi_utest: unit test command 6916 * 6917 * This function send unit test command to fw. 6918 * 6919 * Return: CDF STATUS 6920 */ 6921 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 6922 struct wmi_unit_test_cmd *wmi_utest) 6923 { 6924 wmi_unit_test_cmd_fixed_param *cmd; 6925 wmi_buf_t wmi_buf; 6926 uint8_t *buf_ptr; 6927 int i; 6928 uint16_t len, args_tlv_len; 6929 uint32_t *unit_test_cmd_args; 6930 6931 args_tlv_len = 6932 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 6933 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 6934 6935 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6936 if (!wmi_buf) 6937 return QDF_STATUS_E_NOMEM; 6938 6939 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 6940 buf_ptr = (uint8_t *) cmd; 6941 WMITLV_SET_HDR(&cmd->tlv_header, 6942 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 6943 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 6944 cmd->vdev_id = wmi_utest->vdev_id; 6945 cmd->module_id = wmi_utest->module_id; 6946 cmd->num_args = wmi_utest->num_args; 6947 cmd->diag_token = wmi_utest->diag_token; 6948 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 6949 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6950 (wmi_utest->num_args * sizeof(uint32_t))); 6951 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 6952 WMI_LOGI("%s: VDEV ID: %d", __func__, cmd->vdev_id); 6953 WMI_LOGI("%s: MODULE ID: %d", __func__, cmd->module_id); 6954 WMI_LOGI("%s: TOKEN: %d", __func__, cmd->diag_token); 6955 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args); 6956 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 6957 unit_test_cmd_args[i] = wmi_utest->args[i]; 6958 WMI_LOGI("%d,", wmi_utest->args[i]); 6959 } 6960 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 6961 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6962 WMI_UNIT_TEST_CMDID)) { 6963 WMI_LOGP("%s: failed to send unit test command", __func__); 6964 wmi_buf_free(wmi_buf); 6965 return QDF_STATUS_E_FAILURE; 6966 } 6967 6968 return QDF_STATUS_SUCCESS; 6969 } 6970 6971 /** 6972 * send_power_dbg_cmd_tlv() - send power debug commands 6973 * @wmi_handle: wmi handle 6974 * @param: wmi power debug parameter 6975 * 6976 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 6977 * 6978 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 6979 */ 6980 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 6981 struct wmi_power_dbg_params *param) 6982 { 6983 wmi_buf_t buf = NULL; 6984 QDF_STATUS status; 6985 int len, args_tlv_len; 6986 uint8_t *buf_ptr; 6987 uint8_t i; 6988 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 6989 uint32_t *cmd_args; 6990 6991 /* Prepare and send power debug cmd parameters */ 6992 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 6993 len = sizeof(*cmd) + args_tlv_len; 6994 buf = wmi_buf_alloc(wmi_handle, len); 6995 if (!buf) 6996 return QDF_STATUS_E_NOMEM; 6997 6998 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6999 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 7000 WMITLV_SET_HDR(&cmd->tlv_header, 7001 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 7002 WMITLV_GET_STRUCT_TLVLEN 7003 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 7004 7005 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7006 param->pdev_id); 7007 cmd->module_id = param->module_id; 7008 cmd->num_args = param->num_args; 7009 buf_ptr += sizeof(*cmd); 7010 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7011 (param->num_args * sizeof(uint32_t))); 7012 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 7013 WMI_LOGI("%s: %d num of args = ", __func__, param->num_args); 7014 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 7015 cmd_args[i] = param->args[i]; 7016 WMI_LOGI("%d,", param->args[i]); 7017 } 7018 7019 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 7020 status = wmi_unified_cmd_send(wmi_handle, buf, 7021 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 7022 if (QDF_IS_STATUS_ERROR(status)) { 7023 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 7024 status); 7025 goto error; 7026 } 7027 7028 return QDF_STATUS_SUCCESS; 7029 error: 7030 wmi_buf_free(buf); 7031 7032 return status; 7033 } 7034 7035 /** 7036 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 7037 * @wmi_handle: wmi handle 7038 * @pdev_id: pdev id 7039 * 7040 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 7041 * 7042 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 7043 */ 7044 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7045 uint32_t pdev_id) 7046 { 7047 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 7048 wmi_buf_t buf; 7049 uint16_t len; 7050 QDF_STATUS ret; 7051 7052 len = sizeof(*cmd); 7053 buf = wmi_buf_alloc(wmi_handle, len); 7054 7055 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 7056 7057 if (!buf) 7058 return QDF_STATUS_E_NOMEM; 7059 7060 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 7061 wmi_buf_data(buf); 7062 7063 WMITLV_SET_HDR(&cmd->tlv_header, 7064 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 7065 WMITLV_GET_STRUCT_TLVLEN( 7066 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 7067 7068 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 7069 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 7070 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7071 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 7072 if (QDF_IS_STATUS_ERROR(ret)) { 7073 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 7074 __func__, ret, pdev_id); 7075 wmi_buf_free(buf); 7076 return QDF_STATUS_E_FAILURE; 7077 } 7078 7079 return QDF_STATUS_SUCCESS; 7080 } 7081 7082 /** 7083 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 7084 * @wmi_handle: wmi handle 7085 * @pdev_id: pdev id 7086 * 7087 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 7088 * 7089 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 7090 */ 7091 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 7092 uint32_t pdev_id) 7093 { 7094 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 7095 wmi_buf_t buf; 7096 uint16_t len; 7097 QDF_STATUS ret; 7098 7099 len = sizeof(*cmd); 7100 buf = wmi_buf_alloc(wmi_handle, len); 7101 7102 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 7103 7104 if (!buf) 7105 return QDF_STATUS_E_NOMEM; 7106 7107 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 7108 wmi_buf_data(buf); 7109 7110 WMITLV_SET_HDR(&cmd->tlv_header, 7111 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 7112 WMITLV_GET_STRUCT_TLVLEN( 7113 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 7114 7115 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 7116 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 7117 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7118 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 7119 if (QDF_IS_STATUS_ERROR(ret)) { 7120 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 7121 __func__, ret, pdev_id); 7122 wmi_buf_free(buf); 7123 return QDF_STATUS_E_FAILURE; 7124 } 7125 7126 return QDF_STATUS_SUCCESS; 7127 } 7128 7129 /** 7130 * init_cmd_send_tlv() - send initialization cmd to fw 7131 * @wmi_handle: wmi handle 7132 * @param param: pointer to wmi init param 7133 * 7134 * Return: QDF_STATUS_SUCCESS for success or error code 7135 */ 7136 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 7137 struct wmi_init_cmd_param *param) 7138 { 7139 wmi_buf_t buf; 7140 wmi_init_cmd_fixed_param *cmd; 7141 uint8_t *buf_ptr; 7142 wmi_resource_config *resource_cfg; 7143 wlan_host_memory_chunk *host_mem_chunks; 7144 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 7145 uint16_t idx; 7146 int len; 7147 QDF_STATUS ret; 7148 7149 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 7150 WMI_TLV_HDR_SIZE; 7151 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 7152 7153 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 7154 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 7155 WMI_TLV_HDR_SIZE + 7156 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 7157 7158 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 7159 if (!buf) 7160 return QDF_STATUS_E_FAILURE; 7161 7162 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7163 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 7164 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 7165 7166 host_mem_chunks = (wlan_host_memory_chunk *) 7167 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 7168 + WMI_TLV_HDR_SIZE); 7169 7170 WMITLV_SET_HDR(&cmd->tlv_header, 7171 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 7172 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 7173 7174 wmi_copy_resource_config(resource_cfg, param->res_cfg); 7175 WMITLV_SET_HDR(&resource_cfg->tlv_header, 7176 WMITLV_TAG_STRUC_wmi_resource_config, 7177 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 7178 7179 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 7180 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 7181 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 7182 WMITLV_GET_STRUCT_TLVLEN 7183 (wlan_host_memory_chunk)); 7184 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 7185 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 7186 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 7187 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 7188 "chunk %d len %d requested ,ptr 0x%x ", 7189 idx, host_mem_chunks[idx].size, 7190 host_mem_chunks[idx].ptr); 7191 } 7192 cmd->num_host_mem_chunks = param->num_mem_chunks; 7193 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 7194 7195 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 7196 WMITLV_TAG_ARRAY_STRUC, 7197 (sizeof(wlan_host_memory_chunk) * 7198 param->num_mem_chunks)); 7199 7200 /* Fill hw mode id config */ 7201 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 7202 7203 /* Fill fw_abi_vers */ 7204 copy_fw_abi_version_tlv(wmi_handle, cmd); 7205 7206 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 7207 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 7208 if (QDF_IS_STATUS_ERROR(ret)) { 7209 WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 7210 ret); 7211 wmi_buf_free(buf); 7212 } 7213 7214 return ret; 7215 7216 } 7217 7218 /** 7219 * send_addba_send_cmd_tlv() - send addba send command to fw 7220 * @wmi_handle: wmi handle 7221 * @param: pointer to delba send params 7222 * @macaddr: peer mac address 7223 * 7224 * Send WMI_ADDBA_SEND_CMDID command to firmware 7225 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 7226 */ 7227 static QDF_STATUS 7228 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 7229 uint8_t macaddr[IEEE80211_ADDR_LEN], 7230 struct addba_send_params *param) 7231 { 7232 wmi_addba_send_cmd_fixed_param *cmd; 7233 wmi_buf_t buf; 7234 uint16_t len; 7235 QDF_STATUS ret; 7236 7237 len = sizeof(*cmd); 7238 7239 buf = wmi_buf_alloc(wmi_handle, len); 7240 if (!buf) 7241 return QDF_STATUS_E_NOMEM; 7242 7243 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 7244 7245 WMITLV_SET_HDR(&cmd->tlv_header, 7246 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 7247 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 7248 7249 cmd->vdev_id = param->vdev_id; 7250 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 7251 cmd->tid = param->tidno; 7252 cmd->buffersize = param->buffersize; 7253 7254 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 7255 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 7256 if (QDF_IS_STATUS_ERROR(ret)) { 7257 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 7258 wmi_buf_free(buf); 7259 return QDF_STATUS_E_FAILURE; 7260 } 7261 7262 return QDF_STATUS_SUCCESS; 7263 } 7264 7265 /** 7266 * send_delba_send_cmd_tlv() - send delba send command to fw 7267 * @wmi_handle: wmi handle 7268 * @param: pointer to delba send params 7269 * @macaddr: peer mac address 7270 * 7271 * Send WMI_DELBA_SEND_CMDID command to firmware 7272 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 7273 */ 7274 static QDF_STATUS 7275 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 7276 uint8_t macaddr[IEEE80211_ADDR_LEN], 7277 struct delba_send_params *param) 7278 { 7279 wmi_delba_send_cmd_fixed_param *cmd; 7280 wmi_buf_t buf; 7281 uint16_t len; 7282 QDF_STATUS ret; 7283 7284 len = sizeof(*cmd); 7285 7286 buf = wmi_buf_alloc(wmi_handle, len); 7287 if (!buf) 7288 return QDF_STATUS_E_NOMEM; 7289 7290 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 7291 7292 WMITLV_SET_HDR(&cmd->tlv_header, 7293 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 7294 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 7295 7296 cmd->vdev_id = param->vdev_id; 7297 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 7298 cmd->tid = param->tidno; 7299 cmd->initiator = param->initiator; 7300 cmd->reasoncode = param->reasoncode; 7301 7302 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 7303 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 7304 if (QDF_IS_STATUS_ERROR(ret)) { 7305 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 7306 wmi_buf_free(buf); 7307 return QDF_STATUS_E_FAILURE; 7308 } 7309 7310 return QDF_STATUS_SUCCESS; 7311 } 7312 7313 /** 7314 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 7315 * to fw 7316 * @wmi_handle: wmi handle 7317 * @param: pointer to addba clearresp params 7318 * @macaddr: peer mac address 7319 * Return: 0 for success or error code 7320 */ 7321 static QDF_STATUS 7322 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 7323 uint8_t macaddr[IEEE80211_ADDR_LEN], 7324 struct addba_clearresponse_params *param) 7325 { 7326 wmi_addba_clear_resp_cmd_fixed_param *cmd; 7327 wmi_buf_t buf; 7328 uint16_t len; 7329 QDF_STATUS ret; 7330 7331 len = sizeof(*cmd); 7332 7333 buf = wmi_buf_alloc(wmi_handle, len); 7334 if (!buf) 7335 return QDF_STATUS_E_FAILURE; 7336 7337 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 7338 7339 WMITLV_SET_HDR(&cmd->tlv_header, 7340 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 7341 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 7342 7343 cmd->vdev_id = param->vdev_id; 7344 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 7345 7346 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 7347 ret = wmi_unified_cmd_send(wmi_handle, 7348 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 7349 if (QDF_IS_STATUS_ERROR(ret)) { 7350 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 7351 wmi_buf_free(buf); 7352 return QDF_STATUS_E_FAILURE; 7353 } 7354 7355 return QDF_STATUS_SUCCESS; 7356 } 7357 7358 #ifdef OBSS_PD 7359 /** 7360 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 7361 * def thresh to fw 7362 * @wmi_handle: wmi handle 7363 * @thresh: pointer to obss_spatial_reuse_def_thresh 7364 * 7365 * Return: QDF_STATUS_SUCCESS for success or error code 7366 */ 7367 static 7368 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 7369 wmi_unified_t wmi_handle, 7370 struct wmi_host_obss_spatial_reuse_set_def_thresh 7371 *thresh) 7372 { 7373 wmi_buf_t buf; 7374 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 7375 QDF_STATUS ret; 7376 uint32_t cmd_len; 7377 uint32_t tlv_len; 7378 7379 cmd_len = sizeof(*cmd); 7380 7381 buf = wmi_buf_alloc(wmi_handle, cmd_len); 7382 if (!buf) 7383 return QDF_STATUS_E_NOMEM; 7384 7385 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 7386 wmi_buf_data(buf); 7387 7388 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 7389 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 7390 7391 WMITLV_SET_HDR(&cmd->tlv_header, 7392 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 7393 tlv_len); 7394 7395 cmd->obss_min = thresh->obss_min; 7396 cmd->obss_max = thresh->obss_max; 7397 cmd->vdev_type = thresh->vdev_type; 7398 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 7399 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 7400 if (QDF_IS_STATUS_ERROR(ret)) 7401 wmi_buf_free(buf); 7402 7403 return ret; 7404 } 7405 7406 /** 7407 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 7408 * @wmi_handle: wmi handle 7409 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 7410 * 7411 * Return: QDF_STATUS_SUCCESS for success or error code 7412 */ 7413 static 7414 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 7415 struct wmi_host_obss_spatial_reuse_set_param 7416 *obss_spatial_reuse_param) 7417 { 7418 wmi_buf_t buf; 7419 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 7420 QDF_STATUS ret; 7421 uint32_t len; 7422 7423 len = sizeof(*cmd); 7424 7425 buf = wmi_buf_alloc(wmi_handle, len); 7426 if (!buf) 7427 return QDF_STATUS_E_FAILURE; 7428 7429 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 7430 WMITLV_SET_HDR(&cmd->tlv_header, 7431 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 7432 WMITLV_GET_STRUCT_TLVLEN 7433 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 7434 7435 cmd->enable = obss_spatial_reuse_param->enable; 7436 cmd->obss_min = obss_spatial_reuse_param->obss_min; 7437 cmd->obss_max = obss_spatial_reuse_param->obss_max; 7438 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 7439 7440 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7441 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 7442 7443 if (QDF_IS_STATUS_ERROR(ret)) { 7444 WMI_LOGE( 7445 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 7446 ret); 7447 wmi_buf_free(buf); 7448 } 7449 7450 return ret; 7451 } 7452 #endif 7453 7454 #ifdef QCA_SUPPORT_CP_STATS 7455 /** 7456 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 7457 * @wmi_handle: wma handle 7458 * @evt_buf: event buffer 7459 * @out_buff: buffer to populated after stats extraction 7460 * 7461 * Return: status of operation 7462 */ 7463 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 7464 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 7465 { 7466 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 7467 wmi_congestion_stats *congestion_stats; 7468 7469 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 7470 congestion_stats = param_buf->congestion_stats; 7471 if (!congestion_stats) { 7472 WMI_LOGD("%s: no cca stats in event buffer", __func__); 7473 return QDF_STATUS_E_INVAL; 7474 } 7475 7476 out_buff->vdev_id = congestion_stats->vdev_id; 7477 out_buff->congestion = congestion_stats->congestion; 7478 7479 WMI_LOGD("%s: cca stats event processed", __func__); 7480 return QDF_STATUS_SUCCESS; 7481 } 7482 #endif /* QCA_SUPPORT_CP_STATS */ 7483 7484 /** 7485 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 7486 * event 7487 * @wmi_handle: wmi handle 7488 * @param evt_buf: pointer to event buffer 7489 * @param param: Pointer to hold peer ctl data 7490 * 7491 * Return: QDF_STATUS_SUCCESS for success or error code 7492 */ 7493 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 7494 wmi_unified_t wmi_handle, 7495 void *evt_buf, 7496 struct wmi_host_pdev_ctl_failsafe_event *param) 7497 { 7498 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 7499 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 7500 7501 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 7502 if (!param_buf) { 7503 WMI_LOGE("Invalid ctl_failsafe event buffer"); 7504 return QDF_STATUS_E_INVAL; 7505 } 7506 7507 fix_param = param_buf->fixed_param; 7508 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 7509 7510 return QDF_STATUS_SUCCESS; 7511 } 7512 7513 /** 7514 * save_service_bitmap_tlv() - save service bitmap 7515 * @wmi_handle: wmi handle 7516 * @param evt_buf: pointer to event buffer 7517 * @param bitmap_buf: bitmap buffer, for converged legacy support 7518 * 7519 * Return: QDF_STATUS 7520 */ 7521 static 7522 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 7523 void *bitmap_buf) 7524 { 7525 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 7526 struct wmi_soc *soc = wmi_handle->soc; 7527 7528 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 7529 7530 /* If it is already allocated, use that buffer. This can happen 7531 * during target stop/start scenarios where host allocation is skipped. 7532 */ 7533 if (!soc->wmi_service_bitmap) { 7534 soc->wmi_service_bitmap = 7535 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 7536 if (!soc->wmi_service_bitmap) 7537 return QDF_STATUS_E_NOMEM; 7538 } 7539 7540 qdf_mem_copy(soc->wmi_service_bitmap, 7541 param_buf->wmi_service_bitmap, 7542 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 7543 7544 if (bitmap_buf) 7545 qdf_mem_copy(bitmap_buf, 7546 param_buf->wmi_service_bitmap, 7547 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 7548 7549 return QDF_STATUS_SUCCESS; 7550 } 7551 7552 /** 7553 * save_ext_service_bitmap_tlv() - save extendend service bitmap 7554 * @wmi_handle: wmi handle 7555 * @param evt_buf: pointer to event buffer 7556 * @param bitmap_buf: bitmap buffer, for converged legacy support 7557 * 7558 * Return: QDF_STATUS 7559 */ 7560 static 7561 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 7562 void *bitmap_buf) 7563 { 7564 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 7565 wmi_service_available_event_fixed_param *ev; 7566 struct wmi_soc *soc = wmi_handle->soc; 7567 7568 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 7569 7570 ev = param_buf->fixed_param; 7571 7572 /* If it is already allocated, use that buffer. This can happen 7573 * during target stop/start scenarios where host allocation is skipped. 7574 */ 7575 if (!soc->wmi_ext_service_bitmap) { 7576 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 7577 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 7578 if (!soc->wmi_ext_service_bitmap) 7579 return QDF_STATUS_E_NOMEM; 7580 } 7581 7582 qdf_mem_copy(soc->wmi_ext_service_bitmap, 7583 ev->wmi_service_segment_bitmap, 7584 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 7585 7586 WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 7587 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 7588 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 7589 7590 if (bitmap_buf) 7591 qdf_mem_copy(bitmap_buf, 7592 soc->wmi_ext_service_bitmap, 7593 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 7594 7595 return QDF_STATUS_SUCCESS; 7596 } 7597 /** 7598 * is_service_enabled_tlv() - Check if service enabled 7599 * @param wmi_handle: wmi handle 7600 * @param service_id: service identifier 7601 * 7602 * Return: 1 enabled, 0 disabled 7603 */ 7604 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 7605 uint32_t service_id) 7606 { 7607 struct wmi_soc *soc = wmi_handle->soc; 7608 7609 if (!soc->wmi_service_bitmap) { 7610 WMI_LOGE("WMI service bit map is not saved yet"); 7611 return false; 7612 } 7613 7614 /* if wmi_service_enabled was received with extended bitmap, 7615 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 7616 */ 7617 if (soc->wmi_ext_service_bitmap) 7618 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 7619 soc->wmi_ext_service_bitmap, 7620 service_id); 7621 7622 if (service_id >= WMI_MAX_SERVICE) { 7623 WMI_LOGE("Service id %d but WMI ext service bitmap is NULL", 7624 service_id); 7625 return false; 7626 } 7627 7628 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 7629 service_id); 7630 } 7631 7632 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 7633 struct wlan_psoc_target_capability_info *cap) 7634 { 7635 /* except LDPC all flags are common betwen legacy and here 7636 * also IBFEER is not defined for TLV 7637 */ 7638 cap->ht_cap_info |= ev_target_cap & ( 7639 WMI_HT_CAP_ENABLED 7640 | WMI_HT_CAP_HT20_SGI 7641 | WMI_HT_CAP_DYNAMIC_SMPS 7642 | WMI_HT_CAP_TX_STBC 7643 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 7644 | WMI_HT_CAP_RX_STBC 7645 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 7646 | WMI_HT_CAP_LDPC 7647 | WMI_HT_CAP_L_SIG_TXOP_PROT 7648 | WMI_HT_CAP_MPDU_DENSITY 7649 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 7650 | WMI_HT_CAP_HT40_SGI); 7651 if (ev_target_cap & WMI_HT_CAP_LDPC) 7652 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 7653 WMI_HOST_HT_CAP_TX_LDPC; 7654 } 7655 /** 7656 * extract_service_ready_tlv() - extract service ready event 7657 * @wmi_handle: wmi handle 7658 * @param evt_buf: pointer to received event buffer 7659 * @param cap: pointer to hold target capability information extracted from even 7660 * 7661 * Return: QDF_STATUS_SUCCESS for success or error code 7662 */ 7663 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 7664 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 7665 { 7666 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 7667 wmi_service_ready_event_fixed_param *ev; 7668 7669 7670 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 7671 7672 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 7673 if (!ev) { 7674 qdf_print("%s: wmi_buf_alloc failed", __func__); 7675 return QDF_STATUS_E_FAILURE; 7676 } 7677 7678 cap->phy_capability = ev->phy_capability; 7679 cap->max_frag_entry = ev->max_frag_entry; 7680 cap->num_rf_chains = ev->num_rf_chains; 7681 copy_ht_cap_info(ev->ht_cap_info, cap); 7682 cap->vht_cap_info = ev->vht_cap_info; 7683 cap->vht_supp_mcs = ev->vht_supp_mcs; 7684 cap->hw_min_tx_power = ev->hw_min_tx_power; 7685 cap->hw_max_tx_power = ev->hw_max_tx_power; 7686 cap->sys_cap_info = ev->sys_cap_info; 7687 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 7688 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 7689 cap->max_num_scan_channels = ev->max_num_scan_channels; 7690 cap->max_supported_macs = ev->max_supported_macs; 7691 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 7692 cap->txrx_chainmask = ev->txrx_chainmask; 7693 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 7694 cap->num_msdu_desc = ev->num_msdu_desc; 7695 cap->fw_version = ev->fw_build_vers; 7696 /* fw_version_1 is not available in TLV. */ 7697 cap->fw_version_1 = 0; 7698 7699 return QDF_STATUS_SUCCESS; 7700 } 7701 7702 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 7703 * to host internal WMI_HOST_REGDMN_MODE values. 7704 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 7705 * host currently. Add this in the future if required. 7706 * 11AX (Phase II) : 11ax related values are not currently 7707 * advertised separately by FW. As part of phase II regulatory bring-up, 7708 * finalize the advertisement mechanism. 7709 * @target_wireless_mode: target wireless mode received in message 7710 * 7711 * Return: returns the host internal wireless mode. 7712 */ 7713 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 7714 { 7715 7716 uint32_t wireless_modes = 0; 7717 7718 WMI_LOGD("Target wireless mode: 0x%x", target_wireless_mode); 7719 7720 if (target_wireless_mode & REGDMN_MODE_11A) 7721 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 7722 7723 if (target_wireless_mode & REGDMN_MODE_TURBO) 7724 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 7725 7726 if (target_wireless_mode & REGDMN_MODE_11B) 7727 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 7728 7729 if (target_wireless_mode & REGDMN_MODE_PUREG) 7730 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 7731 7732 if (target_wireless_mode & REGDMN_MODE_11G) 7733 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 7734 7735 if (target_wireless_mode & REGDMN_MODE_108G) 7736 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 7737 7738 if (target_wireless_mode & REGDMN_MODE_108A) 7739 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 7740 7741 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 7742 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20_2G; 7743 7744 if (target_wireless_mode & REGDMN_MODE_XR) 7745 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 7746 7747 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 7748 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 7749 7750 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 7751 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 7752 7753 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 7754 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 7755 7756 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 7757 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 7758 7759 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 7760 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 7761 7762 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 7763 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 7764 7765 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 7766 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 7767 7768 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 7769 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 7770 7771 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 7772 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 7773 7774 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 7775 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 7776 7777 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 7778 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 7779 7780 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 7781 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 7782 7783 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 7784 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 7785 7786 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 7787 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 7788 7789 return wireless_modes; 7790 } 7791 7792 /** 7793 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 7794 * @wmi_handle: wmi handle 7795 * @param evt_buf: Pointer to event buffer 7796 * @param cap: pointer to hold HAL reg capabilities 7797 * 7798 * Return: QDF_STATUS_SUCCESS for success or error code 7799 */ 7800 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 7801 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 7802 { 7803 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 7804 7805 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 7806 if (!param_buf || !param_buf->hal_reg_capabilities) { 7807 WMI_LOGE("%s: Invalid arguments", __func__); 7808 return QDF_STATUS_E_FAILURE; 7809 } 7810 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 7811 sizeof(uint32_t)), 7812 sizeof(struct wlan_psoc_hal_reg_capability)); 7813 7814 cap->wireless_modes = convert_wireless_modes_tlv( 7815 param_buf->hal_reg_capabilities->wireless_modes); 7816 7817 return QDF_STATUS_SUCCESS; 7818 } 7819 7820 /** 7821 * extract_host_mem_req_tlv() - Extract host memory request event 7822 * @wmi_handle: wmi handle 7823 * @param evt_buf: pointer to event buffer 7824 * @param num_entries: pointer to hold number of entries requested 7825 * 7826 * Return: Number of entries requested 7827 */ 7828 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 7829 void *evt_buf, uint8_t *num_entries) 7830 { 7831 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 7832 wmi_service_ready_event_fixed_param *ev; 7833 7834 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 7835 7836 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 7837 if (!ev) { 7838 qdf_print("%s: wmi_buf_alloc failed", __func__); 7839 return NULL; 7840 } 7841 7842 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 7843 WMI_LOGE("Invalid num_mem_reqs %d:%d", 7844 ev->num_mem_reqs, param_buf->num_mem_reqs); 7845 return NULL; 7846 } 7847 7848 *num_entries = ev->num_mem_reqs; 7849 7850 return (host_mem_req *)param_buf->mem_reqs; 7851 } 7852 7853 /** 7854 * save_fw_version_in_service_ready_tlv() - Save fw version in service 7855 * ready function 7856 * @wmi_handle: wmi handle 7857 * @param evt_buf: pointer to event buffer 7858 * 7859 * Return: QDF_STATUS_SUCCESS for success or error code 7860 */ 7861 static QDF_STATUS 7862 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 7863 { 7864 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 7865 wmi_service_ready_event_fixed_param *ev; 7866 7867 7868 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 7869 7870 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 7871 if (!ev) { 7872 qdf_print("%s: wmi_buf_alloc failed", __func__); 7873 return QDF_STATUS_E_FAILURE; 7874 } 7875 7876 /*Save fw version from service ready message */ 7877 /*This will be used while sending INIT message */ 7878 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 7879 sizeof(wmi_handle->fw_abi_version)); 7880 7881 return QDF_STATUS_SUCCESS; 7882 } 7883 7884 /** 7885 * ready_extract_init_status_tlv() - Extract init status from ready event 7886 * @wmi_handle: wmi handle 7887 * @param evt_buf: Pointer to event buffer 7888 * 7889 * Return: ready status 7890 */ 7891 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 7892 void *evt_buf) 7893 { 7894 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 7895 wmi_ready_event_fixed_param *ev = NULL; 7896 7897 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 7898 ev = param_buf->fixed_param; 7899 7900 qdf_print("%s:%d", __func__, ev->status); 7901 7902 return ev->status; 7903 } 7904 7905 /** 7906 * ready_extract_mac_addr_tlv() - extract mac address from ready event 7907 * @wmi_handle: wmi handle 7908 * @param evt_buf: pointer to event buffer 7909 * @param macaddr: Pointer to hold MAC address 7910 * 7911 * Return: QDF_STATUS_SUCCESS for success or error code 7912 */ 7913 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 7914 void *evt_buf, uint8_t *macaddr) 7915 { 7916 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 7917 wmi_ready_event_fixed_param *ev = NULL; 7918 7919 7920 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 7921 ev = param_buf->fixed_param; 7922 7923 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 7924 7925 return QDF_STATUS_SUCCESS; 7926 } 7927 7928 /** 7929 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 7930 * @wmi_handle: wmi handle 7931 * @param evt_buf: pointer to event buffer 7932 * @param macaddr: Pointer to hold number of MAC addresses 7933 * 7934 * Return: Pointer to addr list 7935 */ 7936 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 7937 void *evt_buf, uint8_t *num_mac) 7938 { 7939 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 7940 wmi_ready_event_fixed_param *ev = NULL; 7941 7942 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 7943 ev = param_buf->fixed_param; 7944 7945 *num_mac = ev->num_extra_mac_addr; 7946 7947 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 7948 } 7949 7950 /** 7951 * extract_ready_params_tlv() - Extract data from ready event apart from 7952 * status, macaddr and version. 7953 * @wmi_handle: Pointer to WMI handle. 7954 * @evt_buf: Pointer to Ready event buffer. 7955 * @ev_param: Pointer to host defined struct to copy the data from event. 7956 * 7957 * Return: QDF_STATUS_SUCCESS on success. 7958 */ 7959 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 7960 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 7961 { 7962 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 7963 wmi_ready_event_fixed_param *ev = NULL; 7964 7965 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 7966 ev = param_buf->fixed_param; 7967 7968 ev_param->status = ev->status; 7969 ev_param->num_dscp_table = ev->num_dscp_table; 7970 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 7971 ev_param->num_total_peer = ev->num_total_peers; 7972 ev_param->num_extra_peer = ev->num_extra_peers; 7973 /* Agile_cap in ready event is not supported in TLV target */ 7974 ev_param->agile_capability = false; 7975 ev_param->max_ast_index = ev->max_ast_index; 7976 7977 return QDF_STATUS_SUCCESS; 7978 } 7979 7980 /** 7981 * extract_dbglog_data_len_tlv() - extract debuglog data length 7982 * @wmi_handle: wmi handle 7983 * @param evt_buf: pointer to event buffer 7984 * 7985 * Return: length 7986 */ 7987 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 7988 void *evt_buf, uint32_t *len) 7989 { 7990 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 7991 7992 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 7993 7994 *len = param_buf->num_bufp; 7995 7996 return param_buf->bufp; 7997 } 7998 7999 8000 #ifdef CONFIG_MCL 8001 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 8002 ((_status) & WMI_RXERR_DECRYPT) 8003 #else 8004 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 8005 #endif 8006 8007 /** 8008 * extract_mgmt_rx_params_tlv() - extract management rx params from event 8009 * @wmi_handle: wmi handle 8010 * @param evt_buf: pointer to event buffer 8011 * @param hdr: Pointer to hold header 8012 * @param bufp: Pointer to hold pointer to rx param buffer 8013 * 8014 * Return: QDF_STATUS_SUCCESS for success or error code 8015 */ 8016 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 8017 void *evt_buf, struct mgmt_rx_event_params *hdr, 8018 uint8_t **bufp) 8019 { 8020 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 8021 wmi_mgmt_rx_hdr *ev_hdr = NULL; 8022 int i; 8023 8024 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 8025 if (!param_tlvs) { 8026 WMI_LOGE("Get NULL point message from FW"); 8027 return QDF_STATUS_E_INVAL; 8028 } 8029 8030 ev_hdr = param_tlvs->hdr; 8031 if (!hdr) { 8032 WMI_LOGE("Rx event is NULL"); 8033 return QDF_STATUS_E_INVAL; 8034 } 8035 8036 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 8037 WMI_LOGE("%s: RX mgmt frame decrypt error, discard it", 8038 __func__); 8039 return QDF_STATUS_E_INVAL; 8040 } 8041 8042 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 8043 ev_hdr->pdev_id); 8044 8045 hdr->channel = ev_hdr->channel; 8046 hdr->snr = ev_hdr->snr; 8047 hdr->rate = ev_hdr->rate; 8048 hdr->phy_mode = ev_hdr->phy_mode; 8049 hdr->buf_len = ev_hdr->buf_len; 8050 hdr->status = ev_hdr->status; 8051 hdr->flags = ev_hdr->flags; 8052 hdr->rssi = ev_hdr->rssi; 8053 hdr->tsf_delta = ev_hdr->tsf_delta; 8054 for (i = 0; i < ATH_MAX_ANTENNA; i++) 8055 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 8056 8057 *bufp = param_tlvs->bufp; 8058 8059 return QDF_STATUS_SUCCESS; 8060 } 8061 8062 /** 8063 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 8064 * @wmi_handle: wmi handle 8065 * @param evt_buf: pointer to event buffer 8066 * @param param: Pointer to hold roam param 8067 * 8068 * Return: QDF_STATUS_SUCCESS for success or error code 8069 */ 8070 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 8071 void *evt_buf, wmi_host_roam_event *param) 8072 { 8073 WMI_ROAM_EVENTID_param_tlvs *param_buf; 8074 wmi_roam_event_fixed_param *evt; 8075 8076 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 8077 if (!param_buf) { 8078 WMI_LOGE("Invalid roam event buffer"); 8079 return QDF_STATUS_E_INVAL; 8080 } 8081 8082 evt = param_buf->fixed_param; 8083 qdf_mem_zero(param, sizeof(*param)); 8084 8085 param->vdev_id = evt->vdev_id; 8086 param->reason = evt->reason; 8087 param->rssi = evt->rssi; 8088 8089 return QDF_STATUS_SUCCESS; 8090 } 8091 8092 /** 8093 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 8094 * @wmi_handle: wmi handle 8095 * @param evt_buf: pointer to event buffer 8096 * @param param: Pointer to hold vdev scan param 8097 * 8098 * Return: QDF_STATUS_SUCCESS for success or error code 8099 */ 8100 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 8101 void *evt_buf, struct scan_event *param) 8102 { 8103 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 8104 wmi_scan_event_fixed_param *evt = NULL; 8105 8106 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 8107 evt = param_buf->fixed_param; 8108 8109 qdf_mem_zero(param, sizeof(*param)); 8110 8111 switch (evt->event) { 8112 case WMI_SCAN_EVENT_STARTED: 8113 param->type = SCAN_EVENT_TYPE_STARTED; 8114 break; 8115 case WMI_SCAN_EVENT_COMPLETED: 8116 param->type = SCAN_EVENT_TYPE_COMPLETED; 8117 break; 8118 case WMI_SCAN_EVENT_BSS_CHANNEL: 8119 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 8120 break; 8121 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 8122 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 8123 break; 8124 case WMI_SCAN_EVENT_DEQUEUED: 8125 param->type = SCAN_EVENT_TYPE_DEQUEUED; 8126 break; 8127 case WMI_SCAN_EVENT_PREEMPTED: 8128 param->type = SCAN_EVENT_TYPE_PREEMPTED; 8129 break; 8130 case WMI_SCAN_EVENT_START_FAILED: 8131 param->type = SCAN_EVENT_TYPE_START_FAILED; 8132 break; 8133 case WMI_SCAN_EVENT_RESTARTED: 8134 param->type = SCAN_EVENT_TYPE_RESTARTED; 8135 break; 8136 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 8137 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 8138 break; 8139 case WMI_SCAN_EVENT_MAX: 8140 default: 8141 param->type = SCAN_EVENT_TYPE_MAX; 8142 break; 8143 }; 8144 8145 switch (evt->reason) { 8146 case WMI_SCAN_REASON_NONE: 8147 param->reason = SCAN_REASON_NONE; 8148 break; 8149 case WMI_SCAN_REASON_COMPLETED: 8150 param->reason = SCAN_REASON_COMPLETED; 8151 break; 8152 case WMI_SCAN_REASON_CANCELLED: 8153 param->reason = SCAN_REASON_CANCELLED; 8154 break; 8155 case WMI_SCAN_REASON_PREEMPTED: 8156 param->reason = SCAN_REASON_PREEMPTED; 8157 break; 8158 case WMI_SCAN_REASON_TIMEDOUT: 8159 param->reason = SCAN_REASON_TIMEDOUT; 8160 break; 8161 case WMI_SCAN_REASON_INTERNAL_FAILURE: 8162 param->reason = SCAN_REASON_INTERNAL_FAILURE; 8163 break; 8164 case WMI_SCAN_REASON_SUSPENDED: 8165 param->reason = SCAN_REASON_SUSPENDED; 8166 break; 8167 case WMI_SCAN_REASON_DFS_VIOLATION: 8168 param->reason = SCAN_REASON_DFS_VIOLATION; 8169 break; 8170 case WMI_SCAN_REASON_MAX: 8171 param->reason = SCAN_REASON_MAX; 8172 break; 8173 default: 8174 param->reason = SCAN_REASON_MAX; 8175 break; 8176 }; 8177 8178 param->chan_freq = evt->channel_freq; 8179 param->requester = evt->requestor; 8180 param->scan_id = evt->scan_id; 8181 param->vdev_id = evt->vdev_id; 8182 param->timestamp = evt->tsf_timestamp; 8183 8184 return QDF_STATUS_SUCCESS; 8185 } 8186 8187 /** 8188 * extract_all_stats_counts_tlv() - extract all stats count from event 8189 * @wmi_handle: wmi handle 8190 * @param evt_buf: pointer to event buffer 8191 * @param stats_param: Pointer to hold stats count 8192 * 8193 * Return: QDF_STATUS_SUCCESS for success or error code 8194 */ 8195 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, 8196 void *evt_buf, wmi_host_stats_event *stats_param) 8197 { 8198 wmi_stats_event_fixed_param *ev; 8199 wmi_per_chain_rssi_stats *rssi_event; 8200 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 8201 uint64_t min_data_len; 8202 8203 qdf_mem_zero(stats_param, sizeof(*stats_param)); 8204 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 8205 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 8206 rssi_event = param_buf->chain_stats; 8207 if (!ev) { 8208 WMI_LOGE("%s: event fixed param NULL", __func__); 8209 return QDF_STATUS_E_FAILURE; 8210 } 8211 8212 if (param_buf->num_data > WMI_SVC_MSG_MAX_SIZE - sizeof(*ev)) { 8213 WMI_LOGE("num_data : %u is invalid", param_buf->num_data); 8214 return QDF_STATUS_E_FAULT; 8215 } 8216 8217 switch (ev->stats_id) { 8218 case WMI_REQUEST_PEER_STAT: 8219 stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT; 8220 break; 8221 8222 case WMI_REQUEST_AP_STAT: 8223 stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT; 8224 break; 8225 8226 case WMI_REQUEST_PDEV_STAT: 8227 stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT; 8228 break; 8229 8230 case WMI_REQUEST_VDEV_STAT: 8231 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT; 8232 break; 8233 8234 case WMI_REQUEST_BCNFLT_STAT: 8235 stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT; 8236 break; 8237 8238 case WMI_REQUEST_VDEV_RATE_STAT: 8239 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT; 8240 break; 8241 8242 case WMI_REQUEST_BCN_STAT: 8243 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 8244 break; 8245 8246 default: 8247 stats_param->stats_id = 0; 8248 break; 8249 8250 } 8251 8252 /* ev->num_*_stats may cause uint32_t overflow, so use uint64_t 8253 * to save total length calculated 8254 */ 8255 min_data_len = 8256 (((uint64_t)ev->num_pdev_stats) * sizeof(wmi_pdev_stats_v2)) + 8257 (((uint64_t)ev->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 8258 (((uint64_t)ev->num_peer_stats) * sizeof(wmi_peer_stats)) + 8259 (((uint64_t)ev->num_bcnflt_stats) * 8260 sizeof(wmi_bcnfilter_stats_t)) + 8261 (((uint64_t)ev->num_chan_stats) * sizeof(wmi_chan_stats)) + 8262 (((uint64_t)ev->num_mib_stats) * sizeof(wmi_mib_stats)) + 8263 (((uint64_t)ev->num_bcn_stats) * sizeof(wmi_bcn_stats)) + 8264 (((uint64_t)ev->num_peer_extd_stats) * 8265 sizeof(wmi_peer_extd_stats)); 8266 if (param_buf->num_data != min_data_len) { 8267 WMI_LOGE("data len: %u isn't same as calculated: %llu", 8268 param_buf->num_data, min_data_len); 8269 return QDF_STATUS_E_FAULT; 8270 } 8271 8272 stats_param->num_pdev_stats = ev->num_pdev_stats; 8273 stats_param->num_pdev_ext_stats = 0; 8274 stats_param->num_vdev_stats = ev->num_vdev_stats; 8275 stats_param->num_peer_stats = ev->num_peer_stats; 8276 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 8277 stats_param->num_chan_stats = ev->num_chan_stats; 8278 stats_param->num_bcn_stats = ev->num_bcn_stats; 8279 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 8280 ev->pdev_id); 8281 8282 /* if chain_stats is not populated */ 8283 if (!param_buf->chain_stats || !param_buf->num_chain_stats) 8284 return QDF_STATUS_SUCCESS; 8285 8286 if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats != 8287 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 8288 return QDF_STATUS_SUCCESS; 8289 8290 if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) != 8291 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) 8292 return QDF_STATUS_SUCCESS; 8293 8294 if (rssi_event->num_per_chain_rssi_stats >= 8295 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) { 8296 WMI_LOGE("num_per_chain_rssi_stats:%u is out of bounds", 8297 rssi_event->num_per_chain_rssi_stats); 8298 return QDF_STATUS_E_INVAL; 8299 } 8300 stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats; 8301 8302 return QDF_STATUS_SUCCESS; 8303 } 8304 8305 /** 8306 * extract_pdev_tx_stats() - extract pdev tx stats from event 8307 */ 8308 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, 8309 struct wlan_dbg_tx_stats_v2 *tx_stats) 8310 { 8311 /* Tx Stats */ 8312 tx->comp_queued = tx_stats->comp_queued; 8313 tx->comp_delivered = tx_stats->comp_delivered; 8314 tx->msdu_enqued = tx_stats->msdu_enqued; 8315 tx->mpdu_enqued = tx_stats->mpdu_enqued; 8316 tx->wmm_drop = tx_stats->wmm_drop; 8317 tx->local_enqued = tx_stats->local_enqued; 8318 tx->local_freed = tx_stats->local_freed; 8319 tx->hw_queued = tx_stats->hw_queued; 8320 tx->hw_reaped = tx_stats->hw_reaped; 8321 tx->underrun = tx_stats->underrun; 8322 tx->tx_abort = tx_stats->tx_abort; 8323 tx->mpdus_requed = tx_stats->mpdus_requed; 8324 tx->data_rc = tx_stats->data_rc; 8325 tx->self_triggers = tx_stats->self_triggers; 8326 tx->sw_retry_failure = tx_stats->sw_retry_failure; 8327 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 8328 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 8329 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 8330 tx->pdev_resets = tx_stats->pdev_resets; 8331 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 8332 tx->phy_underrun = tx_stats->phy_underrun; 8333 tx->txop_ovf = tx_stats->txop_ovf; 8334 8335 return; 8336 } 8337 8338 8339 /** 8340 * extract_pdev_rx_stats() - extract pdev rx stats from event 8341 */ 8342 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, 8343 struct wlan_dbg_rx_stats_v2 *rx_stats) 8344 { 8345 /* Rx Stats */ 8346 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 8347 rx->status_rcvd = rx_stats->status_rcvd; 8348 rx->r0_frags = rx_stats->r0_frags; 8349 rx->r1_frags = rx_stats->r1_frags; 8350 rx->r2_frags = rx_stats->r2_frags; 8351 /* Only TLV */ 8352 rx->r3_frags = 0; 8353 rx->htt_msdus = rx_stats->htt_msdus; 8354 rx->htt_mpdus = rx_stats->htt_mpdus; 8355 rx->loc_msdus = rx_stats->loc_msdus; 8356 rx->loc_mpdus = rx_stats->loc_mpdus; 8357 rx->oversize_amsdu = rx_stats->oversize_amsdu; 8358 rx->phy_errs = rx_stats->phy_errs; 8359 rx->phy_err_drop = rx_stats->phy_err_drop; 8360 rx->mpdu_errs = rx_stats->mpdu_errs; 8361 8362 return; 8363 } 8364 8365 /** 8366 * extract_pdev_stats_tlv() - extract pdev stats from event 8367 * @wmi_handle: wmi handle 8368 * @param evt_buf: pointer to event buffer 8369 * @param index: Index into pdev stats 8370 * @param pdev_stats: Pointer to hold pdev stats 8371 * 8372 * Return: QDF_STATUS_SUCCESS for success or error code 8373 */ 8374 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle, 8375 void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats) 8376 { 8377 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 8378 wmi_stats_event_fixed_param *ev_param; 8379 uint8_t *data; 8380 8381 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 8382 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 8383 8384 data = param_buf->data; 8385 8386 if (index < ev_param->num_pdev_stats) { 8387 wmi_pdev_stats_v2 *ev = (wmi_pdev_stats_v2 *) ((data) + 8388 (index * sizeof(wmi_pdev_stats_v2))); 8389 8390 pdev_stats->chan_nf = ev->chan_nf; 8391 pdev_stats->tx_frame_count = ev->tx_frame_count; 8392 pdev_stats->rx_frame_count = ev->rx_frame_count; 8393 pdev_stats->rx_clear_count = ev->rx_clear_count; 8394 pdev_stats->cycle_count = ev->cycle_count; 8395 pdev_stats->phy_err_count = ev->phy_err_count; 8396 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 8397 8398 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 8399 &(ev->pdev_stats.tx)); 8400 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 8401 &(ev->pdev_stats.rx)); 8402 } 8403 8404 return QDF_STATUS_SUCCESS; 8405 } 8406 8407 /** 8408 * extract_unit_test_tlv() - extract unit test data 8409 * @wmi_handle: wmi handle 8410 * @param evt_buf: pointer to event buffer 8411 * @param unit_test: pointer to hold unit test data 8412 * @param maxspace: Amount of space in evt_buf 8413 * 8414 * Return: QDF_STATUS_SUCCESS for success or error code 8415 */ 8416 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 8417 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 8418 { 8419 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 8420 wmi_unit_test_event_fixed_param *ev_param; 8421 uint32_t num_bufp; 8422 uint32_t copy_size; 8423 uint8_t *bufp; 8424 8425 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 8426 ev_param = param_buf->fixed_param; 8427 bufp = param_buf->bufp; 8428 num_bufp = param_buf->num_bufp; 8429 unit_test->vdev_id = ev_param->vdev_id; 8430 unit_test->module_id = ev_param->module_id; 8431 unit_test->diag_token = ev_param->diag_token; 8432 unit_test->flag = ev_param->flag; 8433 unit_test->payload_len = ev_param->payload_len; 8434 WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d", __func__, 8435 ev_param->vdev_id, 8436 ev_param->module_id, 8437 ev_param->diag_token, 8438 ev_param->flag); 8439 WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp); 8440 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 8441 bufp, num_bufp); 8442 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 8443 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 8444 unit_test->buffer_len = copy_size; 8445 8446 return QDF_STATUS_SUCCESS; 8447 } 8448 8449 /** 8450 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 8451 * @wmi_handle: wmi handle 8452 * @param evt_buf: pointer to event buffer 8453 * @param index: Index into extended pdev stats 8454 * @param pdev_ext_stats: Pointer to hold extended pdev stats 8455 * 8456 * Return: QDF_STATUS_SUCCESS for success or error code 8457 */ 8458 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 8459 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 8460 { 8461 return QDF_STATUS_SUCCESS; 8462 } 8463 8464 /** 8465 * extract_vdev_stats_tlv() - extract vdev stats from event 8466 * @wmi_handle: wmi handle 8467 * @param evt_buf: pointer to event buffer 8468 * @param index: Index into vdev stats 8469 * @param vdev_stats: Pointer to hold vdev stats 8470 * 8471 * Return: QDF_STATUS_SUCCESS for success or error code 8472 */ 8473 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 8474 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 8475 { 8476 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 8477 wmi_stats_event_fixed_param *ev_param; 8478 uint8_t *data; 8479 8480 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 8481 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 8482 data = (uint8_t *) param_buf->data; 8483 8484 if (index < ev_param->num_vdev_stats) { 8485 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 8486 ((ev_param->num_pdev_stats) * 8487 sizeof(wmi_pdev_stats_v2)) + 8488 (index * sizeof(wmi_vdev_stats))); 8489 8490 vdev_stats->vdev_id = ev->vdev_id; 8491 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 8492 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 8493 8494 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 8495 sizeof(ev->tx_frm_cnt)); 8496 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 8497 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 8498 ev->multiple_retry_cnt, 8499 sizeof(ev->multiple_retry_cnt)); 8500 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 8501 sizeof(ev->fail_cnt)); 8502 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 8503 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 8504 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 8505 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 8506 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 8507 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 8508 sizeof(ev->tx_rate_history)); 8509 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 8510 sizeof(ev->bcn_rssi_history)); 8511 8512 } 8513 8514 return QDF_STATUS_SUCCESS; 8515 } 8516 8517 /** 8518 * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event 8519 * buffer 8520 * @wmi_handle: wmi handle 8521 * @evt_buf: pointer to event buffer 8522 * @index: Index into vdev stats 8523 * @rssi_stats: Pointer to hold rssi stats 8524 * 8525 * Return: QDF_STATUS_SUCCESS for success or error code 8526 */ 8527 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, 8528 void *evt_buf, uint32_t index, 8529 struct wmi_host_per_chain_rssi_stats *rssi_stats) 8530 { 8531 uint8_t *data; 8532 wmi_rssi_stats *fw_rssi_stats; 8533 wmi_per_chain_rssi_stats *rssi_event; 8534 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 8535 8536 if (!evt_buf) { 8537 WMI_LOGE("evt_buf is null"); 8538 return QDF_STATUS_E_NULL_VALUE; 8539 } 8540 8541 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 8542 rssi_event = param_buf->chain_stats; 8543 8544 if (index >= rssi_event->num_per_chain_rssi_stats) { 8545 WMI_LOGE("invalid index"); 8546 return QDF_STATUS_E_INVAL; 8547 } 8548 8549 data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE; 8550 fw_rssi_stats = &((wmi_rssi_stats *)data)[index]; 8551 8552 rssi_stats->vdev_id = fw_rssi_stats->vdev_id; 8553 qdf_mem_copy(rssi_stats->rssi_avg_beacon, 8554 fw_rssi_stats->rssi_avg_beacon, 8555 sizeof(fw_rssi_stats->rssi_avg_beacon)); 8556 qdf_mem_copy(rssi_stats->rssi_avg_data, 8557 fw_rssi_stats->rssi_avg_data, 8558 sizeof(fw_rssi_stats->rssi_avg_data)); 8559 qdf_mem_copy(&rssi_stats->peer_macaddr, 8560 &fw_rssi_stats->peer_macaddr, 8561 sizeof(fw_rssi_stats->peer_macaddr)); 8562 8563 return QDF_STATUS_SUCCESS; 8564 } 8565 8566 8567 8568 /** 8569 * extract_bcn_stats_tlv() - extract bcn stats from event 8570 * @wmi_handle: wmi handle 8571 * @param evt_buf: pointer to event buffer 8572 * @param index: Index into vdev stats 8573 * @param bcn_stats: Pointer to hold bcn stats 8574 * 8575 * Return: QDF_STATUS_SUCCESS for success or error code 8576 */ 8577 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 8578 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 8579 { 8580 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 8581 wmi_stats_event_fixed_param *ev_param; 8582 uint8_t *data; 8583 8584 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 8585 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 8586 data = (uint8_t *) param_buf->data; 8587 8588 if (index < ev_param->num_bcn_stats) { 8589 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 8590 ((ev_param->num_pdev_stats) * 8591 sizeof(wmi_pdev_stats_v2)) + 8592 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 8593 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 8594 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 8595 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 8596 (index * sizeof(wmi_bcn_stats))); 8597 8598 bcn_stats->vdev_id = ev->vdev_id; 8599 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 8600 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 8601 } 8602 8603 return QDF_STATUS_SUCCESS; 8604 } 8605 8606 /** 8607 * extract_peer_stats_tlv() - extract peer stats from event 8608 * @wmi_handle: wmi handle 8609 * @param evt_buf: pointer to event buffer 8610 * @param index: Index into peer stats 8611 * @param peer_stats: Pointer to hold peer stats 8612 * 8613 * Return: QDF_STATUS_SUCCESS for success or error code 8614 */ 8615 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle, 8616 void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats) 8617 { 8618 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 8619 wmi_stats_event_fixed_param *ev_param; 8620 uint8_t *data; 8621 8622 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 8623 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 8624 data = (uint8_t *) param_buf->data; 8625 8626 if (index < ev_param->num_peer_stats) { 8627 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 8628 ((ev_param->num_pdev_stats) * 8629 sizeof(wmi_pdev_stats_v2)) + 8630 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 8631 (index * sizeof(wmi_peer_stats))); 8632 8633 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 8634 8635 OS_MEMCPY(&(peer_stats->peer_macaddr), 8636 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 8637 8638 peer_stats->peer_rssi = ev->peer_rssi; 8639 peer_stats->peer_tx_rate = ev->peer_tx_rate; 8640 peer_stats->peer_rx_rate = ev->peer_rx_rate; 8641 } 8642 8643 return QDF_STATUS_SUCCESS; 8644 } 8645 8646 /** 8647 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 8648 * @wmi_handle: wmi handle 8649 * @param evt_buf: pointer to event buffer 8650 * @param index: Index into bcn fault stats 8651 * @param bcnflt_stats: Pointer to hold bcn fault stats 8652 * 8653 * Return: QDF_STATUS_SUCCESS for success or error code 8654 */ 8655 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 8656 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 8657 { 8658 return QDF_STATUS_SUCCESS; 8659 } 8660 8661 /** 8662 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 8663 * @wmi_handle: wmi handle 8664 * @param evt_buf: pointer to event buffer 8665 * @param index: Index into extended peer stats 8666 * @param peer_extd_stats: Pointer to hold extended peer stats 8667 * 8668 * Return: QDF_STATUS_SUCCESS for success or error code 8669 */ 8670 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 8671 void *evt_buf, uint32_t index, 8672 wmi_host_peer_extd_stats *peer_extd_stats) 8673 { 8674 return QDF_STATUS_SUCCESS; 8675 } 8676 8677 /** 8678 * extract_chan_stats_tlv() - extract chan stats from event 8679 * @wmi_handle: wmi handle 8680 * @param evt_buf: pointer to event buffer 8681 * @param index: Index into chan stats 8682 * @param vdev_extd_stats: Pointer to hold chan stats 8683 * 8684 * Return: QDF_STATUS_SUCCESS for success or error code 8685 */ 8686 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 8687 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 8688 { 8689 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 8690 wmi_stats_event_fixed_param *ev_param; 8691 uint8_t *data; 8692 8693 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 8694 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 8695 data = (uint8_t *) param_buf->data; 8696 8697 if (index < ev_param->num_chan_stats) { 8698 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 8699 ((ev_param->num_pdev_stats) * 8700 sizeof(wmi_pdev_stats_v2)) + 8701 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 8702 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 8703 (index * sizeof(wmi_chan_stats))); 8704 8705 8706 /* Non-TLV doesn't have num_chan_stats */ 8707 chan_stats->chan_mhz = ev->chan_mhz; 8708 chan_stats->sampling_period_us = ev->sampling_period_us; 8709 chan_stats->rx_clear_count = ev->rx_clear_count; 8710 chan_stats->tx_duration_us = ev->tx_duration_us; 8711 chan_stats->rx_duration_us = ev->rx_duration_us; 8712 } 8713 8714 return QDF_STATUS_SUCCESS; 8715 } 8716 8717 /** 8718 * extract_profile_ctx_tlv() - extract profile context from event 8719 * @wmi_handle: wmi handle 8720 * @param evt_buf: pointer to event buffer 8721 * @idx: profile stats index to extract 8722 * @param profile_ctx: Pointer to hold profile context 8723 * 8724 * Return: QDF_STATUS_SUCCESS for success or error code 8725 */ 8726 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 8727 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 8728 { 8729 return QDF_STATUS_SUCCESS; 8730 } 8731 8732 /** 8733 * extract_profile_data_tlv() - extract profile data from event 8734 * @wmi_handle: wmi handle 8735 * @param evt_buf: pointer to event buffer 8736 * @param profile_data: Pointer to hold profile data 8737 * 8738 * Return: QDF_STATUS_SUCCESS for success or error code 8739 */ 8740 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 8741 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 8742 { 8743 8744 return QDF_STATUS_SUCCESS; 8745 } 8746 8747 /** 8748 * extract_pdev_utf_event_tlv() - extract UTF data info from event 8749 * @wmi_handle: WMI handle 8750 * @param evt_buf: Pointer to event buffer 8751 * @param param: Pointer to hold data 8752 * 8753 * Return : QDF_STATUS_SUCCESS for success or error code 8754 */ 8755 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 8756 uint8_t *evt_buf, 8757 struct wmi_host_pdev_utf_event *event) 8758 { 8759 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 8760 struct wmi_host_utf_seg_header_info *seg_hdr; 8761 8762 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 8763 event->data = param_buf->data; 8764 event->datalen = param_buf->num_data; 8765 8766 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 8767 WMI_LOGE("%s: Invalid datalen: %d ", __func__, event->datalen); 8768 return QDF_STATUS_E_INVAL; 8769 } 8770 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 8771 /* Set pdev_id=1 until FW adds support to include pdev_id */ 8772 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 8773 seg_hdr->pdev_id); 8774 8775 return QDF_STATUS_SUCCESS; 8776 } 8777 8778 /** 8779 * extract_chainmask_tables_tlv() - extract chain mask tables from event 8780 * @wmi_handle: wmi handle 8781 * @param evt_buf: pointer to event buffer 8782 * @param param: Pointer to hold evt buf 8783 * 8784 * Return: QDF_STATUS_SUCCESS for success or error code 8785 */ 8786 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 8787 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 8788 { 8789 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 8790 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 8791 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 8792 uint8_t i = 0, j = 0; 8793 uint32_t num_mac_phy_chainmask_caps = 0; 8794 8795 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 8796 if (!param_buf) 8797 return QDF_STATUS_E_INVAL; 8798 8799 hw_caps = param_buf->soc_hw_mode_caps; 8800 if (!hw_caps) 8801 return QDF_STATUS_E_INVAL; 8802 8803 if ((!hw_caps->num_chainmask_tables) || 8804 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 8805 (hw_caps->num_chainmask_tables > 8806 param_buf->num_mac_phy_chainmask_combo)) 8807 return QDF_STATUS_E_INVAL; 8808 8809 chainmask_caps = param_buf->mac_phy_chainmask_caps; 8810 8811 if (chainmask_caps == NULL) 8812 return QDF_STATUS_E_INVAL; 8813 8814 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 8815 if (chainmask_table[i].num_valid_chainmasks > 8816 (UINT_MAX - num_mac_phy_chainmask_caps)) { 8817 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 8818 num_mac_phy_chainmask_caps, i, 8819 chainmask_table[i].num_valid_chainmasks); 8820 return QDF_STATUS_E_INVAL; 8821 } 8822 num_mac_phy_chainmask_caps += 8823 chainmask_table[i].num_valid_chainmasks; 8824 } 8825 8826 if (num_mac_phy_chainmask_caps > 8827 param_buf->num_mac_phy_chainmask_caps) { 8828 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 8829 num_mac_phy_chainmask_caps, 8830 param_buf->num_mac_phy_chainmask_caps); 8831 return QDF_STATUS_E_INVAL; 8832 } 8833 8834 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 8835 8836 qdf_print("Dumping chain mask combo data for table : %d", i); 8837 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 8838 8839 chainmask_table[i].cap_list[j].chainmask = 8840 chainmask_caps->chainmask; 8841 8842 chainmask_table[i].cap_list[j].supports_chan_width_20 = 8843 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 8844 8845 chainmask_table[i].cap_list[j].supports_chan_width_40 = 8846 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 8847 8848 chainmask_table[i].cap_list[j].supports_chan_width_80 = 8849 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 8850 8851 chainmask_table[i].cap_list[j].supports_chan_width_160 = 8852 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 8853 8854 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 8855 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 8856 8857 chainmask_table[i].cap_list[j].chain_mask_2G = 8858 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 8859 8860 chainmask_table[i].cap_list[j].chain_mask_5G = 8861 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 8862 8863 chainmask_table[i].cap_list[j].chain_mask_tx = 8864 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 8865 8866 chainmask_table[i].cap_list[j].chain_mask_rx = 8867 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 8868 8869 chainmask_table[i].cap_list[j].supports_aDFS = 8870 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 8871 8872 qdf_print("supported_flags: 0x%08x chainmasks: 0x%08x", 8873 chainmask_caps->supported_flags, 8874 chainmask_caps->chainmask 8875 ); 8876 chainmask_caps++; 8877 } 8878 } 8879 8880 return QDF_STATUS_SUCCESS; 8881 } 8882 8883 /** 8884 * extract_service_ready_ext_tlv() - extract basic extended service ready params 8885 * from event 8886 * @wmi_handle: wmi handle 8887 * @param evt_buf: pointer to event buffer 8888 * @param param: Pointer to hold evt buf 8889 * 8890 * Return: QDF_STATUS_SUCCESS for success or error code 8891 */ 8892 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 8893 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 8894 { 8895 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 8896 wmi_service_ready_ext_event_fixed_param *ev; 8897 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 8898 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 8899 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 8900 uint8_t i = 0; 8901 8902 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 8903 if (!param_buf) 8904 return QDF_STATUS_E_INVAL; 8905 8906 ev = param_buf->fixed_param; 8907 if (!ev) 8908 return QDF_STATUS_E_INVAL; 8909 8910 /* Move this to host based bitmap */ 8911 param->default_conc_scan_config_bits = 8912 ev->default_conc_scan_config_bits; 8913 param->default_fw_config_bits = ev->default_fw_config_bits; 8914 param->he_cap_info = ev->he_cap_info; 8915 param->mpdu_density = ev->mpdu_density; 8916 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 8917 param->fw_build_vers_ext = ev->fw_build_vers_ext; 8918 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 8919 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 8920 param->max_bssid_indicator = ev->max_bssid_indicator; 8921 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 8922 8923 hw_caps = param_buf->soc_hw_mode_caps; 8924 if (hw_caps) 8925 param->num_hw_modes = hw_caps->num_hw_modes; 8926 else 8927 param->num_hw_modes = 0; 8928 8929 reg_caps = param_buf->soc_hal_reg_caps; 8930 if (reg_caps) 8931 param->num_phy = reg_caps->num_phy; 8932 else 8933 param->num_phy = 0; 8934 8935 if (hw_caps) { 8936 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 8937 qdf_print("Num chain mask tables: %d", hw_caps->num_chainmask_tables); 8938 } else 8939 param->num_chainmask_tables = 0; 8940 8941 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 8942 param->num_chainmask_tables > 8943 param_buf->num_mac_phy_chainmask_combo) { 8944 wmi_err_rl("num_chainmask_tables is OOB: %u", 8945 param->num_chainmask_tables); 8946 return QDF_STATUS_E_INVAL; 8947 } 8948 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 8949 8950 if (chain_mask_combo == NULL) 8951 return QDF_STATUS_SUCCESS; 8952 8953 qdf_print("Dumping chain mask combo data"); 8954 8955 for (i = 0; i < param->num_chainmask_tables; i++) { 8956 8957 qdf_print("table_id : %d Num valid chainmasks: %d", 8958 chain_mask_combo->chainmask_table_id, 8959 chain_mask_combo->num_valid_chainmask 8960 ); 8961 8962 param->chainmask_table[i].table_id = 8963 chain_mask_combo->chainmask_table_id; 8964 param->chainmask_table[i].num_valid_chainmasks = 8965 chain_mask_combo->num_valid_chainmask; 8966 chain_mask_combo++; 8967 } 8968 qdf_print("chain mask combo end"); 8969 8970 return QDF_STATUS_SUCCESS; 8971 } 8972 8973 /** 8974 * extract_sar_cap_service_ready_ext_tlv() - 8975 * extract SAR cap from service ready event 8976 * @wmi_handle: wmi handle 8977 * @event: pointer to event buffer 8978 * @ext_param: extended target info 8979 * 8980 * Return: QDF_STATUS_SUCCESS for success or error code 8981 */ 8982 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 8983 wmi_unified_t wmi_handle, 8984 uint8_t *event, 8985 struct wlan_psoc_host_service_ext_param *ext_param) 8986 { 8987 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 8988 WMI_SAR_CAPABILITIES *sar_caps; 8989 8990 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 8991 8992 if (!param_buf) 8993 return QDF_STATUS_E_INVAL; 8994 8995 sar_caps = param_buf->sar_caps; 8996 if (sar_caps) 8997 ext_param->sar_version = sar_caps->active_version; 8998 else 8999 ext_param->sar_version = 0; 9000 9001 return QDF_STATUS_SUCCESS; 9002 } 9003 9004 /** 9005 * extract_hw_mode_cap_service_ready_ext_tlv() - 9006 * extract HW mode cap from service ready event 9007 * @wmi_handle: wmi handle 9008 * @param evt_buf: pointer to event buffer 9009 * @param param: Pointer to hold evt buf 9010 * @param hw_mode_idx: hw mode idx should be less than num_mode 9011 * 9012 * Return: QDF_STATUS_SUCCESS for success or error code 9013 */ 9014 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 9015 wmi_unified_t wmi_handle, 9016 uint8_t *event, uint8_t hw_mode_idx, 9017 struct wlan_psoc_host_hw_mode_caps *param) 9018 { 9019 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 9020 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 9021 9022 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 9023 if (!param_buf) 9024 return QDF_STATUS_E_INVAL; 9025 9026 hw_caps = param_buf->soc_hw_mode_caps; 9027 if (!hw_caps) 9028 return QDF_STATUS_E_INVAL; 9029 9030 if (!hw_caps->num_hw_modes || 9031 !param_buf->hw_mode_caps || 9032 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 9033 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 9034 return QDF_STATUS_E_INVAL; 9035 9036 if (hw_mode_idx >= hw_caps->num_hw_modes) 9037 return QDF_STATUS_E_INVAL; 9038 9039 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 9040 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 9041 9042 param->hw_mode_config_type = 9043 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 9044 9045 return QDF_STATUS_SUCCESS; 9046 } 9047 9048 /** 9049 * extract_mac_phy_cap_service_ready_ext_tlv() - 9050 * extract MAC phy cap from service ready event 9051 * @wmi_handle: wmi handle 9052 * @param evt_buf: pointer to event buffer 9053 * @param param: Pointer to hold evt buf 9054 * @param hw_mode_idx: hw mode idx should be less than num_mode 9055 * @param phy_id: phy id within hw_mode 9056 * 9057 * Return: QDF_STATUS_SUCCESS for success or error code 9058 */ 9059 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 9060 wmi_unified_t wmi_handle, 9061 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 9062 struct wlan_psoc_host_mac_phy_caps *param) 9063 { 9064 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 9065 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 9066 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 9067 uint32_t phy_map; 9068 uint8_t hw_idx, phy_idx = 0; 9069 9070 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 9071 if (!param_buf) 9072 return QDF_STATUS_E_INVAL; 9073 9074 hw_caps = param_buf->soc_hw_mode_caps; 9075 if (!hw_caps) 9076 return QDF_STATUS_E_INVAL; 9077 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 9078 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 9079 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 9080 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 9081 return QDF_STATUS_E_INVAL; 9082 } 9083 9084 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 9085 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 9086 break; 9087 9088 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 9089 while (phy_map) { 9090 phy_map >>= 1; 9091 phy_idx++; 9092 } 9093 } 9094 9095 if (hw_idx == hw_caps->num_hw_modes) 9096 return QDF_STATUS_E_INVAL; 9097 9098 phy_idx += phy_id; 9099 if (phy_idx >= param_buf->num_mac_phy_caps) 9100 return QDF_STATUS_E_INVAL; 9101 9102 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 9103 9104 param->hw_mode_id = mac_phy_caps->hw_mode_id; 9105 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 9106 mac_phy_caps->pdev_id); 9107 param->phy_id = mac_phy_caps->phy_id; 9108 param->supports_11b = 9109 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 9110 param->supports_11g = 9111 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 9112 param->supports_11a = 9113 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 9114 param->supports_11n = 9115 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 9116 param->supports_11ac = 9117 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 9118 param->supports_11ax = 9119 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 9120 9121 param->supported_bands = mac_phy_caps->supported_bands; 9122 param->ampdu_density = mac_phy_caps->ampdu_density; 9123 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 9124 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 9125 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 9126 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 9127 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 9128 mac_phy_caps->he_cap_info_2G; 9129 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 9130 mac_phy_caps->he_cap_info_2G_ext; 9131 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 9132 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 9133 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 9134 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 9135 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 9136 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 9137 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 9138 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 9139 mac_phy_caps->he_cap_info_5G; 9140 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 9141 mac_phy_caps->he_cap_info_5G_ext; 9142 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 9143 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 9144 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 9145 qdf_mem_copy(¶m->he_cap_phy_info_2G, 9146 &mac_phy_caps->he_cap_phy_info_2G, 9147 sizeof(param->he_cap_phy_info_2G)); 9148 qdf_mem_copy(¶m->he_cap_phy_info_5G, 9149 &mac_phy_caps->he_cap_phy_info_5G, 9150 sizeof(param->he_cap_phy_info_5G)); 9151 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 9152 sizeof(param->he_ppet2G)); 9153 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 9154 sizeof(param->he_ppet5G)); 9155 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 9156 9157 return QDF_STATUS_SUCCESS; 9158 } 9159 9160 /** 9161 * extract_reg_cap_service_ready_ext_tlv() - 9162 * extract REG cap from service ready event 9163 * @wmi_handle: wmi handle 9164 * @param evt_buf: pointer to event buffer 9165 * @param param: Pointer to hold evt buf 9166 * @param phy_idx: phy idx should be less than num_mode 9167 * 9168 * Return: QDF_STATUS_SUCCESS for success or error code 9169 */ 9170 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 9171 wmi_unified_t wmi_handle, 9172 uint8_t *event, uint8_t phy_idx, 9173 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 9174 { 9175 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 9176 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 9177 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 9178 9179 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 9180 if (!param_buf) 9181 return QDF_STATUS_E_INVAL; 9182 9183 reg_caps = param_buf->soc_hal_reg_caps; 9184 if (!reg_caps) 9185 return QDF_STATUS_E_INVAL; 9186 9187 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 9188 return QDF_STATUS_E_INVAL; 9189 9190 if (phy_idx >= reg_caps->num_phy) 9191 return QDF_STATUS_E_INVAL; 9192 9193 if (!param_buf->hal_reg_caps) 9194 return QDF_STATUS_E_INVAL; 9195 9196 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 9197 9198 param->phy_id = ext_reg_cap->phy_id; 9199 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 9200 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 9201 param->regcap1 = ext_reg_cap->regcap1; 9202 param->regcap2 = ext_reg_cap->regcap2; 9203 param->wireless_modes = convert_wireless_modes_tlv( 9204 ext_reg_cap->wireless_modes); 9205 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 9206 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 9207 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 9208 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 9209 9210 return QDF_STATUS_SUCCESS; 9211 } 9212 9213 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 9214 wmi_unified_t wmi_handle, 9215 uint8_t *event, uint8_t idx, 9216 struct wlan_psoc_host_dbr_ring_caps *param) 9217 { 9218 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 9219 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps; 9220 9221 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 9222 if (!param_buf) 9223 return QDF_STATUS_E_INVAL; 9224 9225 dbr_ring_caps = ¶m_buf->dma_ring_caps[idx]; 9226 9227 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 9228 dbr_ring_caps->pdev_id); 9229 param->mod_id = dbr_ring_caps->mod_id; 9230 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 9231 param->min_buf_size = dbr_ring_caps->min_buf_size; 9232 param->min_buf_align = dbr_ring_caps->min_buf_align; 9233 9234 return QDF_STATUS_SUCCESS; 9235 } 9236 9237 /** 9238 * extract_thermal_stats_tlv() - extract thermal stats from event 9239 * @wmi_handle: wmi handle 9240 * @param evt_buf: Pointer to event buffer 9241 * @param temp: Pointer to hold extracted temperature 9242 * @param level: Pointer to hold extracted level 9243 * 9244 * Return: 0 for success or error code 9245 */ 9246 static QDF_STATUS 9247 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 9248 void *evt_buf, uint32_t *temp, 9249 uint32_t *level, uint32_t *pdev_id) 9250 { 9251 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 9252 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 9253 9254 param_buf = 9255 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 9256 if (!param_buf) 9257 return QDF_STATUS_E_INVAL; 9258 9259 tt_stats_event = param_buf->fixed_param; 9260 9261 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 9262 tt_stats_event->pdev_id); 9263 *temp = tt_stats_event->temp; 9264 *level = tt_stats_event->level; 9265 9266 return QDF_STATUS_SUCCESS; 9267 } 9268 9269 /** 9270 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 9271 * @wmi_handle: wmi handle 9272 * @param evt_buf: pointer to event buffer 9273 * @param idx: Index to level stats 9274 * @param levelcount: Pointer to hold levelcount 9275 * @param dccount: Pointer to hold dccount 9276 * 9277 * Return: 0 for success or error code 9278 */ 9279 static QDF_STATUS 9280 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 9281 void *evt_buf, uint8_t idx, uint32_t *levelcount, 9282 uint32_t *dccount) 9283 { 9284 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 9285 wmi_therm_throt_level_stats_info *tt_level_info; 9286 9287 param_buf = 9288 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 9289 if (!param_buf) 9290 return QDF_STATUS_E_INVAL; 9291 9292 tt_level_info = param_buf->therm_throt_level_stats_info; 9293 9294 if (idx < THERMAL_LEVELS) { 9295 *levelcount = tt_level_info[idx].level_count; 9296 *dccount = tt_level_info[idx].dc_count; 9297 return QDF_STATUS_SUCCESS; 9298 } 9299 9300 return QDF_STATUS_E_FAILURE; 9301 } 9302 #ifdef BIG_ENDIAN_HOST 9303 /** 9304 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 9305 * @param data_len - data length 9306 * @param data - pointer to data 9307 * 9308 * Return: QDF_STATUS - success or error status 9309 */ 9310 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 9311 { 9312 uint8_t *data_aligned = NULL; 9313 int c; 9314 unsigned char *data_unaligned; 9315 9316 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 9317 FIPS_ALIGN)); 9318 /* Assigning unaligned space to copy the data */ 9319 /* Checking if kmalloc does successful allocation */ 9320 if (data_unaligned == NULL) 9321 return QDF_STATUS_E_FAILURE; 9322 9323 /* Checking if space is alligned */ 9324 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 9325 /* align the data space */ 9326 data_aligned = 9327 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 9328 } else { 9329 data_aligned = (u_int8_t *)data_unaligned; 9330 } 9331 9332 /* memset and copy content from data to data aligned */ 9333 OS_MEMSET(data_aligned, 0, data_len); 9334 OS_MEMCPY(data_aligned, data, data_len); 9335 /* Endianness to LE */ 9336 for (c = 0; c < data_len/4; c++) { 9337 *((u_int32_t *)data_aligned + c) = 9338 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 9339 } 9340 9341 /* Copy content to event->data */ 9342 OS_MEMCPY(data, data_aligned, data_len); 9343 9344 /* clean up allocated space */ 9345 qdf_mem_free(data_unaligned); 9346 data_aligned = NULL; 9347 data_unaligned = NULL; 9348 9349 /*************************************************************/ 9350 9351 return QDF_STATUS_SUCCESS; 9352 } 9353 #else 9354 /** 9355 * fips_conv_data_be() - DUMMY for LE platform 9356 * 9357 * Return: QDF_STATUS - success 9358 */ 9359 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 9360 { 9361 return QDF_STATUS_SUCCESS; 9362 } 9363 #endif 9364 9365 /** 9366 * extract_fips_event_data_tlv() - extract fips event data 9367 * @wmi_handle: wmi handle 9368 * @param evt_buf: pointer to event buffer 9369 * @param param: pointer FIPS event params 9370 * 9371 * Return: 0 for success or error code 9372 */ 9373 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 9374 void *evt_buf, struct wmi_host_fips_event_param *param) 9375 { 9376 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 9377 wmi_pdev_fips_event_fixed_param *event; 9378 9379 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 9380 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 9381 9382 if (fips_conv_data_be(event->data_len, param_buf->data) != 9383 QDF_STATUS_SUCCESS) 9384 return QDF_STATUS_E_FAILURE; 9385 9386 param->data = (uint32_t *)param_buf->data; 9387 param->data_len = event->data_len; 9388 param->error_status = event->error_status; 9389 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 9390 event->pdev_id); 9391 9392 return QDF_STATUS_SUCCESS; 9393 } 9394 9395 static bool is_management_record_tlv(uint32_t cmd_id) 9396 { 9397 switch (cmd_id) { 9398 case WMI_MGMT_TX_SEND_CMDID: 9399 case WMI_MGMT_TX_COMPLETION_EVENTID: 9400 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 9401 case WMI_MGMT_RX_EVENTID: 9402 return true; 9403 default: 9404 return false; 9405 } 9406 } 9407 9408 static bool is_diag_event_tlv(uint32_t event_id) 9409 { 9410 if (WMI_DIAG_EVENTID == event_id) 9411 return true; 9412 9413 return false; 9414 } 9415 9416 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 9417 { 9418 wmi_vdev_set_param_cmd_fixed_param *set_cmd; 9419 9420 set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf); 9421 9422 switch (set_cmd->param_id) { 9423 case WMI_VDEV_PARAM_LISTEN_INTERVAL: 9424 case WMI_VDEV_PARAM_DTIM_POLICY: 9425 return HTC_TX_PACKET_TAG_AUTO_PM; 9426 default: 9427 break; 9428 } 9429 9430 return 0; 9431 } 9432 9433 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 9434 { 9435 wmi_sta_powersave_param_cmd_fixed_param *ps_cmd; 9436 9437 ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf); 9438 9439 switch (ps_cmd->param) { 9440 case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD: 9441 case WMI_STA_PS_PARAM_INACTIVITY_TIME: 9442 case WMI_STA_PS_ENABLE_QPOWER: 9443 return HTC_TX_PACKET_TAG_AUTO_PM; 9444 default: 9445 break; 9446 } 9447 9448 return 0; 9449 } 9450 9451 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf, 9452 uint32_t cmd_id) 9453 { 9454 if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended)) 9455 return 0; 9456 9457 switch (cmd_id) { 9458 case WMI_VDEV_SET_PARAM_CMDID: 9459 return wmi_tag_vdev_set_cmd(wmi_hdl, buf); 9460 case WMI_STA_POWERSAVE_PARAM_CMDID: 9461 return wmi_tag_sta_powersave_cmd(wmi_hdl, buf); 9462 default: 9463 break; 9464 } 9465 9466 return 0; 9467 } 9468 9469 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 9470 { 9471 uint16_t tag = 0; 9472 9473 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 9474 pr_err("%s: Target is already suspended, Ignore FW Hang Command", 9475 __func__); 9476 return tag; 9477 } 9478 9479 if (wmi_handle->tag_crash_inject) 9480 tag = HTC_TX_PACKET_TAG_AUTO_PM; 9481 9482 wmi_handle->tag_crash_inject = false; 9483 return tag; 9484 } 9485 9486 /** 9487 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 9488 * @wmi_handle: WMI handle 9489 * @buf: WMI buffer 9490 * @cmd_id: WMI command Id 9491 * 9492 * Return htc_tx_tag 9493 */ 9494 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 9495 wmi_buf_t buf, 9496 uint32_t cmd_id) 9497 { 9498 uint16_t htc_tx_tag = 0; 9499 9500 switch (cmd_id) { 9501 case WMI_WOW_ENABLE_CMDID: 9502 case WMI_PDEV_SUSPEND_CMDID: 9503 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 9504 case WMI_PDEV_RESUME_CMDID: 9505 #ifdef FEATURE_WLAN_D0WOW 9506 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 9507 #endif 9508 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 9509 break; 9510 case WMI_FORCE_FW_HANG_CMDID: 9511 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 9512 break; 9513 case WMI_VDEV_SET_PARAM_CMDID: 9514 case WMI_STA_POWERSAVE_PARAM_CMDID: 9515 htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id); 9516 default: 9517 break; 9518 } 9519 9520 return htc_tx_tag; 9521 } 9522 9523 static struct cur_reg_rule 9524 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 9525 wmi_regulatory_rule_struct *wmi_reg_rule) 9526 { 9527 struct cur_reg_rule *reg_rule_ptr; 9528 uint32_t count; 9529 9530 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr)); 9531 9532 if (!reg_rule_ptr) 9533 return NULL; 9534 9535 for (count = 0; count < num_reg_rules; count++) { 9536 reg_rule_ptr[count].start_freq = 9537 WMI_REG_RULE_START_FREQ_GET( 9538 wmi_reg_rule[count].freq_info); 9539 reg_rule_ptr[count].end_freq = 9540 WMI_REG_RULE_END_FREQ_GET( 9541 wmi_reg_rule[count].freq_info); 9542 reg_rule_ptr[count].max_bw = 9543 WMI_REG_RULE_MAX_BW_GET( 9544 wmi_reg_rule[count].bw_pwr_info); 9545 reg_rule_ptr[count].reg_power = 9546 WMI_REG_RULE_REG_POWER_GET( 9547 wmi_reg_rule[count].bw_pwr_info); 9548 reg_rule_ptr[count].ant_gain = 9549 WMI_REG_RULE_ANTENNA_GAIN_GET( 9550 wmi_reg_rule[count].bw_pwr_info); 9551 reg_rule_ptr[count].flags = 9552 WMI_REG_RULE_FLAGS_GET( 9553 wmi_reg_rule[count].flag_info); 9554 } 9555 9556 return reg_rule_ptr; 9557 } 9558 9559 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 9560 wmi_unified_t wmi_handle, uint8_t *evt_buf, 9561 struct cur_regulatory_info *reg_info, uint32_t len) 9562 { 9563 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 9564 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 9565 wmi_regulatory_rule_struct *wmi_reg_rule; 9566 uint32_t num_2g_reg_rules, num_5g_reg_rules; 9567 9568 WMI_LOGD("processing regulatory channel list"); 9569 9570 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 9571 if (!param_buf) { 9572 WMI_LOGE("invalid channel list event buf"); 9573 return QDF_STATUS_E_FAILURE; 9574 } 9575 9576 chan_list_event_hdr = param_buf->fixed_param; 9577 9578 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 9579 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 9580 num_2g_reg_rules = reg_info->num_2g_reg_rules; 9581 num_5g_reg_rules = reg_info->num_5g_reg_rules; 9582 if ((num_2g_reg_rules > MAX_REG_RULES) || 9583 (num_5g_reg_rules > MAX_REG_RULES) || 9584 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 9585 (num_2g_reg_rules + num_5g_reg_rules != 9586 param_buf->num_reg_rule_array)) { 9587 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 9588 num_2g_reg_rules, num_5g_reg_rules); 9589 return QDF_STATUS_E_FAILURE; 9590 } 9591 if (param_buf->num_reg_rule_array > 9592 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 9593 sizeof(*wmi_reg_rule)) { 9594 wmi_err_rl("Invalid num_reg_rule_array: %u", 9595 param_buf->num_reg_rule_array); 9596 return QDF_STATUS_E_FAILURE; 9597 } 9598 9599 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 9600 REG_ALPHA2_LEN); 9601 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 9602 reg_info->phybitmap = chan_list_event_hdr->phybitmap; 9603 reg_info->offload_enabled = true; 9604 reg_info->num_phy = chan_list_event_hdr->num_phy; 9605 reg_info->phy_id = chan_list_event_hdr->phy_id; 9606 reg_info->ctry_code = chan_list_event_hdr->country_id; 9607 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 9608 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 9609 reg_info->status_code = REG_SET_CC_STATUS_PASS; 9610 else if (chan_list_event_hdr->status_code == 9611 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 9612 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 9613 else if (chan_list_event_hdr->status_code == 9614 WMI_REG_INIT_ALPHA2_NOT_FOUND) 9615 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 9616 else if (chan_list_event_hdr->status_code == 9617 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 9618 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 9619 else if (chan_list_event_hdr->status_code == 9620 WMI_REG_SET_CC_STATUS_NO_MEMORY) 9621 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 9622 else if (chan_list_event_hdr->status_code == 9623 WMI_REG_SET_CC_STATUS_FAIL) 9624 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 9625 9626 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 9627 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 9628 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 9629 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 9630 9631 WMI_LOGD(FL("num_phys = %u and phy_id = %u"), 9632 reg_info->num_phy, reg_info->phy_id); 9633 9634 WMI_LOGD("%s:cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 9635 __func__, reg_info->alpha2, reg_info->dfs_region, 9636 reg_info->min_bw_2g, reg_info->max_bw_2g, 9637 reg_info->min_bw_5g, reg_info->max_bw_5g); 9638 9639 WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 9640 num_2g_reg_rules, num_5g_reg_rules); 9641 wmi_reg_rule = 9642 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 9643 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 9644 + WMI_TLV_HDR_SIZE); 9645 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 9646 wmi_reg_rule); 9647 wmi_reg_rule += num_2g_reg_rules; 9648 9649 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 9650 wmi_reg_rule); 9651 9652 WMI_LOGD("processed regulatory channel list"); 9653 9654 return QDF_STATUS_SUCCESS; 9655 } 9656 9657 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 9658 wmi_unified_t wmi_handle, uint8_t *evt_buf, 9659 struct reg_11d_new_country *reg_11d_country, uint32_t len) 9660 { 9661 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 9662 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 9663 9664 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 9665 if (!param_buf) { 9666 WMI_LOGE("invalid 11d country event buf"); 9667 return QDF_STATUS_E_FAILURE; 9668 } 9669 9670 reg_11d_country_event = param_buf->fixed_param; 9671 9672 qdf_mem_copy(reg_11d_country->alpha2, 9673 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 9674 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 9675 9676 WMI_LOGD("processed 11d country event, new cc %s", 9677 reg_11d_country->alpha2); 9678 9679 return QDF_STATUS_SUCCESS; 9680 } 9681 9682 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 9683 wmi_unified_t wmi_handle, uint8_t *evt_buf, 9684 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 9685 { 9686 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 9687 wmi_avoid_freq_range_desc *afr_desc; 9688 uint32_t num_freq_ranges, freq_range_idx; 9689 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 9690 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 9691 9692 if (!param_buf) { 9693 WMI_LOGE("Invalid channel avoid event buffer"); 9694 return QDF_STATUS_E_INVAL; 9695 } 9696 9697 afr_fixed_param = param_buf->fixed_param; 9698 if (!afr_fixed_param) { 9699 WMI_LOGE("Invalid channel avoid event fixed param buffer"); 9700 return QDF_STATUS_E_INVAL; 9701 } 9702 9703 if (!ch_avoid_ind) { 9704 WMI_LOGE("Invalid channel avoid indication buffer"); 9705 return QDF_STATUS_E_INVAL; 9706 } 9707 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 9708 WMI_LOGE(FL("no.of freq ranges exceeded the limit")); 9709 return QDF_STATUS_E_INVAL; 9710 } 9711 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 9712 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 9713 afr_fixed_param->num_freq_ranges; 9714 9715 WMI_LOGD("Channel avoid event received with %d ranges", 9716 num_freq_ranges); 9717 9718 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 9719 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 9720 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 9721 freq_range_idx++) { 9722 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 9723 afr_desc->start_freq; 9724 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 9725 afr_desc->end_freq; 9726 WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u", 9727 freq_range_idx, afr_desc->tlv_header, 9728 afr_desc->start_freq, afr_desc->end_freq); 9729 afr_desc++; 9730 } 9731 9732 return QDF_STATUS_SUCCESS; 9733 } 9734 9735 #ifdef DFS_COMPONENT_ENABLE 9736 /** 9737 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 9738 * @wmi_handle: wma handle 9739 * @evt_buf: event buffer 9740 * @vdev_id: vdev id 9741 * @len: length of buffer 9742 * 9743 * Return: 0 for success or error code 9744 */ 9745 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 9746 uint8_t *evt_buf, 9747 uint32_t *vdev_id, 9748 uint32_t len) 9749 { 9750 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 9751 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 9752 9753 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 9754 if (!param_tlvs) { 9755 WMI_LOGE("invalid cac complete event buf"); 9756 return QDF_STATUS_E_FAILURE; 9757 } 9758 9759 cac_event = param_tlvs->fixed_param; 9760 *vdev_id = cac_event->vdev_id; 9761 WMI_LOGD("processed cac complete event vdev %d", *vdev_id); 9762 9763 return QDF_STATUS_SUCCESS; 9764 } 9765 9766 /** 9767 * extract_dfs_radar_detection_event_tlv() - extract radar found event 9768 * @wmi_handle: wma handle 9769 * @evt_buf: event buffer 9770 * @radar_found: radar found event info 9771 * @len: length of buffer 9772 * 9773 * Return: 0 for success or error code 9774 */ 9775 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 9776 wmi_unified_t wmi_handle, 9777 uint8_t *evt_buf, 9778 struct radar_found_info *radar_found, 9779 uint32_t len) 9780 { 9781 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 9782 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 9783 9784 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 9785 if (!param_tlv) { 9786 WMI_LOGE("invalid radar detection event buf"); 9787 return QDF_STATUS_E_FAILURE; 9788 } 9789 9790 radar_event = param_tlv->fixed_param; 9791 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 9792 radar_event->pdev_id); 9793 radar_found->detection_mode = radar_event->detection_mode; 9794 radar_found->chan_freq = radar_event->chan_freq; 9795 radar_found->chan_width = radar_event->chan_width; 9796 radar_found->detector_id = radar_event->detector_id; 9797 radar_found->segment_id = radar_event->segment_id; 9798 radar_found->timestamp = radar_event->timestamp; 9799 radar_found->is_chirp = radar_event->is_chirp; 9800 radar_found->freq_offset = radar_event->freq_offset; 9801 radar_found->sidx = radar_event->sidx; 9802 9803 WMI_LOGI("processed radar found event pdev %d," 9804 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 9805 "chan_width (RSSI) %d,detector_id (false_radar) %d," 9806 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 9807 "is_chirp %d,detection mode %d", 9808 radar_event->pdev_id, radar_found->pdev_id, 9809 radar_event->timestamp, radar_event->chan_freq, 9810 radar_event->chan_width, radar_event->detector_id, 9811 radar_event->freq_offset, radar_event->segment_id, 9812 radar_event->sidx, radar_event->is_chirp, 9813 radar_event->detection_mode); 9814 9815 return QDF_STATUS_SUCCESS; 9816 } 9817 9818 #ifdef QCA_MCL_DFS_SUPPORT 9819 /** 9820 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 9821 * @wmi_handle: wma handle 9822 * @evt_buf: event buffer 9823 * @wlan_radar_event: Pointer to struct radar_event_info 9824 * @len: length of buffer 9825 * 9826 * Return: QDF_STATUS 9827 */ 9828 static QDF_STATUS extract_wlan_radar_event_info_tlv( 9829 wmi_unified_t wmi_handle, 9830 uint8_t *evt_buf, 9831 struct radar_event_info *wlan_radar_event, 9832 uint32_t len) 9833 { 9834 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 9835 wmi_dfs_radar_event_fixed_param *radar_event; 9836 9837 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 9838 if (!param_tlv) { 9839 WMI_LOGE("invalid wlan radar event buf"); 9840 return QDF_STATUS_E_FAILURE; 9841 } 9842 9843 radar_event = param_tlv->fixed_param; 9844 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 9845 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 9846 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 9847 wlan_radar_event->rssi = radar_event->rssi; 9848 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 9849 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 9850 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 9851 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 9852 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 9853 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 9854 if (radar_event->pulse_flags & 9855 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 9856 wlan_radar_event->is_psidx_diff_valid = true; 9857 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 9858 } else { 9859 wlan_radar_event->is_psidx_diff_valid = false; 9860 } 9861 9862 wlan_radar_event->pdev_id = radar_event->pdev_id; 9863 9864 return QDF_STATUS_SUCCESS; 9865 } 9866 #else 9867 static QDF_STATUS extract_wlan_radar_event_info_tlv( 9868 wmi_unified_t wmi_handle, 9869 uint8_t *evt_buf, 9870 struct radar_event_info *wlan_radar_event, 9871 uint32_t len) 9872 { 9873 return QDF_STATUS_SUCCESS; 9874 } 9875 #endif 9876 #endif 9877 9878 /** 9879 * send_get_rcpi_cmd_tlv() - send request for rcpi value 9880 * @wmi_handle: wmi handle 9881 * @get_rcpi_param: rcpi params 9882 * 9883 * Return: QDF status 9884 */ 9885 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 9886 struct rcpi_req *get_rcpi_param) 9887 { 9888 wmi_buf_t buf; 9889 wmi_request_rcpi_cmd_fixed_param *cmd; 9890 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 9891 9892 buf = wmi_buf_alloc(wmi_handle, len); 9893 if (!buf) 9894 return QDF_STATUS_E_NOMEM; 9895 9896 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 9897 WMITLV_SET_HDR(&cmd->tlv_header, 9898 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 9899 WMITLV_GET_STRUCT_TLVLEN 9900 (wmi_request_rcpi_cmd_fixed_param)); 9901 9902 cmd->vdev_id = get_rcpi_param->vdev_id; 9903 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 9904 &cmd->peer_macaddr); 9905 9906 switch (get_rcpi_param->measurement_type) { 9907 9908 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 9909 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 9910 break; 9911 9912 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 9913 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 9914 break; 9915 9916 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 9917 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 9918 break; 9919 9920 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 9921 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 9922 break; 9923 9924 default: 9925 /* 9926 * invalid rcpi measurement type, fall back to 9927 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 9928 */ 9929 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 9930 break; 9931 } 9932 WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 9933 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 9934 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9935 WMI_REQUEST_RCPI_CMDID)) { 9936 9937 WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID", 9938 __func__); 9939 wmi_buf_free(buf); 9940 return QDF_STATUS_E_FAILURE; 9941 } 9942 9943 return QDF_STATUS_SUCCESS; 9944 } 9945 9946 /** 9947 * extract_rcpi_response_event_tlv() - Extract RCPI event params 9948 * @wmi_handle: wmi handle 9949 * @evt_buf: pointer to event buffer 9950 * @res: pointer to hold rcpi response from firmware 9951 * 9952 * Return: QDF_STATUS_SUCCESS for successful event parse 9953 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 9954 */ 9955 static QDF_STATUS 9956 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 9957 void *evt_buf, struct rcpi_res *res) 9958 { 9959 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 9960 wmi_update_rcpi_event_fixed_param *event; 9961 9962 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 9963 if (!param_buf) { 9964 WMI_LOGE(FL("Invalid rcpi event")); 9965 return QDF_STATUS_E_INVAL; 9966 } 9967 9968 event = param_buf->fixed_param; 9969 res->vdev_id = event->vdev_id; 9970 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 9971 9972 switch (event->measurement_type) { 9973 9974 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 9975 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 9976 break; 9977 9978 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 9979 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 9980 break; 9981 9982 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 9983 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 9984 break; 9985 9986 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 9987 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 9988 break; 9989 9990 default: 9991 WMI_LOGE(FL("Invalid rcpi measurement type from firmware")); 9992 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 9993 return QDF_STATUS_E_FAILURE; 9994 } 9995 9996 if (event->status) 9997 return QDF_STATUS_E_FAILURE; 9998 else 9999 return QDF_STATUS_SUCCESS; 10000 } 10001 10002 /** 10003 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 10004 * host to target defines. For legacy there is not conversion 10005 * required. Just return pdev_id as it is. 10006 * @param pdev_id: host pdev_id to be converted. 10007 * Return: target pdev_id after conversion. 10008 */ 10009 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 10010 uint32_t pdev_id) 10011 { 10012 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 10013 return WMI_PDEV_ID_SOC; 10014 10015 /*No conversion required*/ 10016 return pdev_id; 10017 } 10018 10019 /** 10020 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 10021 * target to host defines. For legacy there is not conversion 10022 * required. Just return pdev_id as it is. 10023 * @param pdev_id: target pdev_id to be converted. 10024 * Return: host pdev_id after conversion. 10025 */ 10026 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 10027 uint32_t pdev_id) 10028 { 10029 /*No conversion required*/ 10030 return pdev_id; 10031 } 10032 10033 /** 10034 * send_set_country_cmd_tlv() - WMI scan channel list function 10035 * @param wmi_handle : handle to WMI. 10036 * @param param : pointer to hold scan channel list parameter 10037 * 10038 * Return: 0 on success and -ve on failure. 10039 */ 10040 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 10041 struct set_country *params) 10042 { 10043 wmi_buf_t buf; 10044 QDF_STATUS qdf_status; 10045 wmi_set_current_country_cmd_fixed_param *cmd; 10046 uint16_t len = sizeof(*cmd); 10047 uint8_t pdev_id = params->pdev_id; 10048 10049 buf = wmi_buf_alloc(wmi_handle, len); 10050 if (!buf) { 10051 qdf_status = QDF_STATUS_E_NOMEM; 10052 goto end; 10053 } 10054 10055 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 10056 WMITLV_SET_HDR(&cmd->tlv_header, 10057 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 10058 WMITLV_GET_STRUCT_TLVLEN 10059 (wmi_set_current_country_cmd_fixed_param)); 10060 10061 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target(pdev_id); 10062 WMI_LOGD("setting current country to %s and target pdev_id = %u", 10063 params->country, cmd->pdev_id); 10064 10065 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 10066 10067 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 10068 qdf_status = wmi_unified_cmd_send(wmi_handle, 10069 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 10070 10071 if (QDF_IS_STATUS_ERROR(qdf_status)) { 10072 WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 10073 wmi_buf_free(buf); 10074 } 10075 10076 end: 10077 return qdf_status; 10078 } 10079 10080 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 10081 WMI_SET_BITS(alpha, 0, 8, val0); \ 10082 WMI_SET_BITS(alpha, 8, 8, val1); \ 10083 WMI_SET_BITS(alpha, 16, 8, val2); \ 10084 } while (0) 10085 10086 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 10087 uint8_t pdev_id, struct cc_regdmn_s *rd) 10088 { 10089 wmi_set_init_country_cmd_fixed_param *cmd; 10090 uint16_t len; 10091 wmi_buf_t buf; 10092 int ret; 10093 10094 len = sizeof(wmi_set_init_country_cmd_fixed_param); 10095 buf = wmi_buf_alloc(wmi_handle, len); 10096 if (!buf) 10097 return QDF_STATUS_E_NOMEM; 10098 10099 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 10100 WMITLV_SET_HDR(&cmd->tlv_header, 10101 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 10102 WMITLV_GET_STRUCT_TLVLEN 10103 (wmi_set_init_country_cmd_fixed_param)); 10104 10105 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 10106 10107 if (rd->flags == CC_IS_SET) { 10108 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 10109 cmd->country_code.country_id = rd->cc.country_code; 10110 } else if (rd->flags == ALPHA_IS_SET) { 10111 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 10112 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 10113 rd->cc.alpha[0], 10114 rd->cc.alpha[1], 10115 rd->cc.alpha[2]); 10116 } else if (rd->flags == REGDMN_IS_SET) { 10117 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 10118 cmd->country_code.domain_code = rd->cc.regdmn_id; 10119 } 10120 10121 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 10122 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10123 WMI_SET_INIT_COUNTRY_CMDID); 10124 if (ret) { 10125 WMI_LOGE("Failed to config wow wakeup event"); 10126 wmi_buf_free(buf); 10127 return QDF_STATUS_E_FAILURE; 10128 } 10129 10130 return QDF_STATUS_SUCCESS; 10131 } 10132 10133 /** 10134 * send_obss_detection_cfg_cmd_tlv() - send obss detection 10135 * configurations to firmware. 10136 * @wmi_handle: wmi handle 10137 * @obss_cfg_param: obss detection configurations 10138 * 10139 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 10140 * 10141 * Return: QDF_STATUS 10142 */ 10143 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 10144 struct wmi_obss_detection_cfg_param *obss_cfg_param) 10145 { 10146 wmi_buf_t buf; 10147 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 10148 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 10149 10150 buf = wmi_buf_alloc(wmi_handle, len); 10151 if (!buf) 10152 return QDF_STATUS_E_NOMEM; 10153 10154 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 10155 WMITLV_SET_HDR(&cmd->tlv_header, 10156 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 10157 WMITLV_GET_STRUCT_TLVLEN 10158 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 10159 10160 cmd->vdev_id = obss_cfg_param->vdev_id; 10161 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 10162 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 10163 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 10164 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 10165 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 10166 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 10167 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 10168 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 10169 10170 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 10171 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10172 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 10173 WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 10174 wmi_buf_free(buf); 10175 return QDF_STATUS_E_FAILURE; 10176 } 10177 10178 return QDF_STATUS_SUCCESS; 10179 } 10180 10181 /** 10182 * extract_obss_detection_info_tlv() - Extract obss detection info 10183 * received from firmware. 10184 * @evt_buf: pointer to event buffer 10185 * @obss_detection: Pointer to hold obss detection info 10186 * 10187 * Return: QDF_STATUS 10188 */ 10189 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 10190 struct wmi_obss_detect_info 10191 *obss_detection) 10192 { 10193 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 10194 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 10195 10196 if (!obss_detection) { 10197 WMI_LOGE("%s: Invalid obss_detection event buffer", __func__); 10198 return QDF_STATUS_E_INVAL; 10199 } 10200 10201 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 10202 if (!param_buf) { 10203 WMI_LOGE("%s: Invalid evt_buf", __func__); 10204 return QDF_STATUS_E_INVAL; 10205 } 10206 10207 fix_param = param_buf->fixed_param; 10208 obss_detection->vdev_id = fix_param->vdev_id; 10209 obss_detection->matched_detection_masks = 10210 fix_param->matched_detection_masks; 10211 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 10212 &obss_detection->matched_bssid_addr[0]); 10213 switch (fix_param->reason) { 10214 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 10215 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 10216 break; 10217 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 10218 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 10219 break; 10220 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 10221 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 10222 break; 10223 default: 10224 WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason); 10225 return QDF_STATUS_E_INVAL; 10226 } 10227 10228 return QDF_STATUS_SUCCESS; 10229 } 10230 10231 /** 10232 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 10233 * @wmi_handle: wmi handle 10234 * @params: pointer to request structure 10235 * 10236 * Return: QDF_STATUS 10237 */ 10238 static QDF_STATUS 10239 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 10240 struct wmi_roam_scan_stats_req *params) 10241 { 10242 wmi_buf_t buf; 10243 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 10244 WMITLV_TAG_ID tag; 10245 uint32_t size; 10246 uint32_t len = sizeof(*cmd); 10247 10248 buf = wmi_buf_alloc(wmi_handle, len); 10249 if (!buf) 10250 return QDF_STATUS_E_FAILURE; 10251 10252 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 10253 10254 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 10255 size = WMITLV_GET_STRUCT_TLVLEN( 10256 wmi_request_roam_scan_stats_cmd_fixed_param); 10257 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 10258 10259 cmd->vdev_id = params->vdev_id; 10260 10261 WMI_LOGD(FL("Roam Scan Stats Req vdev_id: %u"), cmd->vdev_id); 10262 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10263 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 10264 WMI_LOGE("%s: Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID", 10265 __func__); 10266 wmi_buf_free(buf); 10267 return QDF_STATUS_E_FAILURE; 10268 } 10269 10270 return QDF_STATUS_SUCCESS; 10271 } 10272 10273 /** 10274 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 10275 * @wmi_handle: wmi handle 10276 * @evt_buf: pointer to event buffer 10277 * @vdev_id: output pointer to hold vdev id 10278 * @res_param: output pointer to hold the allocated response 10279 * 10280 * Return: QDF_STATUS 10281 */ 10282 static QDF_STATUS 10283 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 10284 uint32_t *vdev_id, 10285 struct wmi_roam_scan_stats_res **res_param) 10286 { 10287 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 10288 wmi_roam_scan_stats_event_fixed_param *fixed_param; 10289 uint32_t *client_id = NULL; 10290 wmi_roaming_timestamp *timestamp = NULL; 10291 uint32_t *num_channels = NULL; 10292 uint32_t *chan_info = NULL; 10293 wmi_mac_addr *old_bssid = NULL; 10294 uint32_t *is_roaming_success = NULL; 10295 wmi_mac_addr *new_bssid = NULL; 10296 uint32_t *num_roam_candidates = NULL; 10297 wmi_roam_scan_trigger_reason *roam_reason = NULL; 10298 wmi_mac_addr *bssid = NULL; 10299 uint32_t *score = NULL; 10300 uint32_t *channel = NULL; 10301 uint32_t *rssi = NULL; 10302 int chan_idx = 0, cand_idx = 0; 10303 uint32_t total_len; 10304 struct wmi_roam_scan_stats_res *res; 10305 uint32_t i, j; 10306 uint32_t num_scans, scan_param_size; 10307 10308 *res_param = NULL; 10309 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 10310 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 10311 if (!param_buf) { 10312 WMI_LOGE(FL("Invalid roam scan stats event")); 10313 return QDF_STATUS_E_INVAL; 10314 } 10315 10316 fixed_param = param_buf->fixed_param; 10317 10318 num_scans = fixed_param->num_roam_scans; 10319 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 10320 *vdev_id = fixed_param->vdev_id; 10321 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 10322 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 10323 num_scans, WMI_ROAM_SCAN_STATS_MAX); 10324 return QDF_STATUS_E_INVAL; 10325 } 10326 10327 total_len = sizeof(*res) + num_scans * scan_param_size; 10328 10329 res = qdf_mem_malloc(total_len); 10330 if (!res) 10331 return QDF_STATUS_E_NOMEM; 10332 10333 if (!num_scans) { 10334 *res_param = res; 10335 return QDF_STATUS_SUCCESS; 10336 } 10337 10338 if (param_buf->client_id && 10339 param_buf->num_client_id == num_scans) 10340 client_id = param_buf->client_id; 10341 10342 if (param_buf->timestamp && 10343 param_buf->num_timestamp == num_scans) 10344 timestamp = param_buf->timestamp; 10345 10346 if (param_buf->old_bssid && 10347 param_buf->num_old_bssid == num_scans) 10348 old_bssid = param_buf->old_bssid; 10349 10350 if (param_buf->new_bssid && 10351 param_buf->num_new_bssid == num_scans) 10352 new_bssid = param_buf->new_bssid; 10353 10354 if (param_buf->is_roaming_success && 10355 param_buf->num_is_roaming_success == num_scans) 10356 is_roaming_success = param_buf->is_roaming_success; 10357 10358 if (param_buf->roam_reason && 10359 param_buf->num_roam_reason == num_scans) 10360 roam_reason = param_buf->roam_reason; 10361 10362 if (param_buf->num_channels && 10363 param_buf->num_num_channels == num_scans) { 10364 uint32_t count, chan_info_sum = 0; 10365 10366 num_channels = param_buf->num_channels; 10367 for (count = 0; count < param_buf->num_num_channels; count++) { 10368 if (param_buf->num_channels[count] > 10369 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 10370 wmi_err_rl("%u exceeded max scan channels %u", 10371 param_buf->num_channels[count], 10372 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 10373 goto error; 10374 } 10375 chan_info_sum += param_buf->num_channels[count]; 10376 } 10377 10378 if (param_buf->chan_info && 10379 param_buf->num_chan_info == chan_info_sum) 10380 chan_info = param_buf->chan_info; 10381 } 10382 10383 if (param_buf->num_roam_candidates && 10384 param_buf->num_num_roam_candidates == num_scans) { 10385 uint32_t cnt, roam_cand_sum = 0; 10386 10387 num_roam_candidates = param_buf->num_roam_candidates; 10388 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 10389 if (param_buf->num_roam_candidates[cnt] > 10390 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 10391 wmi_err_rl("%u exceeded max scan cand %u", 10392 param_buf->num_roam_candidates[cnt], 10393 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 10394 goto error; 10395 } 10396 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 10397 } 10398 10399 if (param_buf->bssid && 10400 param_buf->num_bssid == roam_cand_sum) 10401 bssid = param_buf->bssid; 10402 10403 if (param_buf->score && 10404 param_buf->num_score == roam_cand_sum) 10405 score = param_buf->score; 10406 10407 if (param_buf->channel && 10408 param_buf->num_channel == roam_cand_sum) 10409 channel = param_buf->channel; 10410 10411 if (param_buf->rssi && 10412 param_buf->num_rssi == roam_cand_sum) 10413 rssi = param_buf->rssi; 10414 } 10415 10416 res->num_roam_scans = num_scans; 10417 for (i = 0; i < num_scans; i++) { 10418 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 10419 10420 if (timestamp) 10421 roam->time_stamp = timestamp[i].lower32bit | 10422 (timestamp[i].upper32bit << 31); 10423 10424 if (client_id) 10425 roam->client_id = client_id[i]; 10426 10427 if (num_channels) { 10428 roam->num_scan_chans = num_channels[i]; 10429 if (chan_info) { 10430 for (j = 0; j < num_channels[i]; j++) 10431 roam->scan_freqs[j] = 10432 chan_info[chan_idx++]; 10433 } 10434 } 10435 10436 if (is_roaming_success) 10437 roam->is_roam_successful = is_roaming_success[i]; 10438 10439 if (roam_reason) { 10440 roam->trigger_id = roam_reason[i].trigger_id; 10441 roam->trigger_value = roam_reason[i].trigger_value; 10442 } 10443 10444 if (num_roam_candidates) { 10445 roam->num_roam_candidates = num_roam_candidates[i]; 10446 10447 for (j = 0; j < num_roam_candidates[i]; j++) { 10448 if (score) 10449 roam->cand[j].score = score[cand_idx]; 10450 if (rssi) 10451 roam->cand[j].rssi = rssi[cand_idx]; 10452 if (channel) 10453 roam->cand[j].freq = 10454 channel[cand_idx]; 10455 10456 if (bssid) 10457 WMI_MAC_ADDR_TO_CHAR_ARRAY( 10458 &bssid[cand_idx], 10459 roam->cand[j].bssid); 10460 10461 cand_idx++; 10462 } 10463 } 10464 10465 if (old_bssid) 10466 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 10467 roam->old_bssid); 10468 10469 if (new_bssid) 10470 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 10471 roam->new_bssid); 10472 } 10473 10474 *res_param = res; 10475 10476 return QDF_STATUS_SUCCESS; 10477 error: 10478 qdf_mem_free(res); 10479 return QDF_STATUS_E_FAILURE; 10480 } 10481 10482 /** 10483 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 10484 * @wmi_handle: wmi handle 10485 * @evt_buf: pointer to event buffer 10486 * @vdev_id: output pointer to hold vdev id 10487 * @tx_status: output pointer to hold the tx_status 10488 * 10489 * Return: QDF_STATUS 10490 */ 10491 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 10492 void *evt_buf, 10493 uint32_t *vdev_id, 10494 uint32_t *tx_status) { 10495 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 10496 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 10497 10498 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 10499 if (!param_buf) { 10500 WMI_LOGE("Invalid offload bcn tx status event buffer"); 10501 return QDF_STATUS_E_INVAL; 10502 } 10503 10504 bcn_tx_status_event = param_buf->fixed_param; 10505 *vdev_id = bcn_tx_status_event->vdev_id; 10506 *tx_status = bcn_tx_status_event->tx_status; 10507 10508 return QDF_STATUS_SUCCESS; 10509 } 10510 10511 #ifdef WLAN_SUPPORT_GREEN_AP 10512 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 10513 uint8_t *evt_buf, 10514 struct wlan_green_ap_egap_status_info *egap_status_info_params) 10515 { 10516 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 10517 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 10518 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 10519 10520 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 10521 if (!param_buf) { 10522 WMI_LOGE("Invalid EGAP Info status event buffer"); 10523 return QDF_STATUS_E_INVAL; 10524 } 10525 10526 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 10527 param_buf->fixed_param; 10528 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 10529 param_buf->chainmask_list; 10530 10531 if (!egap_info_event || !chainmask_event) { 10532 WMI_LOGE("Invalid EGAP Info event or chainmask event"); 10533 return QDF_STATUS_E_INVAL; 10534 } 10535 10536 egap_status_info_params->status = egap_info_event->status; 10537 egap_status_info_params->mac_id = chainmask_event->mac_id; 10538 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 10539 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 10540 10541 return QDF_STATUS_SUCCESS; 10542 } 10543 #endif 10544 10545 /* 10546 * extract_comb_phyerr_tlv() - extract comb phy error from event 10547 * @wmi_handle: wmi handle 10548 * @evt_buf: pointer to event buffer 10549 * @datalen: data length of event buffer 10550 * @buf_offset: Pointer to hold value of current event buffer offset 10551 * post extraction 10552 * @phyerr: Pointer to hold phyerr 10553 * 10554 * Return: QDF_STATUS 10555 */ 10556 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 10557 void *evt_buf, 10558 uint16_t datalen, 10559 uint16_t *buf_offset, 10560 wmi_host_phyerr_t *phyerr) 10561 { 10562 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 10563 wmi_comb_phyerr_rx_hdr *pe_hdr; 10564 10565 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 10566 if (!param_tlvs) { 10567 WMI_LOGD("%s: Received null data from FW", __func__); 10568 return QDF_STATUS_E_FAILURE; 10569 } 10570 10571 pe_hdr = param_tlvs->hdr; 10572 if (!pe_hdr) { 10573 WMI_LOGD("%s: Received Data PE Header is NULL", __func__); 10574 return QDF_STATUS_E_FAILURE; 10575 } 10576 10577 /* Ensure it's at least the size of the header */ 10578 if (datalen < sizeof(*pe_hdr)) { 10579 WMI_LOGD("%s: Expected minimum size %zu, received %d", 10580 __func__, sizeof(*pe_hdr), datalen); 10581 return QDF_STATUS_E_FAILURE; 10582 } 10583 10584 phyerr->pdev_id = wmi_handle->ops-> 10585 convert_pdev_id_target_to_host(pe_hdr->pdev_id); 10586 phyerr->tsf64 = pe_hdr->tsf_l32; 10587 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 10588 phyerr->bufp = param_tlvs->bufp; 10589 10590 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 10591 WMI_LOGD("Invalid buf_len %d, num_bufp %d", 10592 pe_hdr->buf_len, param_tlvs->num_bufp); 10593 return QDF_STATUS_E_FAILURE; 10594 } 10595 10596 phyerr->buf_len = pe_hdr->buf_len; 10597 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 10598 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 10599 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 10600 10601 return QDF_STATUS_SUCCESS; 10602 } 10603 10604 /** 10605 * extract_single_phyerr_tlv() - extract single phy error from event 10606 * @wmi_handle: wmi handle 10607 * @evt_buf: pointer to event buffer 10608 * @datalen: data length of event buffer 10609 * @buf_offset: Pointer to hold value of current event buffer offset 10610 * post extraction 10611 * @phyerr: Pointer to hold phyerr 10612 * 10613 * Return: QDF_STATUS 10614 */ 10615 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 10616 void *evt_buf, 10617 uint16_t datalen, 10618 uint16_t *buf_offset, 10619 wmi_host_phyerr_t *phyerr) 10620 { 10621 wmi_single_phyerr_rx_event *ev; 10622 uint16_t n = *buf_offset; 10623 uint8_t *data = (uint8_t *)evt_buf; 10624 10625 if (n < datalen) { 10626 if ((datalen - n) < sizeof(ev->hdr)) { 10627 WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu", 10628 __func__, datalen, n, sizeof(ev->hdr)); 10629 return QDF_STATUS_E_FAILURE; 10630 } 10631 10632 /* 10633 * Obtain a pointer to the beginning of the current event. 10634 * data[0] is the beginning of the WMI payload. 10635 */ 10636 ev = (wmi_single_phyerr_rx_event *)&data[n]; 10637 10638 /* 10639 * Sanity check the buffer length of the event against 10640 * what we currently have. 10641 * 10642 * Since buf_len is 32 bits, we check if it overflows 10643 * a large 32 bit value. It's not 0x7fffffff because 10644 * we increase n by (buf_len + sizeof(hdr)), which would 10645 * in itself cause n to overflow. 10646 * 10647 * If "int" is 64 bits then this becomes a moot point. 10648 */ 10649 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 10650 WMI_LOGD("%s: buf_len is garbage 0x%x", 10651 __func__, ev->hdr.buf_len); 10652 return QDF_STATUS_E_FAILURE; 10653 } 10654 10655 if ((n + ev->hdr.buf_len) > datalen) { 10656 WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d", 10657 __func__, n, ev->hdr.buf_len, datalen); 10658 return QDF_STATUS_E_FAILURE; 10659 } 10660 10661 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 10662 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 10663 phyerr->bufp = &ev->bufp[0]; 10664 phyerr->buf_len = ev->hdr.buf_len; 10665 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 10666 10667 /* 10668 * Advance the buffer pointer to the next PHY error. 10669 * buflen is the length of this payload, so we need to 10670 * advance past the current header _AND_ the payload. 10671 */ 10672 n += sizeof(*ev) + ev->hdr.buf_len; 10673 } 10674 *buf_offset = n; 10675 10676 return QDF_STATUS_SUCCESS; 10677 } 10678 10679 /** 10680 * extract_esp_estimation_ev_param_tlv() - extract air time from event 10681 * @wmi_handle: wmi handle 10682 * @evt_buf: pointer to event buffer 10683 * @param: Pointer to hold esp event 10684 * 10685 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 10686 */ 10687 static QDF_STATUS 10688 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 10689 void *evt_buf, 10690 struct esp_estimation_event *param) 10691 { 10692 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 10693 wmi_esp_estimate_event_fixed_param *esp_event; 10694 10695 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 10696 if (!param_buf) { 10697 WMI_LOGE("Invalid ESP Estimate Event buffer"); 10698 return QDF_STATUS_E_INVAL; 10699 } 10700 esp_event = param_buf->fixed_param; 10701 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 10702 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 10703 esp_event->pdev_id); 10704 10705 return QDF_STATUS_SUCCESS; 10706 } 10707 10708 /* 10709 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 10710 * updating bss color change within firmware when AP announces bss color change. 10711 * @wmi_handle: wmi handle 10712 * @vdev_id: vdev ID 10713 * @enable: enable bss color change within firmware 10714 * 10715 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 10716 * 10717 * Return: QDF_STATUS 10718 */ 10719 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 10720 uint32_t vdev_id, 10721 bool enable) 10722 { 10723 wmi_buf_t buf; 10724 wmi_bss_color_change_enable_fixed_param *cmd; 10725 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 10726 10727 buf = wmi_buf_alloc(wmi_handle, len); 10728 if (!buf) 10729 return QDF_STATUS_E_NOMEM; 10730 10731 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 10732 WMITLV_SET_HDR(&cmd->tlv_header, 10733 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 10734 WMITLV_GET_STRUCT_TLVLEN 10735 (wmi_bss_color_change_enable_fixed_param)); 10736 cmd->vdev_id = vdev_id; 10737 cmd->enable = enable; 10738 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 10739 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10740 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 10741 WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 10742 wmi_buf_free(buf); 10743 return QDF_STATUS_E_FAILURE; 10744 } 10745 10746 return QDF_STATUS_SUCCESS; 10747 } 10748 10749 /** 10750 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 10751 * configurations to firmware. 10752 * @wmi_handle: wmi handle 10753 * @cfg_param: obss detection configurations 10754 * 10755 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 10756 * 10757 * Return: QDF_STATUS 10758 */ 10759 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 10760 wmi_unified_t wmi_handle, 10761 struct wmi_obss_color_collision_cfg_param *cfg_param) 10762 { 10763 wmi_buf_t buf; 10764 wmi_obss_color_collision_det_config_fixed_param *cmd; 10765 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 10766 10767 buf = wmi_buf_alloc(wmi_handle, len); 10768 if (!buf) 10769 return QDF_STATUS_E_NOMEM; 10770 10771 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 10772 buf); 10773 WMITLV_SET_HDR(&cmd->tlv_header, 10774 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 10775 WMITLV_GET_STRUCT_TLVLEN 10776 (wmi_obss_color_collision_det_config_fixed_param)); 10777 cmd->vdev_id = cfg_param->vdev_id; 10778 cmd->flags = cfg_param->flags; 10779 cmd->current_bss_color = cfg_param->current_bss_color; 10780 cmd->detection_period_ms = cfg_param->detection_period_ms; 10781 cmd->scan_period_ms = cfg_param->scan_period_ms; 10782 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 10783 10784 switch (cfg_param->evt_type) { 10785 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 10786 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 10787 break; 10788 case OBSS_COLOR_COLLISION_DETECTION: 10789 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 10790 break; 10791 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 10792 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 10793 break; 10794 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 10795 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 10796 break; 10797 default: 10798 WMI_LOGE("%s: invalid event type: %d", 10799 __func__, cfg_param->evt_type); 10800 wmi_buf_free(buf); 10801 return QDF_STATUS_E_FAILURE; 10802 } 10803 10804 WMI_LOGD("%s: evt_type: %d vdev id: %d current_bss_color: %d\n" 10805 "detection_period_ms: %d scan_period_ms: %d\n" 10806 "free_slot_expiry_timer_ms: %d", 10807 __func__, cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 10808 cmd->detection_period_ms, cmd->scan_period_ms, 10809 cmd->free_slot_expiry_time_ms); 10810 10811 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 10812 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10813 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 10814 WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d", 10815 __func__, cfg_param->vdev_id); 10816 wmi_buf_free(buf); 10817 return QDF_STATUS_E_FAILURE; 10818 } 10819 10820 return QDF_STATUS_SUCCESS; 10821 } 10822 10823 /** 10824 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 10825 * received from firmware. 10826 * @evt_buf: pointer to event buffer 10827 * @info: Pointer to hold bss collision info 10828 * 10829 * Return: QDF_STATUS 10830 */ 10831 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 10832 struct wmi_obss_color_collision_info *info) 10833 { 10834 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 10835 wmi_obss_color_collision_evt_fixed_param *fix_param; 10836 10837 if (!info) { 10838 WMI_LOGE("%s: Invalid obss color buffer", __func__); 10839 return QDF_STATUS_E_INVAL; 10840 } 10841 10842 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 10843 evt_buf; 10844 if (!param_buf) { 10845 WMI_LOGE("%s: Invalid evt_buf", __func__); 10846 return QDF_STATUS_E_INVAL; 10847 } 10848 10849 fix_param = param_buf->fixed_param; 10850 info->vdev_id = fix_param->vdev_id; 10851 info->obss_color_bitmap_bit0to31 = 10852 fix_param->bss_color_bitmap_bit0to31; 10853 info->obss_color_bitmap_bit32to63 = 10854 fix_param->bss_color_bitmap_bit32to63; 10855 10856 switch (fix_param->evt_type) { 10857 case WMI_BSS_COLOR_COLLISION_DISABLE: 10858 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 10859 break; 10860 case WMI_BSS_COLOR_COLLISION_DETECTION: 10861 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 10862 break; 10863 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 10864 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 10865 break; 10866 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 10867 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 10868 break; 10869 default: 10870 WMI_LOGE("%s: invalid event type: %d, vdev_id: %d", 10871 __func__, fix_param->evt_type, fix_param->vdev_id); 10872 return QDF_STATUS_E_FAILURE; 10873 } 10874 10875 return QDF_STATUS_SUCCESS; 10876 } 10877 10878 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 10879 { 10880 struct wmi_ops *ops = wmi_handle->ops; 10881 10882 ops->send_obss_color_collision_cfg_cmd = 10883 send_obss_color_collision_cfg_cmd_tlv; 10884 ops->extract_obss_color_collision_info = 10885 extract_obss_color_collision_info_tlv; 10886 } 10887 10888 struct wmi_ops tlv_ops = { 10889 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 10890 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 10891 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 10892 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 10893 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 10894 .send_hidden_ssid_vdev_restart_cmd = 10895 send_hidden_ssid_vdev_restart_cmd_tlv, 10896 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 10897 .send_peer_param_cmd = send_peer_param_cmd_tlv, 10898 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 10899 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 10900 .send_peer_create_cmd = send_peer_create_cmd_tlv, 10901 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 10902 .send_peer_rx_reorder_queue_setup_cmd = 10903 send_peer_rx_reorder_queue_setup_cmd_tlv, 10904 .send_peer_rx_reorder_queue_remove_cmd = 10905 send_peer_rx_reorder_queue_remove_cmd_tlv, 10906 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 10907 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 10908 .send_suspend_cmd = send_suspend_cmd_tlv, 10909 .send_resume_cmd = send_resume_cmd_tlv, 10910 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 10911 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 10912 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 10913 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 10914 #ifdef FEATURE_FW_LOG_PARSING 10915 .send_dbglog_cmd = send_dbglog_cmd_tlv, 10916 #endif 10917 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 10918 .send_stats_request_cmd = send_stats_request_cmd_tlv, 10919 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 10920 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 10921 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 10922 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 10923 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 10924 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 10925 .send_scan_start_cmd = send_scan_start_cmd_tlv, 10926 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 10927 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 10928 .send_mgmt_cmd = send_mgmt_cmd_tlv, 10929 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 10930 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 10931 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 10932 .send_set_sta_uapsd_auto_trig_cmd = 10933 send_set_sta_uapsd_auto_trig_cmd_tlv, 10934 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 10935 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 10936 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 10937 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 10938 .send_lro_config_cmd = send_lro_config_cmd_tlv, 10939 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 10940 .send_probe_rsp_tmpl_send_cmd = 10941 send_probe_rsp_tmpl_send_cmd_tlv, 10942 .send_p2p_go_set_beacon_ie_cmd = 10943 send_p2p_go_set_beacon_ie_cmd_tlv, 10944 .send_setup_install_key_cmd = 10945 send_setup_install_key_cmd_tlv, 10946 .send_scan_probe_setoui_cmd = 10947 send_scan_probe_setoui_cmd_tlv, 10948 #ifdef IPA_OFFLOAD 10949 .send_ipa_offload_control_cmd = 10950 send_ipa_offload_control_cmd_tlv, 10951 #endif 10952 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 10953 .send_pno_start_cmd = send_pno_start_cmd_tlv, 10954 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 10955 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 10956 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 10957 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 10958 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 10959 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 10960 .send_congestion_cmd = send_congestion_cmd_tlv, 10961 .send_snr_request_cmd = send_snr_request_cmd_tlv, 10962 .send_snr_cmd = send_snr_cmd_tlv, 10963 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 10964 #ifdef CONFIG_MCL 10965 .send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv, 10966 #ifndef REMOVE_PKT_LOG 10967 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 10968 #endif 10969 #endif 10970 #ifdef WLAN_SUPPORT_GREEN_AP 10971 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 10972 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 10973 .extract_green_ap_egap_status_info = 10974 extract_green_ap_egap_status_info_tlv, 10975 #endif 10976 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 10977 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 10978 #ifdef WLAN_FEATURE_CIF_CFR 10979 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 10980 #endif 10981 .send_dfs_phyerr_filter_offload_en_cmd = 10982 send_dfs_phyerr_filter_offload_en_cmd_tlv, 10983 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 10984 .send_process_dhcpserver_offload_cmd = 10985 send_process_dhcpserver_offload_cmd_tlv, 10986 .send_pdev_set_regdomain_cmd = 10987 send_pdev_set_regdomain_cmd_tlv, 10988 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 10989 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 10990 .save_fw_version_cmd = save_fw_version_cmd_tlv, 10991 .check_and_update_fw_version = 10992 check_and_update_fw_version_cmd_tlv, 10993 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 10994 .send_enable_specific_fw_logs_cmd = 10995 send_enable_specific_fw_logs_cmd_tlv, 10996 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 10997 .send_unit_test_cmd = send_unit_test_cmd_tlv, 10998 #ifdef FEATURE_WLAN_APF 10999 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 11000 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 11001 .send_apf_write_work_memory_cmd = 11002 wmi_send_apf_write_work_memory_cmd_tlv, 11003 .send_apf_read_work_memory_cmd = 11004 wmi_send_apf_read_work_memory_cmd_tlv, 11005 .extract_apf_read_memory_resp_event = 11006 wmi_extract_apf_read_memory_resp_event_tlv, 11007 #endif /* FEATURE_WLAN_APF */ 11008 .init_cmd_send = init_cmd_send_tlv, 11009 .send_vdev_set_custom_aggr_size_cmd = 11010 send_vdev_set_custom_aggr_size_cmd_tlv, 11011 .send_vdev_set_qdepth_thresh_cmd = 11012 send_vdev_set_qdepth_thresh_cmd_tlv, 11013 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 11014 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 11015 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 11016 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 11017 .send_periodic_chan_stats_config_cmd = 11018 send_periodic_chan_stats_config_cmd_tlv, 11019 .send_vdev_spectral_configure_cmd = 11020 send_vdev_spectral_configure_cmd_tlv, 11021 .send_vdev_spectral_enable_cmd = 11022 send_vdev_spectral_enable_cmd_tlv, 11023 .send_thermal_mitigation_param_cmd = 11024 send_thermal_mitigation_param_cmd_tlv, 11025 .send_process_update_edca_param_cmd = 11026 send_process_update_edca_param_cmd_tlv, 11027 .send_bss_color_change_enable_cmd = 11028 send_bss_color_change_enable_cmd_tlv, 11029 .send_coex_config_cmd = send_coex_config_cmd_tlv, 11030 .send_set_country_cmd = send_set_country_cmd_tlv, 11031 .send_addba_send_cmd = send_addba_send_cmd_tlv, 11032 .send_delba_send_cmd = send_delba_send_cmd_tlv, 11033 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 11034 .get_target_cap_from_service_ready = extract_service_ready_tlv, 11035 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 11036 .extract_host_mem_req = extract_host_mem_req_tlv, 11037 .save_service_bitmap = save_service_bitmap_tlv, 11038 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 11039 .is_service_enabled = is_service_enabled_tlv, 11040 .save_fw_version = save_fw_version_in_service_ready_tlv, 11041 .ready_extract_init_status = ready_extract_init_status_tlv, 11042 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 11043 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 11044 .extract_ready_event_params = extract_ready_event_params_tlv, 11045 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 11046 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 11047 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 11048 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 11049 .extract_all_stats_count = extract_all_stats_counts_tlv, 11050 .extract_pdev_stats = extract_pdev_stats_tlv, 11051 .extract_unit_test = extract_unit_test_tlv, 11052 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 11053 .extract_vdev_stats = extract_vdev_stats_tlv, 11054 .extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv, 11055 .extract_peer_stats = extract_peer_stats_tlv, 11056 .extract_bcn_stats = extract_bcn_stats_tlv, 11057 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 11058 .extract_peer_extd_stats = extract_peer_extd_stats_tlv, 11059 .extract_chan_stats = extract_chan_stats_tlv, 11060 .extract_profile_ctx = extract_profile_ctx_tlv, 11061 .extract_profile_data = extract_profile_data_tlv, 11062 .send_fw_test_cmd = send_fw_test_cmd_tlv, 11063 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 11064 .extract_service_ready_ext = extract_service_ready_ext_tlv, 11065 .extract_hw_mode_cap_service_ready_ext = 11066 extract_hw_mode_cap_service_ready_ext_tlv, 11067 .extract_mac_phy_cap_service_ready_ext = 11068 extract_mac_phy_cap_service_ready_ext_tlv, 11069 .extract_reg_cap_service_ready_ext = 11070 extract_reg_cap_service_ready_ext_tlv, 11071 .extract_dbr_ring_cap_service_ready_ext = 11072 extract_dbr_ring_cap_service_ready_ext_tlv, 11073 .extract_sar_cap_service_ready_ext = 11074 extract_sar_cap_service_ready_ext_tlv, 11075 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 11076 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 11077 .extract_fips_event_data = extract_fips_event_data_tlv, 11078 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 11079 .is_management_record = is_management_record_tlv, 11080 .is_diag_event = is_diag_event_tlv, 11081 #ifdef WLAN_FEATURE_ACTION_OUI 11082 .send_action_oui_cmd = send_action_oui_cmd_tlv, 11083 #endif 11084 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 11085 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 11086 .extract_reg_chan_list_update_event = 11087 extract_reg_chan_list_update_event_tlv, 11088 .extract_chainmask_tables = 11089 extract_chainmask_tables_tlv, 11090 .extract_thermal_stats = extract_thermal_stats_tlv, 11091 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 11092 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 11093 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 11094 #ifdef DFS_COMPONENT_ENABLE 11095 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 11096 .extract_dfs_radar_detection_event = 11097 extract_dfs_radar_detection_event_tlv, 11098 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 11099 #endif 11100 .convert_pdev_id_host_to_target = 11101 convert_host_pdev_id_to_target_pdev_id_legacy, 11102 .convert_pdev_id_target_to_host = 11103 convert_target_pdev_id_to_host_pdev_id_legacy, 11104 11105 .convert_host_pdev_id_to_target = 11106 convert_host_pdev_id_to_target_pdev_id, 11107 .convert_target_pdev_id_to_host = 11108 convert_target_pdev_id_to_host_pdev_id, 11109 11110 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 11111 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 11112 .extract_reg_11d_new_country_event = 11113 extract_reg_11d_new_country_event_tlv, 11114 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 11115 .extract_reg_ch_avoid_event = 11116 extract_reg_ch_avoid_event_tlv, 11117 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 11118 .extract_obss_detection_info = extract_obss_detection_info_tlv, 11119 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 11120 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 11121 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 11122 .wmi_check_command_params = wmitlv_check_command_tlv_params, 11123 .extract_comb_phyerr = extract_comb_phyerr_tlv, 11124 .extract_single_phyerr = extract_single_phyerr_tlv, 11125 #ifdef QCA_SUPPORT_CP_STATS 11126 .extract_cca_stats = extract_cca_stats_tlv, 11127 #endif 11128 .extract_esp_estimation_ev_param = 11129 extract_esp_estimation_ev_param_tlv, 11130 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 11131 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 11132 #ifdef OBSS_PD 11133 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 11134 .send_obss_spatial_reuse_set_def_thresh = 11135 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 11136 #endif 11137 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 11138 .extract_ctl_failsafe_check_ev_param = 11139 extract_ctl_failsafe_check_ev_param_tlv, 11140 }; 11141 11142 /** 11143 * populate_tlv_event_id() - populates wmi event ids 11144 * 11145 * @param event_ids: Pointer to hold event ids 11146 * Return: None 11147 */ 11148 static void populate_tlv_events_id(uint32_t *event_ids) 11149 { 11150 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 11151 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 11152 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 11153 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 11154 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 11155 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 11156 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 11157 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 11158 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 11159 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 11160 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 11161 event_ids[wmi_service_ready_ext_event_id] = 11162 WMI_SERVICE_READY_EXT_EVENTID; 11163 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 11164 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 11165 event_ids[wmi_vdev_install_key_complete_event_id] = 11166 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 11167 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 11168 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 11169 11170 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 11171 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 11172 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 11173 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 11174 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 11175 event_ids[wmi_peer_estimated_linkspeed_event_id] = 11176 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 11177 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 11178 event_ids[wmi_peer_delete_response_event_id] = 11179 WMI_PEER_DELETE_RESP_EVENTID; 11180 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 11181 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 11182 event_ids[wmi_tbttoffset_update_event_id] = 11183 WMI_TBTTOFFSET_UPDATE_EVENTID; 11184 event_ids[wmi_ext_tbttoffset_update_event_id] = 11185 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 11186 event_ids[wmi_offload_bcn_tx_status_event_id] = 11187 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 11188 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 11189 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 11190 event_ids[wmi_mgmt_tx_completion_event_id] = 11191 WMI_MGMT_TX_COMPLETION_EVENTID; 11192 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 11193 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 11194 event_ids[wmi_tx_delba_complete_event_id] = 11195 WMI_TX_DELBA_COMPLETE_EVENTID; 11196 event_ids[wmi_tx_addba_complete_event_id] = 11197 WMI_TX_ADDBA_COMPLETE_EVENTID; 11198 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 11199 11200 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 11201 11202 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 11203 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 11204 11205 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 11206 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 11207 11208 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 11209 11210 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 11211 event_ids[wmi_p2p_lo_stop_event_id] = 11212 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 11213 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 11214 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 11215 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 11216 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 11217 event_ids[wmi_d0_wow_disable_ack_event_id] = 11218 WMI_D0_WOW_DISABLE_ACK_EVENTID; 11219 event_ids[wmi_wow_initial_wakeup_event_id] = 11220 WMI_WOW_INITIAL_WAKEUP_EVENTID; 11221 11222 event_ids[wmi_rtt_meas_report_event_id] = 11223 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 11224 event_ids[wmi_tsf_meas_report_event_id] = 11225 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 11226 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 11227 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 11228 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 11229 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 11230 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 11231 event_ids[wmi_diag_event_id_log_supported_event_id] = 11232 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 11233 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 11234 event_ids[wmi_nlo_scan_complete_event_id] = 11235 WMI_NLO_SCAN_COMPLETE_EVENTID; 11236 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 11237 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 11238 11239 event_ids[wmi_gtk_offload_status_event_id] = 11240 WMI_GTK_OFFLOAD_STATUS_EVENTID; 11241 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 11242 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 11243 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 11244 11245 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 11246 11247 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 11248 11249 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 11250 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 11251 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 11252 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 11253 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 11254 event_ids[wmi_wlan_profile_data_event_id] = 11255 WMI_WLAN_PROFILE_DATA_EVENTID; 11256 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 11257 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 11258 event_ids[wmi_vdev_get_keepalive_event_id] = 11259 WMI_VDEV_GET_KEEPALIVE_EVENTID; 11260 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 11261 11262 event_ids[wmi_diag_container_event_id] = 11263 WMI_DIAG_DATA_CONTAINER_EVENTID; 11264 11265 event_ids[wmi_host_auto_shutdown_event_id] = 11266 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 11267 11268 event_ids[wmi_update_whal_mib_stats_event_id] = 11269 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 11270 11271 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 11272 event_ids[wmi_update_vdev_rate_stats_event_id] = 11273 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 11274 11275 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 11276 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 11277 11278 /** Set OCB Sched Response, deprecated */ 11279 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 11280 11281 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 11282 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 11283 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 11284 11285 /* GPIO Event */ 11286 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 11287 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 11288 11289 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 11290 event_ids[wmi_rfkill_state_change_event_id] = 11291 WMI_RFKILL_STATE_CHANGE_EVENTID; 11292 11293 /* TDLS Event */ 11294 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 11295 11296 event_ids[wmi_batch_scan_enabled_event_id] = 11297 WMI_BATCH_SCAN_ENABLED_EVENTID; 11298 event_ids[wmi_batch_scan_result_event_id] = 11299 WMI_BATCH_SCAN_RESULT_EVENTID; 11300 /* OEM Event */ 11301 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 11302 event_ids[wmi_oem_meas_report_event_id] = 11303 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 11304 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 11305 11306 /* NAN Event */ 11307 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 11308 11309 /* LPI Event */ 11310 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 11311 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 11312 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 11313 11314 /* ExtScan events */ 11315 event_ids[wmi_extscan_start_stop_event_id] = 11316 WMI_EXTSCAN_START_STOP_EVENTID; 11317 event_ids[wmi_extscan_operation_event_id] = 11318 WMI_EXTSCAN_OPERATION_EVENTID; 11319 event_ids[wmi_extscan_table_usage_event_id] = 11320 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 11321 event_ids[wmi_extscan_cached_results_event_id] = 11322 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 11323 event_ids[wmi_extscan_wlan_change_results_event_id] = 11324 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 11325 event_ids[wmi_extscan_hotlist_match_event_id] = 11326 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 11327 event_ids[wmi_extscan_capabilities_event_id] = 11328 WMI_EXTSCAN_CAPABILITIES_EVENTID; 11329 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 11330 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 11331 11332 /* mDNS offload events */ 11333 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 11334 11335 /* SAP Authentication offload events */ 11336 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 11337 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 11338 11339 /** Out-of-context-of-bss (OCB) events */ 11340 event_ids[wmi_ocb_set_config_resp_event_id] = 11341 WMI_OCB_SET_CONFIG_RESP_EVENTID; 11342 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 11343 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 11344 event_ids[wmi_dcc_get_stats_resp_event_id] = 11345 WMI_DCC_GET_STATS_RESP_EVENTID; 11346 event_ids[wmi_dcc_update_ndl_resp_event_id] = 11347 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 11348 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 11349 /* System-On-Chip events */ 11350 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 11351 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 11352 event_ids[wmi_soc_hw_mode_transition_event_id] = 11353 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 11354 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 11355 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 11356 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 11357 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 11358 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 11359 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 11360 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 11361 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 11362 event_ids[wmi_peer_sta_ps_statechg_event_id] = 11363 WMI_PEER_STA_PS_STATECHG_EVENTID; 11364 event_ids[wmi_pdev_channel_hopping_event_id] = 11365 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 11366 event_ids[wmi_offchan_data_tx_completion_event] = 11367 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 11368 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 11369 event_ids[wmi_dfs_radar_detection_event_id] = 11370 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 11371 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 11372 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 11373 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 11374 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 11375 event_ids[wmi_service_available_event_id] = 11376 WMI_SERVICE_AVAILABLE_EVENTID; 11377 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 11378 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 11379 /* NDP events */ 11380 event_ids[wmi_ndp_initiator_rsp_event_id] = 11381 WMI_NDP_INITIATOR_RSP_EVENTID; 11382 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 11383 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 11384 event_ids[wmi_ndp_responder_rsp_event_id] = 11385 WMI_NDP_RESPONDER_RSP_EVENTID; 11386 event_ids[wmi_ndp_end_indication_event_id] = 11387 WMI_NDP_END_INDICATION_EVENTID; 11388 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 11389 event_ids[wmi_ndl_schedule_update_event_id] = 11390 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 11391 11392 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 11393 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 11394 event_ids[wmi_pdev_chip_power_stats_event_id] = 11395 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 11396 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 11397 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 11398 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 11399 event_ids[wmi_apf_capability_info_event_id] = 11400 WMI_BPF_CAPABILIY_INFO_EVENTID; 11401 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 11402 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 11403 event_ids[wmi_report_rx_aggr_failure_event_id] = 11404 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 11405 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 11406 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 11407 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 11408 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 11409 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 11410 event_ids[wmi_pdev_hw_mode_transition_event_id] = 11411 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 11412 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 11413 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 11414 event_ids[wmi_coex_bt_activity_event_id] = 11415 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 11416 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 11417 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 11418 event_ids[wmi_radio_tx_power_level_stats_event_id] = 11419 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 11420 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 11421 event_ids[wmi_dma_buf_release_event_id] = 11422 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 11423 event_ids[wmi_sap_obss_detection_report_event_id] = 11424 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 11425 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 11426 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 11427 event_ids[wmi_obss_color_collision_report_event_id] = 11428 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 11429 event_ids[wmi_pdev_div_rssi_antid_event_id] = 11430 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 11431 event_ids[wmi_twt_enable_complete_event_id] = 11432 WMI_TWT_ENABLE_COMPLETE_EVENTID; 11433 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 11434 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 11435 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 11436 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 11437 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 11438 #ifdef AST_HKV1_WORKAROUND 11439 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 11440 #endif 11441 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 11442 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 11443 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 11444 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 11445 event_ids[wmi_roam_blacklist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 11446 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 11447 } 11448 11449 /** 11450 * populate_tlv_service() - populates wmi services 11451 * 11452 * @param wmi_service: Pointer to hold wmi_service 11453 * Return: None 11454 */ 11455 static void populate_tlv_service(uint32_t *wmi_service) 11456 { 11457 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 11458 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 11459 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 11460 wmi_service[wmi_service_roam_scan_offload] = 11461 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 11462 wmi_service[wmi_service_bcn_miss_offload] = 11463 WMI_SERVICE_BCN_MISS_OFFLOAD; 11464 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 11465 wmi_service[wmi_service_sta_advanced_pwrsave] = 11466 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 11467 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 11468 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 11469 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 11470 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 11471 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 11472 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 11473 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 11474 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 11475 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 11476 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 11477 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 11478 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 11479 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 11480 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 11481 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 11482 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 11483 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 11484 wmi_service[wmi_service_packet_power_save] = 11485 WMI_SERVICE_PACKET_POWER_SAVE; 11486 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 11487 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 11488 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 11489 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 11490 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 11491 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 11492 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 11493 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 11494 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 11495 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 11496 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 11497 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 11498 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 11499 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 11500 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 11501 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 11502 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 11503 wmi_service[wmi_service_mcc_bcn_interval_change] = 11504 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 11505 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 11506 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 11507 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 11508 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 11509 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 11510 wmi_service[wmi_service_lte_ant_share_support] = 11511 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 11512 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 11513 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 11514 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 11515 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 11516 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 11517 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 11518 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 11519 wmi_service[wmi_service_bcn_txrate_override] = 11520 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 11521 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 11522 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 11523 wmi_service[wmi_service_estimate_linkspeed] = 11524 WMI_SERVICE_ESTIMATE_LINKSPEED; 11525 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 11526 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 11527 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 11528 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 11529 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 11530 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 11531 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 11532 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 11533 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 11534 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 11535 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 11536 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 11537 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 11538 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 11539 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 11540 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 11541 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 11542 wmi_service[wmi_service_sap_auth_offload] = 11543 WMI_SERVICE_SAP_AUTH_OFFLOAD; 11544 wmi_service[wmi_service_dual_band_simultaneous_support] = 11545 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 11546 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 11547 wmi_service[wmi_service_ap_arpns_offload] = 11548 WMI_SERVICE_AP_ARPNS_OFFLOAD; 11549 wmi_service[wmi_service_per_band_chainmask_support] = 11550 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 11551 wmi_service[wmi_service_packet_filter_offload] = 11552 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 11553 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 11554 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 11555 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 11556 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 11557 wmi_service[wmi_service_multiple_vdev_restart] = 11558 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 11559 11560 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 11561 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 11562 wmi_service[wmi_service_smart_antenna_sw_support] = 11563 WMI_SERVICE_UNAVAILABLE; 11564 wmi_service[wmi_service_smart_antenna_hw_support] = 11565 WMI_SERVICE_UNAVAILABLE; 11566 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 11567 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 11568 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 11569 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 11570 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 11571 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 11572 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 11573 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 11574 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 11575 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 11576 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 11577 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 11578 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 11579 wmi_service[wmi_service_periodic_chan_stat_support] = 11580 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 11581 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 11582 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 11583 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 11584 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 11585 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 11586 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 11587 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 11588 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 11589 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 11590 wmi_service[wmi_service_unified_wow_capability] = 11591 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 11592 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 11593 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 11594 wmi_service[wmi_service_sync_delete_cmds] = 11595 WMI_SERVICE_SYNC_DELETE_CMDS; 11596 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 11597 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 11598 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 11599 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 11600 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 11601 wmi_service[wmi_service_deprecated_replace] = 11602 WMI_SERVICE_DEPRECATED_REPLACE; 11603 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 11604 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 11605 wmi_service[wmi_service_enhanced_mcast_filter] = 11606 WMI_SERVICE_ENHANCED_MCAST_FILTER; 11607 wmi_service[wmi_service_half_rate_quarter_rate_support] = 11608 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 11609 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 11610 wmi_service[wmi_service_p2p_listen_offload_support] = 11611 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 11612 wmi_service[wmi_service_mark_first_wakeup_packet] = 11613 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 11614 wmi_service[wmi_service_multiple_mcast_filter_set] = 11615 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 11616 wmi_service[wmi_service_host_managed_rx_reorder] = 11617 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 11618 wmi_service[wmi_service_flash_rdwr_support] = 11619 WMI_SERVICE_FLASH_RDWR_SUPPORT; 11620 wmi_service[wmi_service_wlan_stats_report] = 11621 WMI_SERVICE_WLAN_STATS_REPORT; 11622 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 11623 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 11624 wmi_service[wmi_service_dfs_phyerr_offload] = 11625 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 11626 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 11627 wmi_service[wmi_service_fw_mem_dump_support] = 11628 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 11629 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 11630 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 11631 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 11632 wmi_service[wmi_service_hw_data_filtering] = 11633 WMI_SERVICE_HW_DATA_FILTERING; 11634 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 11635 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 11636 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 11637 wmi_service[wmi_service_extended_nss_support] = 11638 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 11639 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 11640 wmi_service[wmi_service_bcn_offload_start_stop_support] = 11641 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 11642 wmi_service[wmi_service_offchan_data_tid_support] = 11643 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 11644 wmi_service[wmi_service_support_dma] = 11645 WMI_SERVICE_SUPPORT_DIRECT_DMA; 11646 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 11647 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 11648 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 11649 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 11650 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 11651 wmi_service[wmi_service_11k_neighbour_report_support] = 11652 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 11653 wmi_service[wmi_service_ap_obss_detection_offload] = 11654 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 11655 wmi_service[wmi_service_bss_color_offload] = 11656 WMI_SERVICE_BSS_COLOR_OFFLOAD; 11657 wmi_service[wmi_service_gmac_offload_support] = 11658 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 11659 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 11660 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 11661 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 11662 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 11663 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 11664 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 11665 wmi_service[wmi_service_listen_interval_offload_support] = 11666 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 11667 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 11668 wmi_service[wmi_service_obss_spatial_reuse] = 11669 WMI_SERVICE_OBSS_SPATIAL_REUSE; 11670 wmi_service[wmi_service_per_vdev_chain_support] = 11671 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 11672 wmi_service[wmi_service_new_htt_msg_format] = 11673 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 11674 wmi_service[wmi_service_peer_unmap_cnf_support] = 11675 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 11676 wmi_service[wmi_service_beacon_reception_stats] = 11677 WMI_SERVICE_BEACON_RECEPTION_STATS; 11678 wmi_service[wmi_service_vdev_latency_config] = 11679 WMI_SERVICE_VDEV_LATENCY_CONFIG; 11680 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 11681 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 11682 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 11683 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 11684 wmi_service[wmi_service_nan_disable_support] = 11685 WMI_SERVICE_NAN_DISABLE_SUPPORT; 11686 wmi_service[wmi_service_hw_db2dbm_support] = 11687 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 11688 wmi_service[wmi_service_wlm_stats_support] = 11689 WMI_SERVICE_WLM_STATS_REQUEST; 11690 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 11691 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 11692 } 11693 #ifndef CONFIG_MCL 11694 11695 /** 11696 * populate_pdev_param_tlv() - populates pdev params 11697 * 11698 * @param pdev_param: Pointer to hold pdev params 11699 * Return: None 11700 */ 11701 static void populate_pdev_param_tlv(uint32_t *pdev_param) 11702 { 11703 pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK; 11704 pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK; 11705 pdev_param[wmi_pdev_param_txpower_limit2g] = 11706 WMI_PDEV_PARAM_TXPOWER_LIMIT2G; 11707 pdev_param[wmi_pdev_param_txpower_limit5g] = 11708 WMI_PDEV_PARAM_TXPOWER_LIMIT5G; 11709 pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE; 11710 pdev_param[wmi_pdev_param_beacon_gen_mode] = 11711 WMI_PDEV_PARAM_BEACON_GEN_MODE; 11712 pdev_param[wmi_pdev_param_beacon_tx_mode] = 11713 WMI_PDEV_PARAM_BEACON_TX_MODE; 11714 pdev_param[wmi_pdev_param_resmgr_offchan_mode] = 11715 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE; 11716 pdev_param[wmi_pdev_param_protection_mode] = 11717 WMI_PDEV_PARAM_PROTECTION_MODE; 11718 pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW; 11719 pdev_param[wmi_pdev_param_non_agg_sw_retry_th] = 11720 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH; 11721 pdev_param[wmi_pdev_param_agg_sw_retry_th] = 11722 WMI_PDEV_PARAM_AGG_SW_RETRY_TH; 11723 pdev_param[wmi_pdev_param_sta_kickout_th] = 11724 WMI_PDEV_PARAM_STA_KICKOUT_TH; 11725 pdev_param[wmi_pdev_param_ac_aggrsize_scaling] = 11726 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING; 11727 pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE; 11728 pdev_param[wmi_pdev_param_ltr_ac_latency_be] = 11729 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE; 11730 pdev_param[wmi_pdev_param_ltr_ac_latency_bk] = 11731 WMI_PDEV_PARAM_LTR_AC_LATENCY_BK; 11732 pdev_param[wmi_pdev_param_ltr_ac_latency_vi] = 11733 WMI_PDEV_PARAM_LTR_AC_LATENCY_VI; 11734 pdev_param[wmi_pdev_param_ltr_ac_latency_vo] = 11735 WMI_PDEV_PARAM_LTR_AC_LATENCY_VO; 11736 pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] = 11737 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT; 11738 pdev_param[wmi_pdev_param_ltr_sleep_override] = 11739 WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE; 11740 pdev_param[wmi_pdev_param_ltr_rx_override] = 11741 WMI_PDEV_PARAM_LTR_RX_OVERRIDE; 11742 pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] = 11743 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT; 11744 pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE; 11745 pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE; 11746 pdev_param[wmi_pdev_param_pcielp_txbuf_flush] = 11747 WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH; 11748 pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] = 11749 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK; 11750 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] = 11751 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN; 11752 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] = 11753 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE; 11754 pdev_param[wmi_pdev_param_pdev_stats_update_period] = 11755 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD; 11756 pdev_param[wmi_pdev_param_vdev_stats_update_period] = 11757 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD; 11758 pdev_param[wmi_pdev_param_peer_stats_update_period] = 11759 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD; 11760 pdev_param[wmi_pdev_param_bcnflt_stats_update_period] = 11761 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD; 11762 pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS; 11763 pdev_param[wmi_pdev_param_arp_ac_override] = 11764 WMI_PDEV_PARAM_ARP_AC_OVERRIDE; 11765 pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS; 11766 pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE; 11767 pdev_param[wmi_pdev_param_ani_poll_period] = 11768 WMI_PDEV_PARAM_ANI_POLL_PERIOD; 11769 pdev_param[wmi_pdev_param_ani_listen_period] = 11770 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD; 11771 pdev_param[wmi_pdev_param_ani_ofdm_level] = 11772 WMI_PDEV_PARAM_ANI_OFDM_LEVEL; 11773 pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL; 11774 pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN; 11775 pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA; 11776 pdev_param[wmi_pdev_param_idle_ps_config] = 11777 WMI_PDEV_PARAM_IDLE_PS_CONFIG; 11778 pdev_param[wmi_pdev_param_power_gating_sleep] = 11779 WMI_PDEV_PARAM_POWER_GATING_SLEEP; 11780 pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE; 11781 pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR; 11782 pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE; 11783 pdev_param[wmi_pdev_param_hw_rfkill_config] = 11784 WMI_PDEV_PARAM_HW_RFKILL_CONFIG; 11785 pdev_param[wmi_pdev_param_low_power_rf_enable] = 11786 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE; 11787 pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK; 11788 pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN; 11789 pdev_param[wmi_pdev_param_power_collapse_enable] = 11790 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE; 11791 pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE; 11792 pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE; 11793 pdev_param[wmi_pdev_param_audio_over_wlan_latency] = 11794 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY; 11795 pdev_param[wmi_pdev_param_audio_over_wlan_enable] = 11796 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE; 11797 pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] = 11798 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE; 11799 pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] = 11800 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD; 11801 pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW; 11802 pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG; 11803 pdev_param[wmi_pdev_param_adaptive_early_rx_enable] = 11804 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE; 11805 pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 11806 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP; 11807 pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 11808 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP; 11809 pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] = 11810 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP; 11811 pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 11812 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE; 11813 pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 11814 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT; 11815 pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] = 11816 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP; 11817 pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] = 11818 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT; 11819 pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] = 11820 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE; 11821 pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] = 11822 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE; 11823 pdev_param[wmi_pdev_param_tx_chain_mask_2g] = 11824 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G; 11825 pdev_param[wmi_pdev_param_rx_chain_mask_2g] = 11826 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G; 11827 pdev_param[wmi_pdev_param_tx_chain_mask_5g] = 11828 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G; 11829 pdev_param[wmi_pdev_param_rx_chain_mask_5g] = 11830 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G; 11831 pdev_param[wmi_pdev_param_tx_chain_mask_cck] = 11832 WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK; 11833 pdev_param[wmi_pdev_param_tx_chain_mask_1ss] = 11834 WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS; 11835 pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER; 11836 pdev_param[wmi_pdev_set_mcast_to_ucast_tid] = 11837 WMI_PDEV_SET_MCAST_TO_UCAST_TID; 11838 pdev_param[wmi_pdev_param_mgmt_retry_limit] = 11839 WMI_PDEV_PARAM_MGMT_RETRY_LIMIT; 11840 pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST; 11841 pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] = 11842 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE; 11843 pdev_param[wmi_pdev_param_proxy_sta_mode] = 11844 WMI_PDEV_PARAM_PROXY_STA_MODE; 11845 pdev_param[wmi_pdev_param_mu_group_policy] = 11846 WMI_PDEV_PARAM_MU_GROUP_POLICY; 11847 pdev_param[wmi_pdev_param_noise_detection] = 11848 WMI_PDEV_PARAM_NOISE_DETECTION; 11849 pdev_param[wmi_pdev_param_noise_threshold] = 11850 WMI_PDEV_PARAM_NOISE_THRESHOLD; 11851 pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE; 11852 pdev_param[wmi_pdev_param_set_mcast_bcast_echo] = 11853 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO; 11854 pdev_param[wmi_pdev_param_atf_strict_sch] = 11855 WMI_PDEV_PARAM_ATF_STRICT_SCH; 11856 pdev_param[wmi_pdev_param_atf_sched_duration] = 11857 WMI_PDEV_PARAM_ATF_SCHED_DURATION; 11858 pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN; 11859 pdev_param[wmi_pdev_param_sensitivity_level] = 11860 WMI_PDEV_PARAM_SENSITIVITY_LEVEL; 11861 pdev_param[wmi_pdev_param_signed_txpower_2g] = 11862 WMI_PDEV_PARAM_SIGNED_TXPOWER_2G; 11863 pdev_param[wmi_pdev_param_signed_txpower_5g] = 11864 WMI_PDEV_PARAM_SIGNED_TXPOWER_5G; 11865 pdev_param[wmi_pdev_param_enable_per_tid_amsdu] = 11866 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU; 11867 pdev_param[wmi_pdev_param_enable_per_tid_ampdu] = 11868 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU; 11869 pdev_param[wmi_pdev_param_cca_threshold] = 11870 WMI_PDEV_PARAM_CCA_THRESHOLD; 11871 pdev_param[wmi_pdev_param_rts_fixed_rate] = 11872 WMI_PDEV_PARAM_RTS_FIXED_RATE; 11873 pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM; 11874 pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET; 11875 pdev_param[wmi_pdev_param_wapi_mbssid_offset] = 11876 WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET; 11877 pdev_param[wmi_pdev_param_arp_srcaddr] = 11878 WMI_PDEV_PARAM_ARP_DBG_SRCADDR; 11879 pdev_param[wmi_pdev_param_arp_dstaddr] = 11880 WMI_PDEV_PARAM_ARP_DBG_DSTADDR; 11881 pdev_param[wmi_pdev_param_txpower_decr_db] = 11882 WMI_PDEV_PARAM_TXPOWER_DECR_DB; 11883 pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM; 11884 pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM; 11885 pdev_param[wmi_pdev_param_atf_obss_noise_sch] = 11886 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH; 11887 pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] = 11888 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR; 11889 pdev_param[wmi_pdev_param_cust_txpower_scale] = 11890 WMI_PDEV_PARAM_CUST_TXPOWER_SCALE; 11891 pdev_param[wmi_pdev_param_atf_dynamic_enable] = 11892 WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE; 11893 pdev_param[wmi_pdev_param_atf_ssid_group_policy] = 11894 WMI_UNAVAILABLE_PARAM; 11895 pdev_param[wmi_pdev_param_igmpmld_override] = 11896 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 11897 pdev_param[wmi_pdev_param_igmpmld_tid] = 11898 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 11899 pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN; 11900 pdev_param[wmi_pdev_param_block_interbss] = 11901 WMI_PDEV_PARAM_BLOCK_INTERBSS; 11902 pdev_param[wmi_pdev_param_set_disable_reset_cmdid] = 11903 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID; 11904 pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] = 11905 WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID; 11906 pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] = 11907 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID; 11908 pdev_param[wmi_pdev_param_set_burst_mode_cmdid] = 11909 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID; 11910 pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS; 11911 pdev_param[wmi_pdev_param_mesh_mcast_enable] = 11912 WMI_PDEV_PARAM_MESH_MCAST_ENABLE; 11913 pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] = 11914 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID; 11915 pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] = 11916 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID; 11917 pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] = 11918 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER; 11919 pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] = 11920 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER; 11921 pdev_param[wmi_pdev_param_set_mcast2ucast_mode] = 11922 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE; 11923 pdev_param[wmi_pdev_param_smart_antenna_default_antenna] = 11924 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA; 11925 pdev_param[wmi_pdev_param_fast_channel_reset] = 11926 WMI_PDEV_PARAM_FAST_CHANNEL_RESET; 11927 pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE; 11928 pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT; 11929 pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE; 11930 pdev_param[wmi_pdev_param_antenna_gain_half_db] = 11931 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB; 11932 pdev_param[wmi_pdev_param_esp_indication_period] = 11933 WMI_PDEV_PARAM_ESP_INDICATION_PERIOD; 11934 pdev_param[wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW; 11935 pdev_param[wmi_pdev_param_esp_airtime_fraction] = 11936 WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION; 11937 pdev_param[wmi_pdev_param_esp_ppdu_duration] = 11938 WMI_PDEV_PARAM_ESP_PPDU_DURATION; 11939 pdev_param[wmi_pdev_param_ru26_allowed] = 11940 WMI_PDEV_PARAM_UL_RU26_ALLOWED; 11941 pdev_param[wmi_pdev_param_use_nol] = WMI_PDEV_PARAM_USE_NOL; 11942 /* Trigger interval for all trigger types. */ 11943 pdev_param[wmi_pdev_param_ul_trig_int] = 11944 WMI_PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL; 11945 pdev_param[wmi_pdev_param_sub_channel_marking] = 11946 WMI_PDEV_PARAM_SUB_CHANNEL_MARKING; 11947 pdev_param[wmi_pdev_param_ul_ppdu_duration] = 11948 WMI_PDEV_PARAM_SET_UL_PPDU_DURATION; 11949 pdev_param[wmi_pdev_param_equal_ru_allocation_enable] = 11950 WMI_PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE; 11951 } 11952 11953 /** 11954 * populate_vdev_param_tlv() - populates vdev params 11955 * 11956 * @param vdev_param: Pointer to hold vdev params 11957 * Return: None 11958 */ 11959 static void populate_vdev_param_tlv(uint32_t *vdev_param) 11960 { 11961 vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD; 11962 vdev_param[wmi_vdev_param_fragmentation_threshold] = 11963 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD; 11964 vdev_param[wmi_vdev_param_beacon_interval] = 11965 WMI_VDEV_PARAM_BEACON_INTERVAL; 11966 vdev_param[wmi_vdev_param_listen_interval] = 11967 WMI_VDEV_PARAM_LISTEN_INTERVAL; 11968 vdev_param[wmi_vdev_param_multicast_rate] = 11969 WMI_VDEV_PARAM_MULTICAST_RATE; 11970 vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE; 11971 vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME; 11972 vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE; 11973 vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME; 11974 vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD; 11975 vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME; 11976 vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL; 11977 vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD; 11978 vdev_param[wmi_vdev_oc_scheduler_air_time_limit] = 11979 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT; 11980 vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS; 11981 vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW; 11982 vdev_param[wmi_vdev_param_bmiss_count_max] = 11983 WMI_VDEV_PARAM_BMISS_COUNT_MAX; 11984 vdev_param[wmi_vdev_param_bmiss_first_bcnt] = 11985 WMI_VDEV_PARAM_BMISS_FIRST_BCNT; 11986 vdev_param[wmi_vdev_param_bmiss_final_bcnt] = 11987 WMI_VDEV_PARAM_BMISS_FINAL_BCNT; 11988 vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM; 11989 vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH; 11990 vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET; 11991 vdev_param[wmi_vdev_param_disable_htprotection] = 11992 WMI_VDEV_PARAM_DISABLE_HTPROTECTION; 11993 vdev_param[wmi_vdev_param_sta_quickkickout] = 11994 WMI_VDEV_PARAM_STA_QUICKKICKOUT; 11995 vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE; 11996 vdev_param[wmi_vdev_param_protection_mode] = 11997 WMI_VDEV_PARAM_PROTECTION_MODE; 11998 vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE; 11999 vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI; 12000 vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC; 12001 vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC; 12002 vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC; 12003 vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD; 12004 vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID; 12005 vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS; 12006 vdev_param[wmi_vdev_param_bcast_data_rate] = 12007 WMI_VDEV_PARAM_BCAST_DATA_RATE; 12008 vdev_param[wmi_vdev_param_mcast_data_rate] = 12009 WMI_VDEV_PARAM_MCAST_DATA_RATE; 12010 vdev_param[wmi_vdev_param_mcast_indicate] = 12011 WMI_VDEV_PARAM_MCAST_INDICATE; 12012 vdev_param[wmi_vdev_param_dhcp_indicate] = 12013 WMI_VDEV_PARAM_DHCP_INDICATE; 12014 vdev_param[wmi_vdev_param_unknown_dest_indicate] = 12015 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE; 12016 vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 12017 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS; 12018 vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 12019 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS; 12020 vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 12021 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS; 12022 vdev_param[wmi_vdev_param_ap_enable_nawds] = 12023 WMI_VDEV_PARAM_AP_ENABLE_NAWDS; 12024 vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS; 12025 vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF; 12026 vdev_param[wmi_vdev_param_packet_powersave] = 12027 WMI_VDEV_PARAM_PACKET_POWERSAVE; 12028 vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY; 12029 vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE; 12030 vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 12031 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS; 12032 vdev_param[wmi_vdev_param_early_rx_adjust_enable] = 12033 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE; 12034 vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] = 12035 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM; 12036 vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] = 12037 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE; 12038 vdev_param[wmi_vdev_param_early_rx_slop_step] = 12039 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP; 12040 vdev_param[wmi_vdev_param_early_rx_init_slop] = 12041 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP; 12042 vdev_param[wmi_vdev_param_early_rx_adjust_pause] = 12043 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE; 12044 vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT; 12045 vdev_param[wmi_vdev_param_snr_num_for_cal] = 12046 WMI_VDEV_PARAM_SNR_NUM_FOR_CAL; 12047 vdev_param[wmi_vdev_param_roam_fw_offload] = 12048 WMI_VDEV_PARAM_ROAM_FW_OFFLOAD; 12049 vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC; 12050 vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] = 12051 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS; 12052 vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE; 12053 vdev_param[wmi_vdev_param_early_rx_drift_sample] = 12054 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE; 12055 vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 12056 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR; 12057 vdev_param[wmi_vdev_param_ebt_resync_timeout] = 12058 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT; 12059 vdev_param[wmi_vdev_param_aggr_trig_event_enable] = 12060 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE; 12061 vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] = 12062 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED; 12063 vdev_param[wmi_vdev_param_is_power_collapse_allowed] = 12064 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED; 12065 vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] = 12066 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED; 12067 vdev_param[wmi_vdev_param_inactivity_cnt] = 12068 WMI_VDEV_PARAM_INACTIVITY_CNT; 12069 vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] = 12070 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS; 12071 vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY; 12072 vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] = 12073 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS; 12074 vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 12075 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE; 12076 vdev_param[wmi_vdev_param_rx_leak_window] = 12077 WMI_VDEV_PARAM_RX_LEAK_WINDOW; 12078 vdev_param[wmi_vdev_param_stats_avg_factor] = 12079 WMI_VDEV_PARAM_STATS_AVG_FACTOR; 12080 vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH; 12081 vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE; 12082 vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] = 12083 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE; 12084 vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] = 12085 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE; 12086 vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER; 12087 vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE; 12088 vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE; 12089 vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM; 12090 vdev_param[wmi_vdev_param_he_range_ext_enable] = 12091 WMI_VDEV_PARAM_HE_RANGE_EXT; 12092 vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR; 12093 vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE; 12094 vdev_param[wmi_vdev_param_set_he_sounding_mode] 12095 = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; 12096 vdev_param[wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31; 12097 vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP; 12098 vdev_param[wmi_vdev_param_dtim_enable_cts] = 12099 WMI_VDEV_PARAM_DTIM_ENABLE_CTS; 12100 vdev_param[wmi_vdev_param_atf_ssid_sched_policy] = 12101 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY; 12102 vdev_param[wmi_vdev_param_disable_dyn_bw_rts] = 12103 WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS; 12104 vdev_param[wmi_vdev_param_mcast2ucast_set] = 12105 WMI_VDEV_PARAM_MCAST2UCAST_SET; 12106 vdev_param[wmi_vdev_param_rc_num_retries] = 12107 WMI_VDEV_PARAM_RC_NUM_RETRIES; 12108 vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR; 12109 vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET; 12110 vdev_param[wmi_vdev_param_rts_fixed_rate] = 12111 WMI_VDEV_PARAM_RTS_FIXED_RATE; 12112 vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK; 12113 vdev_param[wmi_vdev_param_vht80_ratemask] = 12114 WMI_VDEV_PARAM_VHT80_RATEMASK; 12115 vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA; 12116 vdev_param[wmi_vdev_param_bw_nss_ratemask] = 12117 WMI_VDEV_PARAM_BW_NSS_RATEMASK; 12118 vdev_param[wmi_vdev_param_set_he_ltf] = 12119 WMI_VDEV_PARAM_HE_LTF; 12120 vdev_param[wmi_vdev_param_disable_cabq] = 12121 WMI_VDEV_PARAM_DISABLE_CABQ; 12122 vdev_param[wmi_vdev_param_rate_dropdown_bmap] = 12123 WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP; 12124 vdev_param[wmi_vdev_param_set_ba_mode] = 12125 WMI_VDEV_PARAM_BA_MODE; 12126 vdev_param[wmi_vdev_param_capabilities] = 12127 WMI_VDEV_PARAM_CAPABILITIES; 12128 vdev_param[wmi_vdev_param_autorate_misc_cfg] = 12129 WMI_VDEV_PARAM_AUTORATE_MISC_CFG; 12130 vdev_param[wmi_vdev_param_ul_shortgi] = WMI_VDEV_PARAM_UL_GI; 12131 vdev_param[wmi_vdev_param_ul_he_ltf] = WMI_VDEV_PARAM_UL_HE_LTF; 12132 vdev_param[wmi_vdev_param_ul_nss] = WMI_VDEV_PARAM_UL_NSS; 12133 vdev_param[wmi_vdev_param_ul_ppdu_bw] = WMI_VDEV_PARAM_UL_PPDU_BW; 12134 vdev_param[wmi_vdev_param_ul_ldpc] = WMI_VDEV_PARAM_UL_LDPC; 12135 vdev_param[wmi_vdev_param_ul_stbc] = WMI_VDEV_PARAM_UL_STBC; 12136 vdev_param[wmi_vdev_param_ul_fixed_rate] = WMI_VDEV_PARAM_UL_FIXED_RATE; 12137 vdev_param[wmi_vdev_param_rawmode_open_war] = 12138 WMI_VDEV_PARAM_RAW_IS_ENCRYPTED; 12139 } 12140 #endif 12141 12142 /** 12143 * populate_target_defines_tlv() - Populate target defines and params 12144 * @wmi_handle: pointer to wmi handle 12145 * 12146 * Return: None 12147 */ 12148 #ifndef CONFIG_MCL 12149 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 12150 { 12151 populate_pdev_param_tlv(wmi_handle->pdev_param); 12152 populate_vdev_param_tlv(wmi_handle->vdev_param); 12153 } 12154 #else 12155 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 12156 { } 12157 #endif 12158 12159 /** 12160 * wmi_ocb_ut_attach() - Attach OCB test framework 12161 * @wmi_handle: wmi handle 12162 * 12163 * Return: None 12164 */ 12165 #ifdef WLAN_OCB_UT 12166 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 12167 #else 12168 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 12169 { 12170 return; 12171 } 12172 #endif 12173 12174 /** 12175 * wmi_tlv_attach() - Attach TLV APIs 12176 * 12177 * Return: None 12178 */ 12179 void wmi_tlv_attach(wmi_unified_t wmi_handle) 12180 { 12181 wmi_handle->ops = &tlv_ops; 12182 wmi_ocb_ut_attach(wmi_handle); 12183 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 12184 #ifdef WMI_INTERFACE_EVENT_LOGGING 12185 /* Skip saving WMI_CMD_HDR and TLV HDR */ 12186 wmi_handle->soc->buf_offset_command = 8; 12187 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 12188 wmi_handle->soc->buf_offset_event = 4; 12189 #endif 12190 populate_tlv_events_id(wmi_handle->wmi_events); 12191 populate_tlv_service(wmi_handle->services); 12192 populate_target_defines_tlv(wmi_handle); 12193 wmi_twt_attach_tlv(wmi_handle); 12194 wmi_extscan_attach_tlv(wmi_handle); 12195 wmi_smart_ant_attach_tlv(wmi_handle); 12196 wmi_dbr_attach_tlv(wmi_handle); 12197 wmi_atf_attach_tlv(wmi_handle); 12198 wmi_ap_attach_tlv(wmi_handle); 12199 wmi_ocb_attach_tlv(wmi_handle); 12200 wmi_nan_attach_tlv(wmi_handle); 12201 wmi_p2p_attach_tlv(wmi_handle); 12202 wmi_roam_attach_tlv(wmi_handle); 12203 wmi_concurrency_attach_tlv(wmi_handle); 12204 wmi_pmo_attach_tlv(wmi_handle); 12205 wmi_sta_attach_tlv(wmi_handle); 12206 wmi_11ax_bss_color_attach_tlv(wmi_handle); 12207 } 12208 qdf_export_symbol(wmi_tlv_attach); 12209 12210 /** 12211 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 12212 * 12213 * Return: None 12214 */ 12215 void wmi_tlv_init(void) 12216 { 12217 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 12218 } 12219