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